[Bug?] OrderSendAsync seems to be sending duplicate events

 

Using OrderSendAsync to quickly send several orders, passes the same order twice to the OnTradeTransaction event handler.

Consider this EA example, which uses Trade\Trade.mqh to place 5 Buy Stop orders

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>

int OnInit()
  {
   CSymbolInfo si;
   CTrade t;

   si.RefreshRates();
   t.SetAsyncMode(true);        // <--------- Async ON
   t.LogLevel(LOG_LEVEL_ALL);

   for(int i=1; i<=5; i++)
     {
      t.BuyStop(1,si.Ask()+100*i);
     }

   return(INIT_SUCCEEDED);
  }

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if(trans.type==TRADE_TRANSACTION_REQUEST) 
     {
      PrintFormat("Order ticket: %u",result.order);
     }
  }

Running the EA, produces the following output (yours might be different):

2017.07.17 09:22:01.751 delme (EURUSD,M15)      CTrade::OrderSend: buy stop 1.00 EURUSD at 101.14754 [placed]
2017.07.17 09:22:01.751 delme (EURUSD,M15)      CTrade::OrderSend: buy stop 1.00 EURUSD at 201.14754 [placed]
2017.07.17 09:22:01.751 delme (EURUSD,M15)      CTrade::OrderSend: buy stop 1.00 EURUSD at 301.14754 [placed]
2017.07.17 09:22:01.751 delme (EURUSD,M15)      CTrade::OrderSend: buy stop 1.00 EURUSD at 401.14754 [placed]
2017.07.17 09:22:01.752 delme (EURUSD,M15)      CTrade::OrderSend: buy stop 1.00 EURUSD at 501.14754 [placed]
2017.07.17 09:22:01.933 delme (EURUSD,M15)      Order ticket: 103935217
2017.07.17 09:22:01.934 delme (EURUSD,M15)      Order ticket: 103935218
2017.07.17 09:22:02.022 delme (EURUSD,M15)      Order ticket: 103935219
2017.07.17 09:22:02.022 delme (EURUSD,M15)      Order ticket: 103935219 <------- REPEAT?
2017.07.17 09:22:02.022 delme (EURUSD,M15)      Order ticket: 103935220
2017.07.17 09:22:02.023 delme (EURUSD,M15)      Order ticket: 103935221

Notice how the create event for Order ticket #103935219 is received twice by the OnTradeTransaction handler.

Is this expected or is it a bug, or am I missing something?

Using MetaTrader 5.00 build 1629 from 14 July 2017.


Thanks.

Files:
delme.mq5  1 kb
 

TRADE_TRANSACTION_REQUEST

Notification of the fact that a trade request has been processed by a server and processing result has been received. Only type field (trade transaction type) must be analyzed for such transactions in MqlTradeTransaction structure. The second and third parameters of OnTradeTransaction (request and result) must be analyzed for additional data.

 

Help + my:

//+------------------------------------------------------------------+
//|                                    TRADE_TRANSACTION_REQUEST.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
input int MagicNumber=1234567;

