MT5 EURUSD: SymbolInfoTick() and CopyTicksRange() return different Bid/Ask prices at identical millisecond timestamps

Dear Members,

I am investigating a reproducible tick-data discrepancy in MetaTrader 5 using read-only native MQL5 and Python tests.

Environment

  • Broker server: FOREX.comGlobal-Demo 531

  • Account type: Demo

  • Symbol: EURUSD

  • Test date: November 9, 2026

  • Platform: MetaTrader 5 for Windows

  • Native methods: SymbolInfoTick() and CopyTicksRange()

  • Python methods: symbol_info_tick(), copy_ticks_range(), copy_ticks_from()

Observed discrepancy

For the same recorded tick timestamp:

time_msc = 1794248101878

flags = 1030

Field SymbolInfoTick() CopyTicksRange()
Bid 1.12025 1.12023
Ask 1.12040 1.12042
Spread 1.5 pips 1.9 pips

The historical Bid is consistently 0.00002 lower, and the historical Ask is 0.00002 higher than the live quote. The midpoint is unchanged.

The native latest quote was sampled before and after retrieving historical ticks, and its timestamp and prices remained unchanged.

This discrepancy appeared in 10/10 native observations across eight distinct timestamps.

A separate native MQL5 versus Python comparison established that historical tick records agreed across both interfaces in all 10 sampled windows, covering four distinct native tick timestamps. The live-versus-history difference persisted.

Questions

  1. Is this difference expected behavior in MT5, or does it indicate broker-side pricing transformation, terminal-side processing, or tick-history synchronization behavior?

  2. Under what conditions can SymbolInfoTick() and CopyTicksRange() return different Bid/Ask prices for the exact same time_msc and flags?

  3. How should a developer identify which price representation is appropriate for historical trading-cost research? Is there a documented way to distinguish the original quote stream from any transformed representation?

  4. What are the precise timestamp semantics for MqlTick.time_msc and Python historical tick timestamps? The broker stated its server uses GMT+2, while the Python documentation describes UTC timestamps. How should this distinction be interpreted, including historical DST transitions?

  5. Is there an official method to diagnose whether tick-history prices have been modified or normalized?

No orders were placed. All tests were performed using bounded read-only operations.

I can provide the native MQL5 source, raw tick comparisons, Python verification output and original evidence files.

I would appreciate a technical explanation or a reference to the relevant official documentation.

Thank you.

patel4x:
What are the precise timestamp semantics for MqlTick.time_msc and Python historical tick timestamps? The broker stated its server uses GMT+2, while the Python documentation describes UTC timestamps. How should this distinction be interpreted, including historical DST transitions?

The mql5.com Python documentation is erroneous. The timestamp of the broker-dealer's data is always returned.

patel4x:
A separate native MQL5 versus Python comparison established that historical tick records agreed across both interfaces in all 10 sampled windows, covering four distinct native tick timestamps. The live-versus-history difference persisted.

In my experience, the ticks arriving in OnTick() don't necessarily include every single real-time tick. When ticks arrive faster than code can be executed, only the most recent tick is returned. Presumably, SymbolInfoTick() operates in the same way regarding live ticks (the former is documented but not the latter).

midpoint is identical and its exactly +/-0.2 pip on both sides, so this isnt the terminal doing anything. that pattern is almost
  always the broker side spread setting. on MT5 the server can apply spread markup per account group, and the live quote and the stored
  tick history dont have to go through the same path. why their history is the wider one, only FOREX.com can tell you, worth asking
  their support with that exact time_msc

  for trading cost research i wouldnt trust either stream. put small trades on the same account type you plan to use and take the
  actual fill prices from the deal history, thats the spread you really pay

  on timestamps, everything MT5 returns is broker server time, python included. it just looks like UTC because its stored as epoch
  seconds. so with GMT+2/+3 you have to handle DST yourself, MT5 wont do it for you

One point worth checking in the DOM comparison: MarketBookGet() requires a prior MarketBookAdd() subscription, and best Bid/Ask should be selected by book entry type rather than assuming the first and last array elements.

I'd also log all historical ticks matching each time_msc before comparing prices. The symmetric spread difference suggests a pricing transformation, but doesn't establish whether it occurred at the broker or terminal level.

MT5 EURUSD: SymbolInfoTick() and CopyTicksRange() return different Bid/Ask prices at identical millisecond timestamps
MT5 EURUSD: SymbolInfoTick() and CopyTicksRange() return different Bid/Ask prices at identical millisecond timestamps
  • 2026.11.09
  • www.mql5.com
Dear Members, I am investigating a reproducible tick-data discrepancy in MetaTrader 5 using read-only native MQL5 and Python tests...

Again a topic without any real information. How were these data collected ?

No code, no logs.

Are AI agents thinking we will "believe" them as is ?!