Check if a condition remains true for a given number of bars.

 

Hi All,

Hopefully, someone can help me with the below. 

I want to check if a condition remains true for a given number of bars. Specifically, I want a MA to keep growing for at least 10 bars, after having crossed a slower MA. If the condition is not met, I want the FOR loop to restart from 0.

This is the code:

#property strict
#property copyright "Davide.P"
//+------------------------------------------------------------------+
input int e_Magic=1;
input int enter=10;
//+------------------------------------------------------------------+
void OnTick(void)
  {
   int   ticket,total,i;
   int   TrendOn=0;
   double MaF=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,0);
   double MaS=iMA(NULL,0,75,0,MODE_EMA,PRICE_CLOSE,0);
//+------------------------------------------------------------------+  
   //BEGINNING
   total=OrdersTotal();
   if(total<1)
     {
     while (MaF>MaS)
        {  
//+------------------------------------------------------------------+        
        //CHK FOR AT LEAST 10 CANDLES INCREMENTING
        for(i=1;i>enter;i++)
            {
            double MaFast=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i);
            double MaFastPrevious=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i+1);
            if (MaFast>MaFastPrevious)    // MA incrementing
               TrendOn=TrendOn+1;
            else;
               TrendOn=0;
            break;
            }
        if(TrendOn=enter)
//+------------------------------------------------------------------+
         //OPEN POSITION
         ticket=OrderSend(Symbol(),OP_BUY,1,Ask,0,Ask-800*Point,Ask+800*Point,NULL,1,0,Blue);
         return;
}}}   
     
The code works only for the first position entered.

Hopefully, someone can explain me what is not correct.

Many thanks!

Davide

 
input int e_Magic=1;
   double MaF=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,0);
   double MaS=iMA(NULL,0,75,0,MODE_EMA,PRICE_CLOSE,0);

When posting code, please avoid posting code with variables that are not used such as above. It can be confusing when your code gets more complicated.


for(i=1;i>enter;i++)

if enter==10, when will this be executed?


if(TrendOn=enter)

Expression is not boolean.


   int   ticket,total,i;
   int   TrendOn=0;

Personally, I think that it is a bad idea to capitalise local variables as I think that many will assume that they are globalscope (in larger blocks of code).

 

Hi Keith, thanks for your help!

Please, note that I am a novice coder, and may have misunderstood some of your comments.


MaF and MaS are the moving averages needed to trigger the WHILE loop. I can't get rid of them.

"if enter==10, when will this be executed?"

I am not sure I get your point.

My intention is to have the FOR loop to check through the previous 10 candles if the MA keeps growing. Should this happen, the TrendOn variable increments by 1 every time. When the loop ends, the IF condition checks the value of TrendOn to see if MA has grown for at least 10 candles.

I think it is TrendOn to be checked not to enter. Enter is whatever number the user decides to input. It doesn't need to be 10.


"Personally, I think that it is a bad idea to.."

Not sure I got this point either. Are you saying that the TrendOn should be a local variable only?


I have updated the code with my understanding of your comments (hopefully, correct).


#property strict
#property copyright "Davide.P"
input int enter=10;
//+------------------------------------------------------------------+
void OnTick(void)
  {
   double MaF=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,0);
   double MaS=iMA(NULL,0,75,0,MODE_EMA,PRICE_CLOSE,0);
//+------------------------------------------------------------------+  
   //BEGINNING
   int total=OrdersTotal();
   if(total<1)
     {
     int TrendOn=0;   
     while (MaF>MaS)
        { 
//+------------------------------------------------------------------+        
        //CHK FOR AT LEAST 10 CANDLES INCREMENTING
        for(int i=1;i==enter;i++)
            {
            double MaFast=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i);
            double MaFastPrevious=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i+1);
            if (MaFast>MaFastPrevious)    // MA incrementing
               TrendOn=TrendOn+1;
            else;
               TrendOn=0;
            }
        if(TrendOn==enter)
