Discussion of article "Orders, Positions, and Deals in MetaTrader 5" - page 4

 

Please tell me, if the OrderSend function returned true and result.order has an order ticket (result.order!=0), does it guarantee that the order is accepted by the broker and it is in the trading tab or at this stage the request is accepted only by the broker's server but not by the exchange?

And the second question, can there be a situation when OrderSend returned true and result.order==0 ?

 
Aleksey Gunin:

Can you please tell me, if the OrderSend function returns true and result.order has an order ticket (result.order!=0), does it guarantee that the order is accepted by the broker and it is in the trading tab or at this stage the request is accepted only by the broker's server but not by the exchange?

Guaranteed.

And the second question, can there be a situation when OrderSend returned true and result.order==0 ?

No.

 
fxsaber:

Guarantees.

No.

Just the other day they added a clarification for the OrderSend function, see the online help.

 
Rashid Umarov:

Just the other day they added a clarification for the OrderSend function, check out the online help.

Does this apply to market orders?

Each accepted order is stored on the trade server waiting to be processed until one of the conditions for its execution occurs:

  • expiration,
  • the occurrence of a counter request,
  • triggering of the order upon receipt of the execution price,
  • receipt of a request to cancel the order.
There is no specification that the Terminal itself always calls OrderCheck before OrderSendAsync, and OrderSend is an add-on over OrderSendAsync

Forum on trading, automated trading systems and testing trading strategies

Typical errors and ways to eliminate them when working with the trading environment

fxsaber, 2018.02.20 12:23 pm.

Conditional scheme of implementation of the standard OrderSend (without timeout)
static MqlTradeResult LastResult = {0};

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult &Result )
{ 
  LastResult = Result;
}

// Conditional algorithm for implementing the standard OrderSend
bool OrderSend( const MqlTradeRequest &Request, MqlTradeResult &Result )
{  
  bool Res = OrderSendAsync(Request, Result);
  
  if (Res)
  {
    while (LastResult.request_id != Result.request_id)
      OnTradeTransaction(); // schematic call
          
    Result = LastResult;    
    Res = (Result.retcode == TRADE_RETCODE_PLACED) ||
          (Result.retcode == TRADE_RETCODE_DONE) ||
          (Result.retcode == TRADE_RETCODE_DONE_PARTIAL);

    LastResult.request_id = 0;
  }
    
  return(Res);
}


From this scheme we can clearly see that when placing a market order via OrderSendAsync on the same MetaQuotes-Demo, it is impossible to guarantee catch the event of placing the corresponding order until the order is executed or rejected. That is, MT5 does not have any simple mechanisms for evaluating the intermediate results of its OrderSendAsync.


OrderSend is executed until Result.request_id is equal to the same value of OrderSendAsync in OnTradeTransaction. Or it is terminated by timeout. Therefore, the result of OrderSend depends only on the type of message in OnTradeTransaction with the corresponding request_id.

It would be useful to hear about the formation of the request_id itself. If I understand correctly, it is a counter of orders sent to the trade server from the moment of launching/connecting the Terminal/Account. The Terminal itself analyses incoming messages from the trade server and either assigns the required request_id to only one (which is doubtful), or resets the request_id to a certain message (most likely). This behaviour made it possible some time ago to get the Bidding History to match the OrderSend output. But because only one message in OnTradeTransaction is visible with the right request_id, the unpleasant situation in asynchronous mode in the quote above occurs.

 

Good afternoon, I found inconsistencies for MqlTradeResult.deal and MqlTradeResult.order

1) Description (MQL5 Reference Manual)


2) Real-time trading

I place market orders (TRADE_ACTION_DEAL). I output MqlTradeResult values using the Print function:


and the deal appears in the log:

I tried to "fall asleep" with the function Sleep for a couple of seconds and output the data again (when the deal is already exactly made and the position is open), the number of the deal did not appear.


3) Strategy Tester

All fields are filled in here:



What causes such differences?

 
Konstantin Kulikov:

Good afternoon, found inconsistencies for MqlTradeResult.deal and MqlTradeResult.order




https://www.mql5.com/en/docs/trading/ordersend

When sending a market order (MqlTradeRequest.action=TRADE_ACTION_DEAL), the successful result of the OrderSend() function does not mean that the order was executed (the corresponding trades were executed): true in this case means only that the order was successfully placed in the trading system for further execution. The trade server can fill in the values of deal or order fields in the returned result structure , if these data will be known to it at the moment of forming the response to the OrderSend() call. In general, the event or events of execution of deals corresponding to the order may occur after the response to the OrderSend() call is sent. Therefore, for any type of trade request, when receiving the result of OrderSend() execution, it is necessary to check first of all the return code of the trade server retcode and the response code of the external trading system retcode_external (if necessary), which are available in the returned result structure.


