In the meantime, I found this thread: https://www.mql5.com/en/forum/357245#comment_19607440
Apparently OrderSend() is just as asynchronously as OrderSendASync(). When OrderSend() returns, the internal bookkeeping in MT5 can still be lagging and not updated yet. You need to implement OnTrade() or OnTradeTransaction() handlers to be sure. That is quite unusual for a blocking "synchronous" call. In other words: you might as well use OrderSendASync() because you are forced to implement a handler anyway.
I am disappointed in this architecture. This does not make sense.
Even worse: the Strategy Tester and demo accounts do not show this behaviour, so to properly test my implementation I need to do trades on an actual live account. @MetaQuotes: please emulate this behaviour in your Strategy Tester and on demo accounts so programmers can better test their code. It is not nice to discover this after months of successful demo trading.

- 2020.12.05
- www.mql5.com
In the meantime, I found this thread: https://www.mql5.com/en/forum/357245#comment_19607440
Apparently OrderSend() is just as asynchronously as OrderSendASync(). When OrderSend() returns, the internal bookkeeping in MT5 can still be lagging and not updated yet. You need to implement OnTrade() or OnTradeTransaction() handlers to be sure. That is quite unusual for a blocking "synchronous" call. In other words: you might as well use OrderSendASync() because you are forced to implement a handler anyway.
I am disappointed in this architecture. This does not make sense.
Even worse: the Strategy Tester and demo accounts do not show this behaviour, so to properly test my implementation I need to do trades on an actual live account. @MetaQuotes: please emulate this behaviour in your Strategy Tester and on demo accounts so programmers can better test their code. It is not nice to discover this after months of successful demo trading.
I understand your feeling but they will not change anything obviously, it's know behaviour since 2014 at least (and fortunately as it would break a lot of existing code).
It may happen on demo account too, I have seen it, though it's rare as they are is no real order processing in this case.
May I ask why you need to know price just after OrderSend() returned ?
Yes, but it would be helpful if the strategy tester and demo account showed the same behaviour to enable coders to make sure their code is robust.
My EA keeps a detailed transaction log showing recent ticks, the full MqlTradeRequest structure, the exact time the request was send, the full MqlTradeResult, the exact latency/duration of the round-trip to the server, the ping time, and also the slippage we got from the broker. For that last one, I obviously need to know the open price.
Having such detailed logging has helped me to keep brokers honest and in one case made it clear the broker was cheating. I had all the evidence to show.
Inspired by the great MT4Orders library of @fxsaber (https://www.mql5.com/ru/code/16006), I now implemented a busy-wait loop that actively polls the HistoryDeals until the corresponding deal appears. When the market opens on Monday I will give it a try to see how long MT5 needs before it updates its internal state after OrderSend() returned. Hopefully this is fast enough. I have added a time-out of 5 seconds just in case, but expect it to be milliseconds, not seconds.

Yes, but it would be helpful if the strategy tester and demo account showed the same behaviour to enable coders to make sure their code is robust.
My EA keeps a detailed transaction log showing recent ticks, the full MqlTradeRequest structure, the exact time the request was send, the full MqlTradeResult, the exact latency/duration of the round-trip to the server, the ping time, and also the slippage we got from the broker. For that last one, I obviously need to know the open price.
Having such detailed logging has helped me to keep brokers honest and in one case made it clear the broker was cheating. I had all the evidence to show.
Inspired by the great MT4Orders library of @fxsaber (https://www.mql5.com/ru/code/16006), I now implemented a busy-wait loop that actively polls the HistoryDeals until the corresponding deal appears. When the market opens on Monday I will give it a try to see how long MT5 needs before it updates its internal state after OrderSend() returned. Hopefully this is fast enough. I have added a time-out of 5 seconds just in case, but expect it to be milliseconds, not seconds.
I really don't get why you need to use a timer or a loop when you have events at your disposal. Anyway...
I really don't get why you need to use a timer or a loop when you have events at your disposal. Anyway...
Because I want to log more than just the open price/slippage, and I want my logs to be in chronological order.
Using events would either require me to log bits and pieces in multiple messages all referring to the same transaction. As a human reading back the log, I need to try to collect all info at different places.
The alternative is to store the transaction details in a data structure, and log all in one message once the event comes in. But then the log messages are no longer in chronological order. The EA might have logged why it decided to make a trade, logged some values of internal state, made the trade, logged some results, etc. And then several messages later the transaction details will be logged delayed.
To properly do this, I would need to create a log mechanism that sorts messages and only writes to disk with a delay, but that is much to complex for what it is: simply a text file with messages.
how long MT5 needs before it updates its internal state after OrderSend() returned. Hopefully this is fast enough.н
Typically, this is a few milliseconds. It rarely exceeds a second, but it happens.
A full OrderSend-function response is important for this as well. It also makes writing code much easier.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
My EA opens positions at market price using OrderSend(). In the Strategy Tester, and on demo, when the call returns "10009 Request Completed", the MqlTradeResult.price field holds the price at which the position was opened, and the MqlTradeResult.deal field holds the corresponding deal ID.
However, on a live account, the MqlTradeResult.price and MqlTradeResult.deal fields can be zero. I am using the blocking OrderSend() call, not the asynchronous OrderSendASync() call, so I expected the MqlTradeResult structure to be filled upon return.
Can I not rely on this? If so, how long do I need to wait before calling PositionGetDouble(POSITION_PRICE_OPEN) gives me the correct non-zero value?
Example logging below: