Weird mismatch using SymbolInfoTick and CopyTicksRange

 

Hello, I have been using CopyTicksRange to get a range of ticks to then construct 1-minute OHLC data from the raw ticks, later i tried looking through my broker and execute some testing trades and i found that CopyTicksRange returns ticks that are different from using SymbolInfoTick. To test this i wrote this simple MQL5 Code and the results were as follow 

API Bid Ask Spread
SymbolInfoTick 1.14435 1.14444 9 points
CopyTicks 1.14439 1.14440 1 point
CopyTicksRange 1.14439 1.14440 1 point

I wonder why this happens and how to counter this? 
void OnTick()
{
   MqlTick live;
   MqlTick latest[];
   MqlTick range[];

   if(!SymbolInfoTick(_Symbol, live))
   {
      Print("SymbolInfoTick failed");
      return;
   }

   int n1 = CopyTicks(_Symbol, latest, COPY_TICKS_ALL, 0, 1);
   int n2 = CopyTicksRange(
      _Symbol,
      range,
      COPY_TICKS_ALL,
      live.time_msc,
      live.time_msc + 1
   );

   Print("====================================================");

   PrintFormat(
      "SymbolInfoTick\n"
      " time_msc=%I64u\n"
      " time=%s\n"
      " bid=%.10f\n"
      " ask=%.10f\n"
      " last=%.10f\n"
      " volume=%I64u\n"
      " flags=%u\n"
      " spread=%d points",
      live.time_msc,
      TimeToString((datetime)live.time, TIME_DATE|TIME_SECONDS),
      live.bid,
      live.ask,
      live.last,
      live.volume,
      live.flags,
      (int)MathRound((live.ask-live.bid)/_Point)
   );

   if(n1 > 0)
   {
      PrintFormat(
         "CopyTicks\n"
         " time_msc=%I64u\n"
         " time=%s\n"
         " bid=%.10f\n"
         " ask=%.10f\n"
         " last=%.10f\n"
         " volume=%I64u\n"
         " flags=%u\n"
         " spread=%d points",
         latest[0].time_msc,
         TimeToString((datetime)latest[0].time, TIME_DATE|TIME_SECONDS),
         latest[0].bid,
         latest[0].ask,
         latest[0].last,
         latest[0].volume,
         latest[0].flags,
         (int)MathRound((latest[0].ask-latest[0].bid)/_Point)
      );
   }
   else
   {
      Print("CopyTicks returned ", n1);
   }

   if(n2 > 0)
   {
      PrintFormat(
         "CopyTicksRange\n"
         " time_msc=%I64u\n"
         " time=%s\n"
         " bid=%.10f\n"
         " ask=%.10f\n"
         " last=%.10f\n"
         " volume=%I64u\n"
         " flags=%u\n"
         " spread=%d points",
         range[0].time_msc,
         TimeToString((datetime)range[0].time, TIME_DATE|TIME_SECONDS),
         range[0].bid,
         range[0].ask,
         range[0].last,
         range[0].volume,
         range[0].flags,
         (int)MathRound((range[0].ask-range[0].bid)/_Point)
      );
   }
   else
   {
      Print("CopyTicksRange returned ", n2);
   }

   Print("====================================================");
}
Documentation on MQL5: CopyTicksRange / Matrix and Vector Methods
Documentation on MQL5: CopyTicksRange / Matrix and Vector Methods
  • www.mql5.com
Get ticks from an MqlTick structure into a matrix or a vector within the specified date range. Elements are counted from the past to the present...
 

Please, read the docs:

Indexing goes from the past to the present meaning that a tick with the index 0 is the oldest one in the array.

To get the latest tick you need latest[n - 1].

Documentation on MQL5: CopyTicksRange / Matrix and Vector Methods
Documentation on MQL5: CopyTicksRange / Matrix and Vector Methods
  • www.mql5.com
Get ticks from an MqlTick structure into a matrix or a vector within the specified date range. Elements are counted from the past to the present...
 
Stanislav Korotky #:

Please, read the docs:

To get the latest tick you need latest[n - 1].

If you looked closely, you would find that I'm only expecting 1 index as a return so using latest[n - 1] yielded the same behavior I was talking about.  
 
Ahmed Gamal #:
If you looked closely, you would find that I'm only expecting 1 index as a return so using latest[n - 1] yielded the same behavior I was talking about.  

You did not post exact log which you got after running this script, this is why I'm not sure it works as you said. For example, CopyTicksRange for 1 ms may return many ticks. To see timing could be also important.

 
Stanislav Korotky #:

You did not post exact log which you got after running this script, this is why I'm not sure it works as you said. For example, CopyTicksRange for 1 ms may return many ticks. To see timing could be also important.