//+------------------------------------------------------------------+
         //OPEN POSITION
         int ticket=OrderSend(Symbol(),OP_BUY,1,Ask,0,Ask-800*Point,Ask+800*Point,NULL,0,0,Blue);
         return;
}}}   
Now, this code doesn't work yet, but I don't know why.
I have also tried to omit the variable "enter" and put directly the number 10 in the FOR loop and IF condition. It works but only for the first order. After that, it doesn't check if the MA is growing. This makes me think that TrendOn doesn't reset to 0 after the first order.

 Any idea?

Many thanks
Davide
 
Davide.P:


MaF and MaS are the moving averages needed to trigger the WHILE loop. I can't get rid of them. 

I must have missed that before but

Why do you even need the while loop? Don't you get stuck in an endless loop? Maybe it should be an if?

My intention is to have the FOR loop to check through the previous 10 candles if the MA keeps growing. Should this happen, the TrendOn variable increments by 1 every time. When the loop ends, the IF condition checks the value of TrendOn to see if MA has grown for at least 10 candles.

Then why do you reset TrendOn to 0 when the MA stops increasing?

Not sure I got this point either. Are you saying that the TrendOn should be a local variable only?

It IS a local variable - you declare it locally.

 
Keith Watford:
Why do you even need the while loop? Don't you get stuck in an endless loop? Maybe it should be an if?

For simplicity, I have removed the while loop.  

Then why do you reset TrendOn to 0 when the MA stops increasing?

Because I want to check if a condition remains true for a given number of bars. In this specific case, to be sure that the trend has changed and it is not a false reversal. If the MA has gone up for 2 bars, then down for 2 and then up again 6 bars, then the condition is not met because MA hasn't grown consistnetly for 10 bars.

I have copied below a simpler piece of code, with no WHILE loop and no enter variable. If you test it with any symbol and timeframe, you'll see that the code works only for the first order. After that, it stops checking if the MA is growing. I believe that this is because TrenOn doesn't reset as 0 after the order is placed. However, I do not understand why, since I declare it 0 at the beginning of the code.

Any idea?

#property strict
#property copyright "Davide.P"
//+------------------------------------------------------------------+
void OnTick(void)
  { 
   int TrendOn=0;  
   int total=OrdersTotal();
   if(total<1)
     {
//+------------------------------------------------------------------+        
        //CHK FOR AT LEAST 10 CANDLES INCREMENTING
        for(int i=1;i=10;i++)
            {
            double MaFast=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i);
            double MaFastPrevious=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i+1);
            if (MaFast>MaFastPrevious)    // MA incrementing
               TrendOn=TrendOn+1;
            else;
               TrendOn=0;
            break;
            }
        if(TrendOn=10)
         {
//+------------------------------------------------------------------+
         //OPEN POSITION
         int ticket=OrderSend(Symbol(),OP_BUY,1,Ask,0,Ask-800*Point,Ask+800*Point,NULL,0,0,Blue);
         return;
         }
}} 

Many thanks
Davide
 
if(TrendOn=10)

You should be getting a warning that this is not a boolean expression.

Also, what is this?

for(int i=1;i=10;i++)
else;

Please only post code that you have checked.

 

This should work better(not tested)

void OnTick()
{
   int trendOn=0;
   if(OrdersTotal()<1)
      {
      //CHK FOR AT LEAST 10 CANDLES INCREMENTING
      for(int i=1; i<=10; i++)
         {
         double MaFast=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i);
         double MaFastPrevious=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i+1);
         if (MaFast>MaFastPrevious)    // MA incrementing
            trendOn++;
         else
            {
            trendOn=0;
            break;
            }
         }
      if(trendOn==10)
         {
         //OPEN POSITION
         int ticket=OrderSend(Symbol(),OP_BUY,1,Ask,0,Ask-800*Point,Ask+800*Point,NULL,0,0,Blue);
         return;
         }
      }
}

I have removed the

//+------------------------------------------------------------------+

which break up blocks of code as I actually find them confusing in unexpected positions.

We all have different ways, but I cannot understand why you use them.

 
Keith Watford:
This works perfectly. You are a star!

I see that the problem was with the code syntax. Something I'll watch out for in the future.


Many thanks

Davide

Reason: