How to get the ticket number of the closing trade in MQL5 even with requotes?

 
Hi guys,

I want to capture the closing trade (deal #5 on the logs) but can't seem to figure out how. I'm afraid my knowledge of some aof the functions/events/classes on MQL5 is also limited. More specifically on the following:

What exactly happens on requotes? I can't find resources how to deal with requotes.. the examples I have found only points to logging the retcode result. Does the MqlTradeResult gets updated on the next trade if the prices are within the deviation? This doesn't seem to be the case as I also tried printing ontick and no log was generated between the initial failure to close trade and the successful execution of deal#5.

On the function "CTradeCustom::Sell" below, I have following comment 
"Is it right to declare these structures inside a function or should this be on the global scope? TestEA.mq5? or Expert.mqh? For use on the OnTrade(), OnTradeTransaction()?"

Having admited my limited knowledge and experiance on MQL5 and the functions/events/structures I have mentioned. Can anyone please point me to a resource other than the documention that can help with these questions? I have been searching for days now on the documentation and this forum but I cannot find something I can implement as a solution. Please note that since I am not sure if these question are realated to my initial question as per the subject of this thread, I have opted just keep all of them under one thread.

The logs are as follows:
CL      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   Journal|Trading|Trade:Open, Type:ORDER_TYPE_BUY, PO_positionTicket0:4, EntryPrice:1.09506, EntryVolume:0.02000
CJ      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   Journal|Debug|PO_id:EURUSD|TREND_UP, PO_symbol:EURUSD, PO_direction:TREND_UP, PO_validity:true, PO_positionTicket0:4, PO_exitTicket0:0, PO_stopLoss:1.09438, PO_orderstatus:MO_PENDING
LS      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
DN      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTrade function triggered
JL      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
JS      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTrade function triggered
HI      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
HD      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTrade function triggered
FJ      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
QD      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:42   Trigger:TRIGGER_EXIT_STOP_LOSS
OD      0       15:09:49.891    Trade   2020.04.10 18:12:42   requote 1.09430 / 1.09434 / 1.09430 (instant sell 0.02 EURUSD at 1.09438)
LK      0       15:09:49.891    Trades  2020.04.10 18:12:42   requote 1.09430 / 1.09434 (instant sell 0.02 EURUSD at 1.09438, close #4 buy 0.02 EURUSD 1.09506)
HI      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:42   sleeping on requote
GD      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:43   sleeping on requote
FS      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:44   sleeping on requote
EN      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:45   sleeping on requote
DM      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:46   sleeping on requote
RJ      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   Encountered error! retcode:10004, retcode_external:0
DH      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   Journal|Trading|Unable to close position for ticket:4
OP      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   Ticket=0
NK      0       15:09:49.891    Trade   2020.04.10 18:12:47   instant sell 0.02 EURUSD at 1.09430, close #4 (1.09430 / 1.09434 / 1.09430)
FF      0       15:09:49.891    Trades  2020.04.10 18:12:47   deal #5 sell 0.02 EURUSD at 1.09430 done (based on order #5)
HK      0       15:09:49.891    Trade   2020.04.10 18:12:47   deal performed [#5 sell 0.02 EURUSD at 1.09430]
NR      0       15:09:49.891    Trade   2020.04.10 18:12:47   order performed sell 0.02 at 1.09430 [#5 sell 0.02 EURUSD at 1.09430]
PR      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTradeTransaction function triggered
PQ      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTrade function triggered
NO      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTradeTransaction function triggered
FR      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTrade function triggered

And the code snippets below:
TestEA v00.04.mq5
void OnTick()
  {
   // printf("new tick");
   Expert.OnTick();
        return;
  }
void OnTrade(void)// I have not used this function before
  {
   printf("OnTrade function triggered");  // This is just to try and see if this gets triggered before Deal#5 is executed and after the initial requote error
  }

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)// I have not used this function before
  {
   printf("OnTradeTransaction function triggered");  //This is just to try and see if this gets triggered before Deal#5 is executed and after the initial requote error
  }
  
Expert.mqh

case  ORCA_TRIGGER_EXIT_STOP_LOSS:
         PrintFormat("Trigger:%s",EnumToString(trigger)); // See Logs : Trigger:TRIGGER_EXIT_STOP_LOSS
         ticket = Trade.CloseByTicket(PO.positionTicket[0],PO.stopLoss,mSlipPips);
         PrintFormat("Ticket=%i", ticket); // See Logs: Ticket=0. // The EA was not able to capture the ticket for closing position due to requote
         if (ticket>0){
                  PO.exitTicket[0]=ticket;
               }

Trade.mqh // inherits from #include     <Trade/Trade.mqh>
ulong CTradeCustom::CloseByTicket(ulong ticket, double price, int slippage){
   ulong             newTicket = 0;
   string            msg;
   double            actCloseVolume;
   double            actClosePrice;
   
   
   if (PositionSelectByTicket(ticket)==true){
      if (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY){
         newTicket = Sell(ticket, PositionGetDouble(POSITION_VOLUME),PositionGetString(POSITION_SYMBOL),price,slippage,0,0,NULL,0);
      }
      if (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL){
         newTicket = Buy(ticket, PositionGetDouble(POSITION_VOLUME),PositionGetString(POSITION_SYMBOL),price,slippage,0,0,NULL,0);
      }
      
      if (newTicket>0){
         actCloseVolume = HistoryOrderGetDouble(newTicket,ORDER_VOLUME_CURRENT);
         actClosePrice  = HistoryOrderGetDouble(newTicket,ORDER_PRICE_OPEN);
      } else {
                msg = StringFormat("Unable to close position for ticket:%i", ticket);
                Journal.Trading(msg);
               }
   
      } else { //Position might have been closed?
               msg = StringFormat("Ticket # %i not found or closed already!", ticket); 
               Journal.Trading(msg);
               Journal.ErrorCheck(); 
               }
   

   
   return newTicket;
}

ulong           CTradeCustom::Sell(ulong position, const double volume,const string symbol=NULL,double price=0.0, const int slippage=2,const double sl=0.0,const double tp=0.0,const string comment="", const datetime expiration=0) {
        if (price==0.0) price   =       SellPrice(symbol);
        int slip = slippage*PipPointFactor(symbol);
        
        double stopLoss = (position==NULL)?sl:0;
        double takeProfit = (position==NULL)?tp:0;
        ulong posTicket   = (position==NULL)?NULL:position;
        
        ulong ticket=0;
        MqlTradeRequest request; // Is it right to declare these structures inside function or should this be on the global scope? TestEA.mq5 or Expert.mqh? For use on the OnTrade(), OnTradeTransaction()
        MqlTradeResult result; // Is it right to declare these structures inside function or should this be on the global scope? TestEA.mq5 or Expert.mqh? For use on the OnTrade(), OnTradeTransaction()
        
        request.action          =  TRADE_ACTION_DEAL;
        request.type            =  ORDER_TYPE_SELL;
        request.type_filling    =  ORDER_FILLING_FOK;   // order Execution type
        request.symbol          =  symbol;
        request.volume          =  volume;
        request.price           =  price;
        request.deviation       =  slip;
        request.sl              =  stopLoss;
        request.tp              =  takeProfit;
        request.comment         =  comment;
        request.expiration      =  expiration;
        request.type_time       =  ORDER_TIME_GTC;   // Order Expiration type
        request.magic           =  mMagic;
        //request.stoplimit // For pending orders
        request.position        =  posTicket;// Position ticket for modifying position
        //request.position_by // Ticket of an opposite position
        
        if (OrderSend(request, result)==true && result.retcode == 10009 && result.order>0) {ticket = result.order;}
        else {
              for(int retry=0; retry<5; retry++){
                 if (result.retcode == 10004){
                    printf("sleeping on requote"); // I was under the impression that if I retry reading the result again I'll be able to capture the result of the requote
                    Sleep(1000);
                    continue;
                 } 
                 if (result.retcode == 10009 && result.order>0){ticket = result.order;break;} else{PrintFormat("Encountered error! retcode:%i, retcode_external:%i",result.retcode, result.retcode_external);}
              }
              if (result.retcode != 10009 && result.order==0){PrintFormat("Encountered error! retcode:%i, retcode_external:%i",result.retcode, result.retcode_external);}
              }

        return ticket;
}


I appreciate any help guys. Thank you!

Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Request Result Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Request Result Structure
  • www.mql5.com
Trade Request Result Structure - Data Structures - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
On requote all you are doing is reading a certain memory area then sleeping for 1 second, repeating this 5 times.

You need to modify your order and resend it. Else nothing happens...

Your code is not doing anything with requotes, except for sleeping... Or being lazy...
 
Dominik Egert:
On requote all you are doing is reading a certain memory area then sleeping for 1 second, repeating this 5 times.

You need to modify your order and resend it. Else nothing happens...

Your code is not doing anything with requotes, except for sleeping... Or being lazy...


Thanks Dominik. I've added some more comments on the logs to provide more clarity, can you please have a look?

CL      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   Journal|Trading|Trade:Open, Type:ORDER_TYPE_BUY, PO_positionTicket0:4, EntryPrice:1.09506, EntryVolume:0.02000 // This is the log for entering the trade with ticket #4
CJ      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   Journal|Debug|PO_id:EURUSD|TREND_UP, PO_symbol:EURUSD, PO_direction:TREND_UP, PO_validity:true, PO_positionTicket0:4, PO_exitTicket0:0, PO_stopLoss:1.09438, PO_orderstatus:MO_PENDING // This is the log for entering the trade
LS      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered // This part was triggered by the 'OnTradeTransaction' Function on TestEA.mq5, I've added this to see if I can use the 'Ontrade Transaction' to capture the intended ticket number
DN      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTrade function triggered // This part was triggered by the 'OnTrade' Function on TestEA.mq5, I've added this to see if I can use the 'Ontrade Transaction' to capture the intended ticket number
JL      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
JS      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTrade function triggered
HI      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
HD      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTrade function triggered
FJ      0       15:09:49.881    TestEA v00.04 (EURUSD,M5)       2020.04.10 17:59:00   OnTradeTransaction function triggered
QD      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:42   Trigger:TRIGGER_EXIT_STOP_LOSS // This part was triggred by the line 'case  ORCA_TRIGGER_EXIT_STOP_LOSS:' onthe Expert.mqh which is triggered on the 'OnTick' function on the TestEA.mq5.
OD      0       15:09:49.891    Trade   2020.04.10 18:12:42   requote 1.09430 / 1.09434 / 1.09430 (instant sell 0.02 EURUSD at 1.09438) // This was the initial attempt to close but failed due to requote
LK      0       15:09:49.891    Trades  2020.04.10 18:12:42   requote 1.09430 / 1.09434 (instant sell 0.02 EURUSD at 1.09438, close #4 buy 0.02 EURUSD 1.09506) 
HI      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:42   sleeping on requote // This was my attempt to see if I can recapture the closing ticket after the requote. Please see 'CTradeCustom::Sell' function
GD      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:43   sleeping on requote
FS      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:44   sleeping on requote
EN      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:45   sleeping on requote
DM      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:46   sleeping on requote
RJ      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   Encountered error! retcode:10004, retcode_external:0 //Please see 'CTradeCustom::Sell' function
DH      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   Journal|Trading|Unable to close position for ticket:4 //Please see 'CTradeCustom::Sell' function
OP      0       15:09:49.891    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   Ticket=0 // Returned value of the funtion 'CTradeCustom::CloseByTicket' under Trade.mqh
NK      0       15:09:49.891    Trade   2020.04.10 18:12:47   instant sell 0.02 EURUSD at 1.09430, close #4 (1.09430 / 1.09434 / 1.09430) // Attempt to close again.
FF      0       15:09:49.891    Trades  2020.04.10 18:12:47   deal #5 sell 0.02 EURUSD at 1.09430 done (based on order #5) // Succeded in closing the trade. This deal #5 is the closing ticket for #4. ticket #5 is the one I wanted to capture
HK      0       15:09:49.891    Trade   2020.04.10 18:12:47   deal performed [#5 sell 0.02 EURUSD at 1.09430]
NR      0       15:09:49.891    Trade   2020.04.10 18:12:47   order performed sell 0.02 at 1.09430 [#5 sell 0.02 EURUSD at 1.09430]
PR      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTradeTransaction function triggered
PQ      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTrade function triggered
NO      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTradeTransaction function triggered
FR      0       15:09:49.893    TestEA v00.04 (EURUSD,M5)       2020.04.10 18:12:47   OnTrade function triggered
It would seem that the successful dea#5 was triggred from the 'broker' side (this was run on the strategy tester). Initially i thought is was rerun (i.e. the trigger to close on stop loss and the succeeding functions were run again) on the new tick but this wasn't the case. I tried 
// printf("new tick");

on the 'OnTick' function of the TestEA.mq5 but nothing was logged just before deal#5 was executed.

 
You need to do another Sendorder.
It does not change anything, adding more log Output.

 
Dominik Egert:
You need to do another Sendorder.
It does not change anything, adding more log Output.

I've updated my previous comment to include the following

It would seem that the successful deal#5 was triggred from the 'broker' side (this was run on the strategy tester). Initially i thought is was rerun (i.e. the trigger to close on stop loss and the succeeding functions were run again) on the new tick but this wasn't the case. I tried 
// printf("new tick");

on the 'OnTick' function of the TestEA.mq5 but nothing was logged just before deal#5 was executed.

 
I have to add, the new price was well within the deviation.