Документация по MQL5: Торговые функции / OrderSend
Документация по MQL5: Торговые функции / OrderSend
  • www.mql5.com
Торговый запрос проходит несколько стадий проверок на торговом сервере. В первую очередь проверяется корректность заполнения всех необходимых полей параметра , и при отсутствии ошибок сервер принимает ордер для дальнейшей обработки. При успешном принятии ордера торговым сервером функция OrderSend() возвращает значение true. Рекомендуется...
 

Thanks for such an informative article. @MetaQuotes

Query: How can I collectively loop through both : open orders and open positions in a single for() loop (in a similar way how we loop all orders in MQL4 and then check if an order is already executed or a pending order) ?

 
Rahul Dhangar :

Thanks for such an informative article. @MetaQuotes

Query: How can I collectively loop through both : open orders and open positions in a single for() loop (in a similar way how we loop all orders in MQL4 and then check if an order is already executed or a pending order) ?

To calculate POSITIONS and PENDING ORDERS you must use two independent cycles. One cycle enumerates POSITIONS, and the second cycle enumerates PENDED ORDERS. Example: Calculate Positions and Pendong Orders

How to start with MQL5
How to start with MQL5
  • 2020.12.19
  • www.mql5.com
This thread discusses MQL5 code examples. There will be examples of how to get data from indicators, how to program advisors...
 

I know you're not really one to worry about those starting out in the mql5 language, given the strong community you have, despite many criticisms, here's one more:

The translation and the very wording of the text hinders understanding...I sweated, I had to go far to find out who should come first, since the documentation itself contradicts itself, in the text:

  • Order history

    To get information about an order from the history, you first need to create the order history cache using one of three functions: HistorySelect(start, end), HistorySelectByPosition() or HistoryOrderSelect(ticket). If the execution is successful, the cache will store the number of orders, returned by theHistoryOrdersTotal() function. Access to the properties of these orders is carried out by each of the elements in the ticket, using the appropriate function:

    1. HistoryOrderGetDouble(ticket_order, type_property)
    2. HistoryOrderGetInteger(ticket_order, type_property)
    3. HistoryOrderGetString(ticket_order, type_property)


In contrast to: https: //www.mql5.com/pt/docs/trading/historyorderstotal transcribed below.



HistoryOrdersTotal

Returns the number of orders in the history. Before calling HistoryOrdersTotal(), you must first receive the history of trades and orders using theHistorySelect() function or theHistorySelectByPosition() function.

int HistoryOrdersTotal();

Return Value

Value of typedouble.

Note

Do not confuse orders from a trade history withpending orders that appear in the "Trade" tab of the Toolbox bar. The list oforders that have been cancelled or led to a transaction can be seen in the "History" tab of the client terminal's toolbox.

Also see


The first passage contradicts itself, it doesn't need any help, but the second comes along and finishes complicating things....: after all, who comes first, HistoryOrdersTotal or one of the three functions HistorySelect (start, end) HistorySelectByPosition() or HistoryOrderSelect(ticket), or even HistorySelectByPosition(), mentioned in the second text.

That was difficult, it could have been easier... but I think the first thing that comes to mind is one of the three HistorySelect(start, end) HistorySelectByPosition () or HistoryOrderSelect(ticket), or even HistorySelectByPosition(), mentioned in the second text...

Documentação sobre MQL5: Funções de Negociação / HistoryOrdersTotal
Documentação sobre MQL5: Funções de Negociação / HistoryOrdersTotal
  • www.mql5.com
HistoryOrdersTotal - Funções de Negociação - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 

Good afternoon,
question to the developers: can you give me an approximate information, how much memory the history cache takes? approximately kbytes for one deal and one order.

I ran the script in a terminal with a small history and got this result:

void OnStart()
  {
   Print("TerminalInfoInteger(TERMINAL_MEMORY_USED) = ", TerminalInfoInteger(TERMINAL_MEMORY_USED));
   if(HistorySelect(0, INT_MAX))
     {
      Print("TerminalInfoInteger(TERMINAL_MEMORY_USED) = ", TerminalInfoInteger(TERMINAL_MEMORY_USED));
      Print("HistoryDealsTotal  = ", HistoryDealsTotal());
      Print("HistoryOrdersTotal = ", HistoryOrdersTotal());
     }
  }

2021.05.14 14:46:41.265	TestCashSize (Si-6.21,H1)	TerminalInfoInteger(TERMINAL_MEMORY_USED) = 488
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	TerminalInfoInteger(TERMINAL_MEMORY_USED) = 489
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	HistoryDealsTotal  = 1928
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	HistoryOrdersTotal = 1116

This means that with a history of a couple of million trades and a million orders, the cache will take about a gigabyte?

And so for each mql programme?