You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
To create a comprehensive test case, I’d need to understand the practical scenario – are we only trading on ticks where the timing matches to the nearest millisecond?
No. The aim is always to ensure that the environment is up to date for all symbols. In my example, the validity condition is always met in OnTimer. Opening a position is merely for demonstration purposes.
Right.
It is not yet clear where the implementation in the OnTickMulti event ‘loses’ a tick, or in other words, how it is that SymbolInfoTick returns prices other than those expected (I previously suggested that there is likely a delay due to the dispatching of custom events from the indicator) — I would test it without the spy indicator to keep the experiment clean — simply using SymbolInfoTick/CopyTicks on all symbols from the standard OnTick event, at least for the same timestamp.
As for OnTimer, I have some questions about it (please correct me if I’m wrong):
We have no guarantee that the handler will execute in less than a millisecond, so simply incrementing the counter does not guarantee that the original synchronisation will be maintained; in other words, the synchronisation with the server time really needs to be done on the fly every time (after opening a position or performing other calculations more complex than an increment, if any). In other words, the refined approach outlined above won’t work when a large number of positions need to be opened.
Furthermore, even the initial synchronisation (counter initialisation) isn’t 100% foolproof, in my humble opinion.
Let’s say that in the tester, the server time really does start without milliseconds, but how will such code work online? And why are we adding 1 millisecond? I’d still get the server time from the ticks.
This isn’t nitpicking, just some doubts about whether the ‘validity condition’ will always be met.
Simply incrementing the counter does not guarantee that the original synchronisation will be maintained
It’s guaranteed in the Tester.
But how will this code work online?
There’s no such problem online, as all data received by the terminal is indicative: it’s out of date due to lags.
And why are we adding 1 millisecond?
Because the very first OnTimer will be triggered after a specified interval, not immediately.
It is not yet clear where the implementation in the OnTickMulti event ‘loses’ a tick; or, to put it another way, how it is that SymbolInfoTick returns prices that are not as expected
OnTickMulti is definitely not to blame, as the standard SymbolInfoTick function returns the correct tick for one of the symbols, but not for the others.
The reason lies solely in the sequence in which the ticks are delivered.
Forum on trading, automated trading systems and the testing of trading strategies
Libraries: OnTickMulti
fxsaber, 30 September 2025 09:24
Ticks with the same timestamp do not arrive simultaneously. They arrive sequentially. And if a EURUSD tick with a higher timestamp arrives first, then at that moment nothing is known about the GBPUSD tick with the same timestamp, which will arrive second. Therefore, when the first EURUSD tick arrives, the second GBPUSD tick simply does not exist; instead, the data from the previous GBPUSD tick is available.Because the very first OnTimer will be triggered after a specified interval, rather than immediately.
I’ve come up with a quick way to update all the data.
This mechanism allows you to work exclusively with up-to-date data, even in normal mode (single-currency mode without OnTickMulti). For example, for EURUSD there may be several ticks with the same time stamp. Refreshing the data allows you to work with the most recent tick – the last one in that sequence.
P.S. This is yet another reason to create custom symbols – to log only the latest tick from sequences with identical timestamps. In this case, the update will always be maintained in single-currency mode.
But the opening prices are the same, even though the opening times are the same for all symbols.
And because of this behaviour, it is impossible to test a number of systems properly.
I’ve refreshed my memory on the tester’s opening price mode. The key point is that, despite the name, the tester generates 4 OHLC ticks in this mode, rather than 1 as one might intuitively expect from the name. Of these four reference points, only the first ‘O’ is used for expert advisors to trigger OnTick, whilst for indicators, OnCalculate is additionally triggered three times for HLC or LHC (depending on the direction of the bar) with ticks for the corresponding prices. The timings for these three additional points are artificially set to the last three seconds of the bar. It follows that the spy indicator sends several events for each symbol instead of just one. This is probably something to bear in mind for those using the opening price mode.
I have also observed an artefact (after adding debugging to my own similar spy indicator from the book) whereby the tick event for an additional symbol from the previous bar is, for some reason, repeated on the new bar; only for the spy’s OnCalculate method to be called afterwards, at which point an event for a new tick of the additional symbol with the updated price is received. As a result, to have the current price for additional symbols, you need to include a timestamp in the events themselves and avoid reprocessing events that have already been processed. I do this in my own code when sending data as follows:
And when receiving data (the example shown is for a single additional symbol; for multiple symbols, you’ll need a `timestamp[]` array!):
It should be noted that if there are ticks with identical millisecond values, the first of these is executed, not the last.
The simplest way to synchronise