//--- enable CTrade trading class and declare the variable of this class 
#include <Trade\Trade.mqh> 
CTrade m_trade;
//--- flags for installing and deleting the pending order 
bool pending_done=false;
//--- pending order ticket will be stored here 
ulong order_ticket;
//+------------------------------------------------------------------+ 
//| Expert initialization function                                   | 
//+------------------------------------------------------------------+ 
int OnInit()
  {
//--- set MagicNumber to mark all our orders 
   m_trade.SetExpertMagicNumber(MagicNumber);
//--- trade requests will be sent in asynchronous mode using OrderSendAsync() function 
   m_trade.SetAsyncMode(true);
//--- initialize the variable by zero 
   order_ticket=0;
//--- 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+ 
//| Expert tick function                                             | 
//+------------------------------------------------------------------+ 
void OnTick()
  {
//---installing a pending order 
   if(!pending_done)
     {
      for(int i=1; i<=5; i++)
        {
         pending_done=false;
         order_ticket=0;
         double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
         bool res=m_trade.BuyStop(0.1,buy_stop_price,_Symbol);
         //--- if BuyStop() function performed successfully  
         if(res)
           {
            pending_done=true;
            //--- get a result of the request sending from ctrade 
            MqlTradeResult trade_result;
            m_trade.Result(trade_result);
            //--- get request_id for the sent request 
            uint request_id=trade_result.request_id;
            Print("Request has been sent to set a pending order. Request_ID=",request_id);
            //--- storing the order ticket (will be zero if using the asynchronous mode of sending to CTrade) 
            order_ticket=trade_result.order;
            ////--- all is done, early exit from OnTick() handler 
            //return;
           }
        }
     }
//---         
  }
//+------------------------------------------------------------------+ 
//| TradeTransaction function                                        | 
//+------------------------------------------------------------------+ 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value  
   ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
//--- if the transaction is the request handling result, only its name is displayed 
   if(type==TRADE_TRANSACTION_REQUEST)
     {
      Print(EnumToString(type));
      //--- display the handled request string name 
      Print("------------RequestDescription\r\n",RequestDescription(request));
      //--- display request result description 
      Print("------------ResultDescription\r\n",TradeResultDescription(result));
      //--- store the order ticket for its deletion at the next handling in OnTick() 
      if(result.order!=0)
        {
         //--- delete this order by its ticket at the next OnTick() call 
         order_ticket=result.order;
         Print(" Pending order ticket ",order_ticket,"\r\n");
        }
     }
   else // display the full description for transactions of another type 
//--- display description of the received transaction in the Journal 
      Print("------------TransactionDescription\r\n",TransactionDescription(trans));

//---      
  }
//+------------------------------------------------------------------+ 
//| Returns transaction textual description                          | 
//+------------------------------------------------------------------+ 
string TransactionDescription(const MqlTradeTransaction &trans)
  {
//---  
   string desc=EnumToString(trans.type)+"\r\n";
   desc+="Symbol: "+trans.symbol+"\r\n";
   desc+="Deal ticket: "+(string)trans.deal+"\r\n";
   desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
   desc+="Order ticket: "+(string)trans.order+"\r\n";
   desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
   desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
   desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
   desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
   desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
   desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
   desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
   desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
   desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
   desc+="Position: "+(string)trans.position+"\r\n";
   desc+="Position by: "+(string)trans.position_by+"\r\n";
//--- return the obtained string 
   return desc;
  }
//+------------------------------------------------------------------+ 
//| Returns the trade request textual description                    | 
//+------------------------------------------------------------------+ 
string RequestDescription(const MqlTradeRequest &request)
  {
//--- 
   string desc=EnumToString(request.action)+"\r\n";
   desc+="Symbol: "+request.symbol+"\r\n";
   desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
   desc+="Order ticket: "+(string)request.order+"\r\n";
   desc+="Order type: "+EnumToString(request.type)+"\r\n";
   desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
   desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
   desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
   desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
   desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
   desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
   desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
   desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
   desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
   desc+="Comment: "+request.comment+"\r\n";
//--- return the obtained string 
   return desc;
  }
//+------------------------------------------------------------------+ 
//| Returns the textual description of the request handling result   | 
//+------------------------------------------------------------------+ 
string TradeResultDescription(const MqlTradeResult &result)
  {
//--- 
   string desc="Retcode "+(string)result.retcode+"\r\n";
   desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
   desc+="Order ticket: "+(string)result.order+"\r\n";
   desc+="Deal ticket: "+(string)result.deal+"\r\n";
   desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
   desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
   desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
   desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
   desc+="Comment: "+result.comment+"\r\n";
//--- return the obtained string 
   return desc;
  }
//+------------------------------------------------------------------+

result:

Request has been sent to set a pending order. Request_ID=25
Request has been sent to set a pending order. Request_ID=26
Request has been sent to set a pending order. Request_ID=27
Request has been sent to set a pending order. Request_ID=28
Request has been sent to set a pending order. Request_ID=29
------------TransactionDescription
TRADE_TRANSACTION_ORDER_ADD
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923054
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_STARTED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

------------TransactionDescription
TRADE_TRANSACTION_ORDER_UPDATE
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923054
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_PLACED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

TRADE_TRANSACTION_REQUEST
------------RequestDescription
TRADE_ACTION_PENDING
Symbol: EURUSD
Magic Number: 1234567
Order ticket: 157923054
Order type: ORDER_TYPE_BUY_STOP
Order filling: ORDER_FILLING_RETURN
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Deviation points: 0
Stop Loss: 0
Take Profit: 0
Stop Limit: 0
Volume: 0.1
Comment: 

