Wrong symbol for Pending Order ticket during EA backtesting

 

Hi everyone,

I am trying to implement a method for modyfing open pending Orders (mainly SELL STOPS and BUY STOPS) similar to modifying an open Position like a trailing stop-loss algorithm would do. The objective is to obtain a better price than the market. Anyway.


The code draft (work under progress) is as follows and it is executed at every tick:


void AdjustTrailingPendingStops(int t_pips)
{
   ulong tckt;
   uint rcode=TRADE_RETCODE_DONE;
   MqlTick last_tick;

  
   
   //Adjust existing trailing pending orders
   for (int i=0; i<OrdersTotal(); i++)
   {

      if((tckt=OrderGetTicket(i))>0) //automatically selects the order
      {
      
                
      string symbol = OrderGetString(ORDER_SYMBOL);
      string comment = OrderGetString(ORDER_COMMENT);

     
     
      //Only manipulate Price Hunter pending orders
      if (StringCompare(comment, "Price Hunter") == 0)
      {
      
 
         int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
         double points=SymbolInfoDouble(symbol,SYMBOL_POINT);
         
         //get the order's opening price and size
         double price =         OrderGetDouble(ORDER_PRICE_OPEN);
         double order_size =    OrderGetDouble(ORDER_VOLUME_CURRENT);
      
         //get current symbol ask and bid prices
         SymbolInfoTick(symbol,last_tick);
         double ask=last_tick.ask; //SymbolInfoDouble(symbol,SYMBOL_ASK);
         double bid=last_tick.bid; //SymbolInfoDouble(symbol,SYMBOL_BID);
         
         double T1=NormalizeDouble(t_pips*points,digits);
         
         
         //get the order type
         if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) //It is a Buy stop
         {
            if (NormalizeDouble(price-ask, digits) > T1)
            {

              trade.OrderModify(tckt, NormalizeDouble(ask+T1,digits), 0, 0, ORDER_TIME_GTC, 0, 0);
              rcode=  trade.ResultRetcode();
         
            }
         }
         else if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) // It is a Sell stop    
         {
            if (NormalizeDouble(bid-price,digits) > T1)
            {
              trade.OrderModify(tckt, NormalizeDouble(bid-T1,digits), 0, 0, ORDER_TIME_GTC, 0, 0);
              rcode=  trade.ResultRetcode();
 
            }
         }
      
      
         if (rcode!=TRADE_RETCODE_DONE)
            Alert("Error modifying pending order:",GetLastError(),"!!");
          

 
       } //price hunter comment
      } //select ticket           
   } //for loop
}


Now it does work as I wanted to and I have been testing it on real-tick historical data. However, sometimes it throws up a weird error and I cannot understand what is going on.


What will happen is that it will get the ticket for the order to modify and try to modify it, but in the terminal (Metatrader 5) it will complain that the price requested for the symbol on the order is invalid.  The problem is that although I requested the correct ticket and price for the symbol I want to modify, the terminal  seems to mix up the ticket to a symbol of another pending order or sometimes to a position. You can see in the attached images, where the terminal has got the wrong ticket+symbol pair


Ticket for pending order #10 is eurgbp and not gbpusd as the journal says.



I am not sure if this is some synchronisation problem related with the terminal or my code requesting modifications at every tick but I do not know how to solve it and I would appreciate some help.


Thanks

Files:
terminal1.png  47 kb
terminal2.png  16 kb
 
Which MT5 build are you using ?
 
Alain Verleyen:
Which MT5 build are you using ?


Version 5 .00 build 2007

25 Feb 2019

 
ForexTraingRobot01:


Version 5 .00 build 2007

25 Feb 2019

The problem is certainly due to your order #11 on GBPUSD triggered at the exact same tick you are trying to modify #10 on EURGBP.

However that seems an MT5 issue. Not sure how you can avoid it.

Is it reproducible (you get always the same running the same backtest) ?
 
Alain Verleyen:
Is it reproducible (you get always the same running the same backtest) ?


Yes it is

 
ForexTraingRobot01:


Yes it is

You can try :

   for (int i=OrdersTotal()-1; i>=0; i--)

