Preventing expert advisor from opening positions too close to eachother on same signal.

 

So, I've been dealing with the recurring issue that my EA kept opening positions till the numeric block stopped it:

if(CalculateCurrentOrders(Symbol) < MaxOrdersPerSymbol) DoTrading();
else return;

so what i tried to do is making a bool function to put a red or a green light in a determined range so that when the ea detects an order in a Range defined by ATR, it won't open new positions. 

This works pretty fine rn, but I keep getting this warning: 


bool IsOutOfRange()
  {
   double RangeUP;
   double RangeDOWN;
   double ATR = iATR(Symbol(),Period(),x,x);

   RangeUP     = Close[0] + (ATR);
   RangeDOWN   = Close[0] - (ATR);


   



   if(CalculateCurrentOrders(Symbol()) < 1)
   {
      return(true); // to make it return true if there are no opened orders.

   }
   else
     {   
         for(int i=OrdersTotal()-1; i>=0; --i) 
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderSymbol() == _Symbol && (OrderMagicNumber() != 0)))  // to select orders from the current symbol and whatever magicnumber != 0
            {
               if(OrderOpenPrice() < RangeUP && OrderOpenPrice() > RangeDOWN) 
               return(false);
               else return(true);
               
            }
      
     }


  }



So I was wondering: is there anyway I can do this better? Because this warning makes me unconfident with the functional performance of this function. Thanks in advance! 

 

So you return false on the main control path.

bool IsOutOfRange()
  {
   double RangeUP;
   double RangeDOWN;
   double ATR = iATR(Symbol(),Period(),x,x);

   RangeUP     = Close[0] + (ATR);
   RangeDOWN   = Close[0] - (ATR);


   



   if(CalculateCurrentOrders(Symbol()) < 1)
   {
      return(true); // to make it return true if there are no opened orders.

   }
   else
     {   
         for(int i=OrdersTotal()-1; i>=0; --i) 
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderSymbol() == _Symbol && (OrderMagicNumber() != 0)))  // to select orders from the current symbol and whatever magicnumber != 0
            {
               if(OrderOpenPrice() < RangeUP && OrderOpenPrice() > RangeDOWN) 
               return(false);
               else return(true);
               
            }
      
     }
   return(false);
  }
 
Marco vd Heijden:

So you return false on the main control path.

Won't this return false no matter what? 

 
Antonio Bartolucci:

Won't this return false no matter what? 

Not if your codes returns true before it reaches the end.

You can also declare a variable at the start of the function and then assign it a value in the loop and then return the variable as outcome.

bool IsOutOfRange()
  {
   bool   out_of_range = false;
   double RangeUP;
   double RangeDOWN;
   double ATR = iATR(Symbol(),Period(),x,x);

   RangeUP     = Close[0] + (ATR);
   RangeDOWN   = Close[0] - (ATR);

   if(CalculateCurrentOrders(Symbol()) < 1)
   {
      //return(true); // to make it return true if there are no opened orders.
      out_of_range = 1; 
   }
   else
     {   
         for(int i=OrdersTotal()-1; i>=0; --i) 
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderSymbol() == _Symbol && (OrderMagicNumber() != 0)))  // to select orders from the current symbol and whatever magicnumber != 0
            {
               if(OrderOpenPrice() < RangeUP && OrderOpenPrice() > RangeDOWN) 
                 {
                  out_of_range = 0;
                  //return(false);
                 }
               
               //else return(true);
               else
                {
                 out_of_range = 1; 
                } 
               
            }
     }
   return(out_of_range);
  }

Here is an example but i didn't test it/.

Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
//| Expert initialization function                                   | //| Expert deinitialization function                                 | //| Expert tick function                                             | //| test1                                                            |...
 
Marco vd Heijden:

Not if your codes returns true before it reaches the end.

You can also declare a variable at the start of the function and then assign it a value in the loop and then return the variable as outcome.

ok thanks! I'll try it! 

 
if(OrderOpenPrice() < RangeUP && OrderOpenPrice() > RangeDOWN) 
return(false);
else return(true);

If you find one order inside the range you return false; fine.

Otherwise, it is outside, but there could be other orders inside the range; returning true is wrong. Process all orders.

if(RangeDown < OrderOpenPrice() && OrderOpenPrice() < RangeDOWN) return false; // Inside range.
// else continue processing all orders.
Then at the end of the loop, you haven't found any orders inside the range; return true.
 
William Roeder:

If you find one order inside the range you return false; fine.

Otherwise, it is outside, but there could be other orders inside the range; returning true is wrong. Process all orders.

I didn’t think about this to be honest. Thanks for the tip. I was actually mainly concerned about the latest opened order because ( inevitably ) the latest opened order is more likely to be in the range. Without processing the other orders it should be able to not open another one too close to the last one, am I wrong? 
Reason: