How to work correctly in MT5 with OrderSend - page 11

 
prostotrader:

Not two, one :)

if(transaction.type == TRADE_TRANSACTION_REQUEST && request.action == TRADE_ACTION_DEAL)

TRADE_TRANSACTION_REQUEST is needed when you use OrderSendAsymc to receive an order ticket.

So what's wrong there? How do you know if I am using OrderSendAsync() specifically?
And I can't use it to check, for example, stamp of the Expert Advisor that sent me a trade request? Or, for example, to check the ticket of the position, from which the last trade was executed?

Finally, I can use this event to check the price at which the transaction was made (although I agree, checking the price in this event only makes sense when using asynchronous trading).

So, if I use asynchronous order sending, is the code correct?

 
Oleg Shenker:

So what is wrong with it? How do you know that maybe I use OrderSendAsync()?
And I cannot use it to check, for example, the stamp of the Expert Advisor who sent a trade request? Or, for example, to check the ticket of the position, from which the last trade was executed?

Finally, I can use this event to check the price at which the transaction was made (although I agree, checking the price in this event only makes sense when using asynchronous trading).

So if I use asynchronous order sending, the code is correct?

The topic is called

"How to work correctly with OrderSend".

This function (as conceived by the developers) should be fully synchronous, i.e. if you send an order and if you get a ticket,

all is OK with the order. But now this function does not work quite correctly, so after receiving a ticket of an order, you

get a confirmation in OnTradeTransaction that everything is OK.

I.e., the data on this order is fully synchronized in the terminal.

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
           switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Данные по ордеру синхронизированы
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }
 
prostotrader:

The topic is called

"How to work correctly with OrderSend".

This function (as conceived by the developers) should be fully synchronous, i.e. if you send an order and if you get a ticket,

all is OK with the order. But now this function does not work quite correctly, so after receiving a ticket of an order, you

get a confirmation in OnTradeTransaction that everything is OK.

That is, the data for this order is fully synchronized in the terminal.

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
           switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Данные по ордеру синхронизированы
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }


Great! I know it. Only I am using asynchronous order sending. I have a different problem, the REQUEST event (meaning finalising the transaction totals) for the same transaction came twice.
 
Oleg Shenker:
Great! I know how it works. Only I am using asynchronous order sending. I have a different problem, the REQUEST event (in the sense of finalising the transaction totals) for the same transaction came twice.

You just don't quite understand how OnTradeTransaction messages should be handled when placing OrderSEndAsync

Record this EA and see how it works

Files:
TestOrders.mq5  25 kb
 
prostotrader:

You just don't quite understand how OnTradeTransaction messages should be handled when placing OrderSEndAsync

Record the Expert Advisor and see how it works

That's what I'm asking you, how TradeTransactions should be handled correctly.

 
Oleg Shenker:

That's what I'm asking you, how TradeTransactions should be handled correctly.

The order for OrderSendAsync is as follows:

When you send an order with the OrderSendAsync command, if the order is sent successfully, you will receive order_id

bool SendOrderAsyncMode()
  {
   double price=SymbolInfoDouble(Symbol(),SYMBOL_SESSION_PRICE_LIMIT_MAX);
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   order_ticket=0;
   order_id=0;
   request.action = TRADE_ACTION_PENDING;
   request.magic  = 9876543210;
   request.symbol = Symbol();
   request.volume = 1;
   request.price  = price;
   request.type=ORDER_TYPE_SELL_LIMIT;
   request.comment="Async mode";
   request.type_filling=ORDER_FILLING_RETURN;
   request.type_time=ORDER_TIME_DAY;
   if(OrderSendAsync(request,result))
     {
      if((result.retcode==TRADE_RETCODE_PLACED) || (result.retcode==TRADE_RETCODE_DONE))
        {
         if(result.request_id>0)
           {
            order_id=result.request_id;
            Print(__FUNCTION__," Order sent in async mode");
            return(true);
           }
         else
           {
            Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
           }
        }
      else
        {
         Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
        }
     }
   else
     {
      Print(__FUNCTION__," Order not sent in async mode.");
     }
   return(false);
  }

Then we get all other data in OnTradeTransactions

1. Receive order ticket

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_REQUEST:
         if((order_id>0) && (order_id==result.request_id))
           {
            order_id=0;
            order_ticket=result.order;
            Print(__FUNCTION__," Order get ticket done. Ticket = ",result.order);
           }
         break;
     }
}

2. If you use market or limit (not pending) orders, i.e. those that are immediately executed

or rejected, it is necessary to monitor TRADE_TRANSACTION_HISTORY_ADD, since in any case 3.

Such orders are added to the history.

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_HISTORY_ADD:
         if(order_ticket==trans.order)
           {
             //Берем данные из истории
           }
         break;
    }
  }


If you use pending orders (can be executed in parts), then you need to monitor

There are three events TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD.

TRADE_TRANSACTION_ORDER_UPDATE - serves to get information that the order has been set (modified)

TRADE_TRANSACTION_DEAL_ADD - getting information that a deal has been executed

TRADE_TRANSACTION_HISTORY_ADD - the order is not present in the trade system; we can view the data on the order

That's all the "wisdom"

Added

OrderSendAsync andOnTradeTransaction interactionworks without problems.

and on forex (real)

 
prostotrader:

Added

OrderSendAsync andOnTradeTransactionwork fine, I checked it on FOREX (demo)

Both on FOREX (real)

Thank you! Now I know how to use OnTradeTransaction() function or there are some other secrets?

How can I do it without any caveats if the TradeTransaction() event can get lost?

 
Oleg Shenker:

Thank you! Now I know how to use OnTradeTransaction() or are there any other secrets?

How can there be no caveats if the TradeTransaction() event can get lost?

There are no more secrets.

It may get lost (but it happened 3-4 times in 4-5 months and in moments of strong market activity),

so insurance would not be a bad thing.

 

And here is a concrete example of an order check

Terminal log:

2017.01.05 11:46:01.673 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.895 Trades  'xxxxx': accepted buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.896 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3 placed for execution in 1223.187 ms

Expert Advisor Log:

2017.01.05 11:46:02.829 trader (PLT-3.17,H1)      CheckOrders: Задержка ответа сервера. Ожидание продолжается...


The order was sent on2017.01.05 11:46:01.673

No reply from server for more than 1 second, order has been checked.

In normal mode the response comes in 7-10 msec.

 

Answering the question"How to work correctly in MT5 with OrderSend"

There is a simple answer.

Until the developers fix the problem, then

ulong pre_ticket; //Предварительный тикет
ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      pre_ticket=result.order;
    }  
  }
//----------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
{
   switch(trans.type)
   {
     case TRADE_TRANSACTION_ORDER_UPDATE:
       if((pre_ticket>0) && (trans.order==pre_ticket))
       {
         switch(trans.order_state)
         {
           case ORDER_STATE_PLACED:
             order_ticket = pre_ticket;
           break;
         }
       }
     break;
   }
}

When they do, then

ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      order_ticket=result.order;
    }  
  }
Reason: