Download MetaTrader 5

HistoryOrderSelect not working for executed pending order

To add comments, please log in or register
Martin Bittencourt
142
Martin Bittencourt  

Hi!


I'm facing a problem when calling HistoryOrderSelect. I have an EA where I put a pending order and it is eventually executed, but HistoryOrderSelect fails to cath its data with the correct ticket and HistoryOrdersTotal returns 0 even though the order was clearly executed (see prints). This is a curious bug since I already used position orders before and this function as well and everything worked fine while there is no real difference between that code and the one I'm using.

What could be happening for this function to not work properly?


Diary


History


PendingOperationStatus getPendingOpStatus(ulong ticket)
{  
   if (ticket == 0)
      return POS_NoOp;
      
   //If it comes here, probably price returned: partial or no execution
   if (!OrderSelect(ticket))
   {
      const int orderSelectError = GetLastError();
      
      if (HistoryOrderSelect(ticket))
      {
         const ulong resp = HistoryOrderGetInteger(ticket,ORDER_STATE);
         
         if (resp == ORDER_STATE_FILLED)
            return POS_Executed;
         else if (resp == ORDER_STATE_CANCELED)
         {
            //Print("getPendingOpStatus: Canceled");
            return POS_Canceled;
         }
         else
         {
            Print("getPendingOpStatus: Something else: ",resp);
            return POS_Other;
         }
      }
      else
      {
         Print("getPendingOpStatus: Both OrderSelect (",orderSelectError,") and HistoryOrderSelect (",GetLastError(),") failed");
         
         return POS_Other;
      }
   }
         
   long state = OrderGetInteger(ORDER_STATE);
   
   switch (int(state))
   {
      case ORDER_STATE_STARTED:
         //Print("getPendingOpStatus: Status: STARTED");
         
         return POS_NotExecuted;
         
      case ORDER_STATE_PLACED:
         //Print("getPendingOpStatus: Status: PLACED");
         
         return POS_NotExecuted;
         
      case ORDER_STATE_PARTIAL:
         //Print("getPendingOpStatus: Status: PARTIAL");
         
         return POS_Partial;
         
      case ORDER_STATE_FILLED:
         //Print("getPendingOpStatus: Status: FILLED");
         
         return POS_Executed;
         
      case ORDER_STATE_REQUEST_ADD:
         //Print("getPendingOpStatus: Status: REQUEST ADD");
         
         return POS_NotExecuted;
         
      default:
         Print("getPendingOpStatus: Status: OTHER (",state,")");
         return POS_Other;
   }
}
Alain Verleyen
Moderator
33491
Alain Verleyen  

Which MT5 build are you using ?

Is this your real code ? In your log we can see "High Pending order 2 status: 0", but it's not in the code you posted.

Martin Bittencourt
142
Martin Bittencourt  

Hi, Alain!

I'm using MetEditor Version: 5.00 build 1643 25 Jul 2017.

About the code, yes, the code is the function I use to check for order status. The "High Pending..." was a print inside the function calling getPendingOpStatus(). It's just a print with the result, nothing important.

I did a second, very simple EA to check if it wasn't some weird bug being generated by another part of the EA, but the result was the same. Here it is:


#include <Trade\MTradeSimple.mqh>
#include <Common.mqh>

#define TRADE_SLEEP  50

// Input variables 
sinput int MagicNumber = 0; //Magic number

sinput string Asset_Info = "============================="; //----------------ASSET DETAILS----------------
input double AssetTick = 0.5; //Asset's tick
input int AssetTickDecRelevance = 1; //Asset's quote relevant decimal numbers
input double AssetVolumeTick = 1; //Asset's volume tick
input int AssetVolumeDecRelevance = 0; //Asset's volume relevant decimal numbers
input double AssetMinFinancialVariance = 5.0; //Minimal financial virance
input double AssetMaxVolumePerOperation = 100; //Asset's maximum acceptable volume
input double AssetMinEquityForMinVolume = 1500; //Minimal equity to operate minimal volume

MTradeSimple glTrade;

bool openPositions = false;
ulong opTicket;

int OnInit()
{
   
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   
}

void OnTick()
{
   if (!openPositions)
   {
      if (!glTrade.sendNewPendingOrder(ORDER_TYPE_BUY_STOP,
                                       10,
                                       getCurrPrice() + AssetTick * 10))
      {      
         Print("Error putting operation");
      }
         
      Sleep(TRADE_SLEEP);
      
      opTicket = glTrade.tradeResult.order;
      
      openPositions = true;
   }
   
   PendingOperationStatus opStatus = getPendingOpStatus(opTicket);
   
   Print("Op status: ",opStatus);
}