Not sure it will change anything however.

If it doesn't work, can you post a testing EA and conditions (broker, dates, settings...) to reproduce the issue ? I will check and report it to Metaquotes if needed.

 
Alain Verleyen:

You can try :

Not sure it will change anything however.

If it doesn't work, can you post a testing EA and conditions (broker, dates, settings...) to reproduce the issue ? I will check and report it to Metaquotes if needed.


No it didn't change anything still the problem persists.

However, I managed to find a solution. Instead of using

trade.OrderModify(tckt, NormalizeDouble(ask+T1,digits), 0, 0, ORDER_TIME_GTC, 0, 0);


I went with MqlTradeRequest and OrderSend() as follows:


void AdjustTrailingPendingStops(int t_pips)
{
   ulong  tckt=0;
   MqlTradeRequest request={0}; 
   MqlTradeResult  result={TRADE_RETCODE_DONE};


  
   
   //Adjust existing trailing pending orders
   for (int i=0; i<OrdersTotal(); i++)
   {

      if((tckt=OrderGetTicket(i))>0) //automatically selects the order
      {
      
                
      string symbol = OrderGetString(ORDER_SYMBOL);
      string comment = OrderGetString(ORDER_COMMENT);

     
     //setup trade request
     request.action=TRADE_ACTION_MODIFY;  
     request.order = tckt;                            
     request.symbol   =symbol;                                   
     request.deviation=5;  
     request.tp = 0;
     request.sl = 0;
   
     
     
     
      //Only manipulate Price Hunter pending orders
      if (StringCompare(comment, "Price Hunter") == 0)
      {
      
 
         int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
         double points=SymbolInfoDouble(symbol,SYMBOL_POINT);
         
         //get the order's opening price and size
         double price =         OrderGetDouble(ORDER_PRICE_OPEN);
         double order_size =    OrderGetDouble(ORDER_VOLUME_CURRENT);
      
         //get current symbol ask and bid prices

         double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
         double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
         
         double T1=NormalizeDouble(t_pips*points,digits);
         
         
         //get the order type
         if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) //It is a Buy stop
         {
            if (NormalizeDouble(price-ask, digits) > T1)
            {
              request.price    =NormalizeDouble(ask+T1,digits); 
              if(!OrderSend(request,result))
               PrintFormat("OrderSend error %d",GetLastError());  // if unable to send the request, output the error code

            }
         }
         else if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) // It is a Sell stop    
         {
            if (NormalizeDouble(bid-price,digits) > T1)
            {          
              request.price    =NormalizeDouble(bid-T1, digits); 
              if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());  // if unable to send the request, output the error code
            }
         }
      
      
         if (result.retcode!=TRADE_RETCODE_DONE)
            Alert("Error modifying pending order:",GetLastError(),"!!");
          
          
         
         ZeroMemory(request);
         ZeroMemory(result);
 
       } //price hunter comment
      } //select ticket           
   } //for loop
}


This works fine without causing any of the abovementioned errors in the terminal.

Not sure why the CTrade option doesn't work. I was under the impression that both CTrade and OrderSend() use the same calls.


I had the following initialisations for CTrade on OnInit()

   trade.SetDeviationInPoints(Slippage);
   //--- order filling mode, the mode allowed by the server should be used
   trade.SetTypeFilling(_checked_filling);
   //--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()
   trade.SetAsyncMode(false);

but I wouldn't imagine those being the problem.


Anyway.

As for debugging this unfortunately I cannot provide my EA but if you really want to spend the time reproducing this using my function I can try to help with information.

Thanks

 
ForexTraingRobot01:

Show all Tester settings. What is the name of the trading server?

 
fxsaber:

Show all Tester settings. What is the name of the trading server?


FXPro-MT5: Demo account

 
ForexTraingRobot01:


FXPro-MT5: Demo account

And Tester-screen.

Настройка тестирования эксперта в Тестере Стратегий

 
fxsaber:

And Tester-screen.


  I am actually testing stuff right now so it is greyed out but these are my settings.


 BTW it is a multi-currency EA

Files:
Untitled.png  11 kb