no problem, here is the log and as you can see for the same timestamp i get different results, i found this using various brokers but, especially with my current broker. this destroys any attempt to backtest using ticks retrieved using CopyTicksRange
2026.07.20 18:17:09.061 Testing (EURUSD,H1)     ====================================================
2026.07.20 18:17:09.062 Testing (EURUSD,H1)     SymbolInfoTick
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      time_msc=1784571428897
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      time=2026.07.20 18:17:08
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      bid=1.1406600000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      ask=1.1407500000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      spread=9 points
2026.07.20 18:17:09.062 Testing (EURUSD,H1)     CopyTicks
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      time_msc=1784571428897
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      time=2026.07.20 18:17:08
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      bid=1.1407100000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      ask=1.1407100000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.062 Testing (EURUSD,H1)     CopyTicksRange
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      time_msc=1784571428897
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      time=2026.07.20 18:17:08
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      bid=1.1407100000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      ask=1.1407100000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.062 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.062 Testing (EURUSD,H1)     ====================================================
2026.07.20 18:17:09.338 Testing (EURUSD,H1)     ====================================================
2026.07.20 18:17:09.338 Testing (EURUSD,H1)     SymbolInfoTick
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      time_msc=1784571429400
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      bid=1.1406500000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      ask=1.1407400000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      spread=9 points
2026.07.20 18:17:09.338 Testing (EURUSD,H1)     CopyTicks
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      time_msc=1784571429400
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      bid=1.1407000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      ask=1.1407000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.338 Testing (EURUSD,H1)     CopyTicksRange
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      time_msc=1784571429400
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      bid=1.1407000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      ask=1.1407000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.338 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.338 Testing (EURUSD,H1)     ====================================================
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     ====================================================
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     SymbolInfoTick
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time_msc=1784571429525
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      bid=1.1406400000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      ask=1.1407300000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      spread=9 points
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     CopyTicks
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time_msc=1784571429525
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      bid=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      ask=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     CopyTicksRange
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time_msc=1784571429525
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      bid=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      ask=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     ====================================================
 

OnTick() can be triggered after a batch of ticks. In such case, you can have different values.

All is normal.

 
Alain Verleyen #:

OnTick() can be triggered after a batch of ticks. In such case, you can have different values.

All is normal.

What made me write this simple script in the first place is to investigate after I have used the python API using CopyTicksRange gave me near results where the spread and ticks are not consistent alongside the same call using SymbolInfoTick from also the python API. it's like the saved data retrieved from CopyTicksRange comes from a different feed. 
 
Ahmed Gamal #:
What made me write this simple script in the first place is to investigate after I have used the python API using CopyTicksRange gave me near results where the spread and ticks are not consistent alongside the same call using SymbolInfoTick from also the python API. it's like the saved data retrieved from CopyTicksRange comes from a different feed. 

Ticks can come fast (several in same milliseconds). OnTick is not necessary called for each of them individually.

So within OnTick(), if you check like you did (SymbolInfoTick versus index 0 of CopyTicks/Range) you can have different ticks. Get and check ALL the ticks, not 1 (count), or 1 ms. 

Also you should check according to your last check (OnTick) as using SymbolInfoTick timemsc as reference will not necessarily give you the first tick in the batch.

Using Python API should not change this behaviour.

 
Alain Verleyen #:

Ticks can come fast (several in same milliseconds). OnTick is not necessary called for each of them individually.

So within OnTick(), if you check like you did (SymbolInfoTick versus index 0 of CopyTicks/Range) you can have different ticks. Get and check ALL the ticks, not 1 (count), or 1 ms. 

Also you should check according to your last check (OnTick) as using SymbolInfoTick timemsc as reference will not necessarily give you the first tick in the batch.

Using Python API should not change this behaviour.

The msc timestamp matched tick should be the same. That is :


2026.07.20 18:17:09.444 Testing (EURUSD,H1)     SymbolInfoTick
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time_msc=1784571429525
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      bid=1.1406400000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      ask=1.1407300000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      spread=9 points
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     CopyTicks
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time_msc=1784571429525
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      bid=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      ask=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      spread=0 points
2026.07.20 18:17:09.444 Testing (EURUSD,H1)     CopyTicksRange
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time_msc=1784571429525
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      time=2026.07.20 18:17:09
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      bid=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      ask=1.1406900000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      last=0.0000000000
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      volume=0
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      flags=6
2026.07.20 18:17:09.444 Testing (EURUSD,H1)      spread=0 points

Should all have the same properties. 

Ahmed Gamal #:
it's like the saved data retrieved from CopyTicksRange comes from a different feed. 

It is a known phenomona. See https://www.mql5.com/ru/forum/233647/page3#comment_15601676 check if the fix there solves yours. However it is better to go with a professional broker that does not have this account type fiasco going on.

Библиотеки: HistoryTicks
Библиотеки: HistoryTicks
  • 2020.01.09
  • www.mql5.com
HistoryTicks: Автор: fxsaber...
 
Enrique Dangeroux #:

The msc timestamp matched tick should be the same. That is :


Should all have the same properties. 

No if they are not the same tick.