The function above is inside the common header file. MTradeSimple's only used function is as follows:

Martin Bittencourt
142
Martin Bittencourt  
bool MTradeSimple::sendNewPendingOrder(const ENUM_ORDER_TYPE type, 
                                       const double volume,
                                       const double price,
                                       const double stopLoss = 0,
                                       const double stopLossLimit = 0,
                                       const double takeProfit = 0,
                                       const ulong deviation = 0, 
                                       const ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_DAY, //Bovespa!
                                       datetime expiration = 0) //Format:  D'2012.01.10 15:00'
{
   ZeroMemory(tradeRequest);
   
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   
   tradeRequest.type = type; //BUY_STOP, etc.; 
   tradeRequest.type_filling = ORDER_FILLING_RETURN;
   tradeRequest.symbol = _Symbol;
   tradeRequest.volume = volume;
   tradeRequest.price = price;
   
   tradeRequest.sl = stopLoss;
   tradeRequest.tp = takeProfit;
   tradeRequest.stoplimit = stopLossLimit; //only needed when placing a stop limit order
   tradeRequest.deviation = deviation;
   
   tradeRequest.type_time = typeTime;
   tradeRequest.expiration = expiration;
   
   return checkOrderAndSend(tradeRequest,tradeResult);
}


And getCurrPrice just return the current asset's quote, nothing out of the ordinary.

Martin Bittencourt
142
Martin Bittencourt  

I'm sorry, but since it seems no one knows about this problem, how may I report this to the MT5 company?

Alain Verleyen
Moderator
33491
Alain Verleyen  
Martin Bittencourt:

I'm sorry, but since it seems no one knows about this problem, how may I report this to the MT5 company?

Seems I forgot to answer :-)

This is not a bug, but a "latency" issue (not sure about the best term). Your pending request is sent, so OrderSend() returns true but the order is not yet executed, it will be a bit later (or sometimes a lot later). There are several ways to deal with that.

Martin Bittencourt
142
Martin Bittencourt  
Alain Verleyen:

Seems I forgot to answer :-)

This is not a bug, but a "latency" issue (not sure about the best term). Your pending request is sent, so OrderSend() returns true but the order is not yet executed, it will be a bit later (or sometimes a lot later). There are several ways to deal with that.


Hi, Verleyen!

No problems about the delay =)

About the problem, I'm truly skeptic this is a "latency" issue as you described. As you may recall by reading my original post, there is no problem until the order is executed. Till that moment I'm able to correctly access the pending order status. It's only AFTER execution that the problem starts with me being unable to locate the order any more either with OrderSelect or HistoryOrderSelect; the order just disappears from the system. It's worth also mentioning this happens in backtesting, so server latency explanations don't fit here. And the problem continues on and on without end.

Nguyen Nga
11049
Nguyen Nga  

your code is wrong at function getPendingOpStatus.

Have not history of pending order so can not use : HistoryOrderSelect(ticket))

Martin Bittencourt
142
Martin Bittencourt  
Nguyen Nga:

your code is wrong at function getPendingOpStatus.

Have not history of pending order so can not use : HistoryOrderSelect(ticket))


Hi! Thanks for your time.

I wasn't able to clearly understand your comment, but if you mean there wasn't any History, I'm sorry, but that is clear I have in my second print (and, as the log shows, I not only had a pending order set, but it was executed). Either way could you please write the full sentence and explain what you mean?

Nguyen Nga
11049
Nguyen Nga  
Martin Bittencourt:

Hi! Thanks for your time.

I wasn't able to clearly understand your comment, but if you mean there wasn't any History, I'm sorry, but that is clear I have in my second print (and, as the log shows, I not only had a pending order set, but it was executed). Either way could you please write the full sentence and explain what you mean?


Let print ticket of pending before getPendingOpStatus

 Print("opTicket : ",opTicket);

PendingOperationStatus opStatus = getPendingOpStatus(opTicket);
   
   Print("Op status: ",opStatus);

Martin Bittencourt
142
Martin Bittencourt  
Nguyen Nga:

Let print ticket of pending before getPendingOpStatus


Well, I can't see any error occurring. The "opTicket" is a global variable in my EA example and, as such, it maintains the value of the order ticket after the pending order is executed as the print following your suggestion confirmed. So I can't see which error you're seeing in my code. (Maybe you could give a full explanation/description of the problem you're seeing?)


Print

12
To add comments, please log in or register