------------ResultDescription
Retcode 10009
Request ID: 25
Order ticket: 157923054
Deal ticket: 0
Volume: 0.1
Price: 0
Ask: 0
Bid: 0
Comment: 

 Pending order ticket 157923054

------------TransactionDescription
TRADE_TRANSACTION_ORDER_ADD
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923055
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_STARTED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

------------TransactionDescription
TRADE_TRANSACTION_ORDER_UPDATE
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923055
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_PLACED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

TRADE_TRANSACTION_REQUEST
------------RequestDescription
TRADE_ACTION_PENDING
Symbol: EURUSD
Magic Number: 1234567
Order ticket: 157923055
Order type: ORDER_TYPE_BUY_STOP
Order filling: ORDER_FILLING_RETURN
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Deviation points: 0
Stop Loss: 0
Take Profit: 0
Stop Limit: 0
Volume: 0.1
Comment: 

------------ResultDescription
Retcode 10009
Request ID: 26
Order ticket: 157923055
Deal ticket: 0
Volume: 0.1
Price: 0
Ask: 0
Bid: 0
Comment: 

 Pending order ticket 157923055

------------TransactionDescription
TRADE_TRANSACTION_ORDER_ADD
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923056
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_STARTED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

------------TransactionDescription
TRADE_TRANSACTION_ORDER_UPDATE
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923056
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_PLACED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

------------TransactionDescription
TRADE_TRANSACTION_ORDER_ADD
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923057
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_STARTED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

TRADE_TRANSACTION_REQUEST
------------RequestDescription
TRADE_ACTION_PENDING
Symbol: EURUSD
Magic Number: 1234567
Order ticket: 157923056
Order type: ORDER_TYPE_BUY_STOP
Order filling: ORDER_FILLING_RETURN
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Deviation points: 0
Stop Loss: 0
Take Profit: 0
Stop Limit: 0
Volume: 0.1
Comment: 

------------ResultDescription
Retcode 10009
Request ID: 27
Order ticket: 157923056
Deal ticket: 0
Volume: 0.1
Price: 0
Ask: 0
Bid: 0
Comment: 

 Pending order ticket 157923056

------------TransactionDescription
TRADE_TRANSACTION_ORDER_UPDATE
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923057
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_PLACED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

TRADE_TRANSACTION_REQUEST
------------RequestDescription
TRADE_ACTION_PENDING
Symbol: EURUSD
Magic Number: 1234567
Order ticket: 157923057
Order type: ORDER_TYPE_BUY_STOP
Order filling: ORDER_FILLING_RETURN
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Deviation points: 0
Stop Loss: 0
Take Profit: 0
Stop Limit: 0
Volume: 0.1
Comment: 

------------ResultDescription
Retcode 10009
Request ID: 28
Order ticket: 157923057
Deal ticket: 0
Volume: 0.1
Price: 0
Ask: 0
Bid: 0
Comment: 

 Pending order ticket 157923057

------------TransactionDescription
TRADE_TRANSACTION_ORDER_ADD
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923058
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_STARTED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

------------TransactionDescription
TRADE_TRANSACTION_ORDER_UPDATE
Symbol: EURUSD
Deal ticket: 0
Deal type: DEAL_TYPE_BUY
Order ticket: 157923058
Order type: ORDER_TYPE_BUY_STOP
Order state: ORDER_STATE_PLACED
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Price trigger: 0
Stop Loss: 0
Take Profit: 0
Volume: 0.1
Position: 0
Position by: 0

TRADE_TRANSACTION_REQUEST
------------RequestDescription
TRADE_ACTION_PENDING
Symbol: EURUSD
Magic Number: 1234567
Order ticket: 157923058
Order type: ORDER_TYPE_BUY_STOP
Order filling: ORDER_FILLING_RETURN
Order time type: ORDER_TIME_GTC
Order expiration: 1970.01.01 00:00
Price: 1.15776
Deviation points: 0
Stop Loss: 0
Take Profit: 0
Stop Limit: 0
Volume: 0.1
Comment: 

------------ResultDescription
Retcode 10009
Request ID: 29
Order ticket: 157923058
Deal ticket: 0
Volume: 0.1
Price: 0
Ask: 0
Bid: 0
Comment: 

 Pending order ticket 157923058

ds

Reason: