Problem in filtering by symbol in a rare circumstances.

 

My EA is attached to several symbols, the opening order depends on the last closed order from history, every single EA works perfect separately for every symbol for a long time without problem until when the 2 or 3 orders for each symbol closes at the same exact time,  at that time it loses control to manage them separately it selects for example the last EURUSD order and continue with GBPUSD. although the condition to filter with symbol exists and works perfect except as I said when the two symbols closes at the same time. 

The log shows that "Last Selected Closed Order is ....."  different from the one the EA is attached.

Thanks for your help.

for (int i = OrdersHistoryTotal() - 1; i >= 0 ; i--)
               {
               if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))continue;
                  {
                  if (OrderSymbol() != Symbol() && OrderMagicNumber() != Magic)continue;
                     {    
                     if (OrderType() == OP_SELL && OrderCloseTime() > 0 && OrderProfit() < 0)
                        {
                        int OrderTicketH = OrderTicket();            // Ticket Number of the selected Order
                        int OrderTypeH = OrderType();                // Order type of the selected Order
                        double LotSizeH = OrderLots();               // Lot size of the selected Order
                        double OrderProfitH = OrderProfit();         // Profit of the selected Order
                        Print("Last Selected Closed Order is : ", Symbol(), " Ticket = ", OrderTicketH, " OrderType = ", OrderTypeH, " LotSize = ", LotSizeH, " Profit = ", OrderProfitH);
                        Sleep(100);
                        RefreshRates();
                        BuyOrder = OrderSend(Symbol(), OP_BUY, LotSize, Ask, UseSlippage, SL * UsePoint, TP * UsePoint), Magic, 0, clrGreen);
                        }
                     }
                  }     
               }
 
if (OrderSymbol() != Symbol() || OrderMagicNumber() != Magic)continue;
alternatively, don't use negative logic (if not continue,) use positive logic (if do):
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
&& OrderSymbol() == Symbol()
&& OrderMagicNumber() == Magic
){ ...
 
whroeder1:
alternatively, don't use negative logic (if not continue,) use positive logic (if do):

This. Negative logic with continue statements is the ghost of MQL past. Back in the old days we had to use this logic because all statements in the expression were always evaluated regardless of whether or not it resolved to a true/false condition. Now MQL works like other programming languages and exits the expression as soon as it can make an absolute resolution. 

 

Symbol

 if (OrderSymbol() != Symbol() && OrderMagicNumber() != Magic)continue;

The order selected here is not a EURUSD but GBPUSD. I can't understand why it selects the GBPUSD order even if the Symbol condition is false

if (OrderSymbol() != Symbol() || OrderMagicNumber() != Magic)continue;

Thanks whroeder1 I'm not sure but the problem is in selecting symbol regardless what the MagicNumber condition is. tell me what do you think and if there is any documentation about negative and positive logic, it may help. 

Thanks for your precious help.

 
Toufik:

The order selected here is not a EURUSD but GBPUSD. I can't understand why it selects the GBPUSD order even if the Symbol condition is false

Thanks whroeder1 I'm not sure but the problem is in selecting symbol regardless what the MagicNumber condition is. tell me what do you think and if there is any documentation about negative and positive logic, it may help. 

Thanks for your precious help.

Flat out - stop using the old style if negative then continue statements. Also, your scoping is all messed up. Probably due to confusion caused by the lack of indentation in the continue statements. See...

   for (int i = OrdersHistoryTotal() - 1; i >= 0 ; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
      {
         continue;
      }
      {
         if (OrderSymbol() != Symbol() && OrderMagicNumber() != Magic)
         {
            continue;
         }         
         {    
            if (OrderType() == OP_SELL && OrderCloseTime() > 0 && OrderProfit() < 0)
            {
               int OrderTicketH = OrderTicket();            // Ticket Number of the selected Order
               int OrderTypeH = OrderType();                // Order type of the selected Order
               double LotSizeH = OrderLots();               // Lot size of the selected Order
               double OrderProfitH = OrderProfit();         // Profit of the selected Order
               Print("Last Selected Closed Order is : ", Symbol(), " Ticket = ", OrderTicketH, " OrderType = ", OrderTypeH, " LotSize = ", LotSizeH, " Profit = ", OrderProfitH);
               Sleep(100);
               RefreshRates();
               BuyOrder = OrderSend(Symbol(), OP_BUY, LotSize, Ask, UseSlippage, SL * UsePoint, TP * UsePoint), Magic, 0, clrGreen);
            }
         }
      }     
   }


So let's address the bigger issue; this is not guaranteed to select the last order in history. In order to get the last order you need a routine to actually retrieve the most recently closed order. You're also introducing sleep on a loop that shares a common resource with other EAs so it's no wonder that your having issues. Split your logic up so you first find the most recently closed position THEN do something with it. 

#define MAGIC 192837
bool buy_when_closed_sell_at_loss()
{
   if(OrderSelect(most_recent_closed(_Symbol, MAGIC), SELECT_BY_TICKET)
      && OrderType() == OP_SELL 
      && OrderProfit() < 0.0
   ){
      int ticket = OrderSend(...);
      return ticket >= 0;
   }
   return false;   
}


int most_recent_closed(string symbol, int magic)
{
   datetime close_time = -1;
   int ticket = -1;
   for(int i=OrdersHistoryTotal()-1; i>=0; --i)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
         && OrderSymbol() = symbol
         && OrderMagicNumber() = magic
         && OrderType() < 2
         && OrderCloseTime() > close_time
      ){
         ticket = OrderTicket();
         close_time = OrderCloseTime();
      }
   }
   return ticket;
}

 

 
nicholi shen:

Flat out - stop using the old style if negative then continue statements. Also, your scoping is all messed up. Probably due to confusion caused by the lack of indentation in the continue statements. See...


So let's address the bigger issue; this is not guaranteed to select the last order in history. In order to get the last order you need a routine to actually retrieve the most recently closed order. You're also introducing sleep on a loop that shares a common resource with other EAs so it's no wonder that your having issues. Split your logic up so you first find the most recently closed position THEN do something with it. 

 

Thank you, I took off the old style "if negative" continue statements and I split the logic as you suggested, in overall I can't see the difference because the reason that causes the issue happens rarely, that's why I need to identify the problem and be sure that it will never happen again, do you think the old negative logic is the reason ?

Thank you again nicholi shen, you have been of great help.

Reason: