Odd issue getting an open position's Open price

idh  

I've had some code that has been working fine on a demo account ever since I wrote it 9 months ago.  Using MT5.

I recently moved to a funded account (live) and have run into issues. Here a snippet of my original code where I located the issue is occurring, that was working fine on demo okay. I'll then show some modifications I made to try resolve it, but that too didnt work.

I'm aware people will have views on the right way and wrong way of doing things, that's the nature of programming and learning. We find our path, improve, so please be gentle :-)

I'm opening a position straightaway, no pending orders. I'm using ORDER_FILLING_IOC, and my accounts are in Hedging mode.

//--- send a trade request
   MqlTradeResult result= {};
   if(OrderSend(request,result) == true)    //order send was successful?
     {
      //success ordersend
      if(result.retcode==TRADE_RETCODE_DONE)     //trade ok?
        {
         ticket=result.order;

         //store the position's open price
         position_open_price = result.price;

the result.price contains the open price of the position. Never had an issue with it on demo test.


When I ran this code on a live funded account, result.order contains 0 (which is the bug), even though a position is open and ticket number is correct. To make things more confusing, sometimes it contains the open price.

So, I changed the code a bit to this:

//--- send a trade request
   MqlTradeResult result= {};
   if(OrderSend(request,result) == true)    //order send was successful?
     {
      //success ordersend
      if(result.retcode==TRADE_RETCODE_DONE)     //trade ok?
        {
         ticket=result.order;
         Print("the deal ticket is=", ticket);
         
         //fixes? 26/09/22
         PositionSelectByTicket(ticket);
         position_open_price=PositionGetDouble(POSITION_PRICE_OPEN);
         Print("Position's open price is ", position_open_price);
         
         //debug
         if(PositionGetDouble(POSITION_PRICE_OPEN) == 0)
         {
           Print("error code:" ,GetLastError());
           SendNotification("error:"+GetLastError()+", ticket " +ticket);
           ResetLastError();
         }
         //end fix 26/09/22

The sendnotification I get contains the correct ticket number for the open position, but the error code 4753

In this altered version, ticket contains the correct ticket number. I can see the position is open in the trade tab, and check the ticket number matches. However, PositionSelectByTicket returns and error 4753 which is  ERR_TRADE_POSITION_NOT_FOUND and the result.price is 0.  Odd, it says position not found, but I can see it is open, and ticket/result.order contains the correct ticket number of the position I can see in the trade terminal.

I've read a few posts about people having similar issues in the past but have not found a resolution. One thing I did think about, was maybe there is some kind of delay going on and that I need to have a small loop around the PositionSelectByTicket that retries the selection a set number of times (not infinite until success as would lock up trade terminal probably).

I should note that position_open_price is type DOUBLE

Can a kind soul spot anything obvious? 


thanks for your time.

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
  • www.mql5.com
Order Properties - Trade Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
idh  

-- UPDATE

Thank you for all your replies, please don't all reply at once will you.

I've solved this. I'm updating this post with a note just in case it is somehow useful to someone out there who experiences the same issue in future.

The issue is we need to introduce a small delay between storing the ticket number and then trying to select the ticket. I suspect it is something to do with the MT5 terminal catching up.


So to use my example above, we add the Sleep command, Sleep(200); introduces a 200milisecond delay before code execution continues. 

//--- send a trade request
   MqlTradeResult result= {};
   if(OrderSend(request,result) == true)    //order send was successful?
     {
      //success ordersend
      if(result.retcode==TRADE_RETCODE_DONE)     //trade ok?
        {
         ticket=result.order;
         Print("the deal ticket is=", ticket);

         //new: introduce a 200ms delay before continuing
         Sleep(200);
         
         //fixes? 26/09/22
         PositionSelectByTicket(ticket);
         position_open_price=PositionGetDouble(POSITION_PRICE_OPEN);
         Print("Position's open price is ", position_open_price);
         
         //debug
         if(PositionGetDouble(POSITION_PRICE_OPEN) == 0)
         {
           Print("error code:" ,GetLastError());
           SendNotification("error:"+GetLastError()+", ticket " +ticket);
           ResetLastError();
         }
         //end fix 26/09/22


Doesn't feel particularly elegant. And I'm probably heading to MQL Hell for this, where yes, I will be judged on the quality of my code.

Instead of using Sleep(200), an alternative is to use a While loop that just keeps looping round and round until the ticket is finally selected (loop is exited, and code execution continues). But again, not very elegant. Be warned, loop could go on forever and may cause unexpected lock ups of MT5 GUI.  There will be better coders out there than me that can offer a better solution than I.


Using While loop version:

//--- send a trade request
   MqlTradeResult result= {};
   if(OrderSend(request,result) == true)    //order send was successful?
     {
      //success ordersend
      if(result.retcode==TRADE_RETCODE_DONE)     //trade ok?
        {
         ticket=result.order;
         Print("the deal ticket is=", ticket);

         //fixes? 26/09/22
         While(PositionSelectByTicket(ticket)==false) //while PositionSelectByTicket function returns false, i.e. it failed, keep on looping and retrying until selected
         {
                //an empty loop that does nothing, could go on forever so be careful. 
		//What if your position has a TP set and it gets hit before the ticket gets selected? ;-) infinity welcomes careful drivers...
         }
        
         position_open_price=PositionGetDouble(POSITION_PRICE_OPEN);
         Print("Position's open price is ", position_open_price);
         
         //debug
         if(PositionGetDouble(POSITION_PRICE_OPEN) == 0)
         {
           Print("error code:" ,GetLastError());
           SendNotification("error:"+GetLastError()+", ticket " +ticket);
           ResetLastError();
         }
         //end fix 26/09/22
Reason: