What is a synchronized series?

 

https://www.mql5.com/en/docs/constants/tradingconstants/enum_series_info_integer

Identifier Description
Type
SERIES_SYNCHRONIZED Symbol/period data synchronization flag for the current moment bool

I'm trying to understand what exactly the value returned by the SeriesInfoInteger() function means when called with prop_id = SERIES_SYNCHRONIZED.

Synchronization here likely refers to the synchronization of the terminal's symbol history with the data on the trading server. The following quote may indirectly support this assumption:

Synchronization of the Terminal Data and Server Data

Since a mql5 program can call data from any symbol and timeframe, there is a possibility that data of a necessary timeseries are not formed yet in the terminal or the necessary price data aren't synchronized with the trade server. In this case it's hard to predict the latency time.

But what exact data does SERIES_SYNCHRONIZED refer to?

I requested data from a different timeframe for the test. As you can see in the code below, I attempted to copy just the current bar. I knew the terminal wouldn't be able to provide even that one current bar on the first try, because that timeframe's chart hadn't been used for a long time.

#property indicator_plots 0

int OnInit() { return(INIT_SUCCEEDED); }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   static bool flag = false;
   if(flag)
      return rates_total;
   flag = true;
   //---
   test(PERIOD_H6);
   //---
   return rates_total;
  }

#define _boolToStr(a) ((a) ? "true" : "false")
void test(ENUM_TIMEFRAMES a_tf)
  {
   const bool syncBefore = SeriesInfoInteger(Symbol(), a_tf, SERIES_SYNCHRONIZED);
   MqlRates rates[1];
   ResetLastError();
   CopyRates(Symbol(), a_tf, 0, 1, rates);
   const int copyRatesError = _LastError;
   const bool syncAfter = SeriesInfoInteger(Symbol(), a_tf, SERIES_SYNCHRONIZED);
   PrintFormat("current bar %s, syncBefore %s, copyRatesError %i, syncAfter %s", TimeToString(rates[0].time),
               _boolToStr(syncBefore), copyRatesError, _boolToStr(syncAfter));
  }

The test showed that SERIES_SYNCHRONIZED returns true even though the data for the current bar is missing. This raises the suspicion that SERIES_SYNCHRONIZED indicates synchronization of HCC data, not the data of a specific timeseries.

  • If SERIES_SYNCHRONIZED is about HCC data, then why is it returned by SeriesInfoInteger(), which accepts a timeframe as one of its arguments? Why does the documentation describe SERIES_SYNCHRONIZED as a "Symbol/period data synchronization flag" instead of simply a "Symbol data synchronization flag"?
  • If each timeseries (i.e., chart of each timeframe) has its own independent SERIES_SYNCHRONIZED, then why does it return true for a timeseries that doesn't even have the current bar available?

Main question: What specific data does SERIES_SYNCHRONIZED actually refer to?

Additional question: How does SERIES_SYNCHRONIZED differ from SymbolIsSynchronized()?

 

Here’s an interesting statement from a MetaQuotes employee (machine-translated):

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Slava, 2021.05.29 18:16

...

3. It’s pointless to ask whether your symbol is synchronized from OnTick or OnCalculate. Of course it is!

...

I’m not entirely sure whether he was referring to SERIES_SYNCHRONIZED. And unfortunately, he didn’t explain why the current chart’s symbol is guaranteed to be synchronized for EAs and indicators 😁

And here’s a quote from AlgoBook, where the author does exactly what Slava called pointless (unless I’m mistaken — which is entirely possible):

https://www.mql5.com/en/book/applications/indicators_make/indicators_multisymbol

At the very beginning, we check if the timeseries of the current symbol and the current timeframe is requested from an indicator-type MQL program. Such requests are prohibited, since the "native" timeseries on which the indicator is running is already being built by the terminal or is ready: requesting it again may lead to looping or blocking. Therefore, we simply return the synchronization flag (SERIES_SYNCHRONIZED) and, if it is not yet ready, the indicator should check the data later (on the next ticks, by timer, or something else).

bool QuoteRefresh(const string asset, const ENUM_TIMEFRAMES period, const datetime start)
{
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE) == PROGRAM_INDICATOR && _Symbol == asset && _Period == period)
   {
      return (bool)SeriesInfoInteger(asset, period, SERIES_SYNCHRONIZED);
   }
   ...
 

Forum on trading, automated trading systems and testing trading strategies

About SERIES_SYNCHRONIZED

attila.okcu, 2016.11.18 11:05

I've got the following reply from the service desk: "Actually, the SERIES_SYNCHRONIZED flag means that the local price history is synchronized with the server. It is not related to timeseries."

And, the service desk also said that the example code in the documentation will be checked and fixed if necessary.

As a reminder, the data on the server are M1 data ONLY.

EDIT: After some investigations, the above quote is dubious. Here is an other one :

Forum on trading, automated trading systems and testing of trading strategies

SeriesInfoInteger(_Symbol,_Period,SERIES_SYNCHRONIZED)) and SymbolIsSynchronized(_Symbol)

Slava , 2017.04.05 08:22

Money for fish again.

Have you read the material?

SymbolIsSynchronized (_Symbol) is applied to the symbol in general, regardless of the timeframe (do you see the timeframe among the parameters of this function?), i.e. to the intermediate data

SeriesInfoInteger(_Symbol,_Period,SERIES_SYNCHRONIZED)) is applied to a timeseries. That is, to a period symbol. This function has a timeframe parameter.


 
Vladislav Boyko:

I'm trying to understand what exactly the value returned by the SeriesInfoInteger() function means when called with prop_id = SERIES_SYNCHRONIZED.

Synchronization here likely refers to the synchronization of the terminal's symbol history with the data on the trading server. The following quote may indirectly support this assumption:

But what exact data does SERIES_SYNCHRONIZED refer to?

I requested data from a different timeframe for the test. As you can see in the code below, I attempted to copy just the current bar. I knew the terminal wouldn't be able to provide even that one current bar on the first try, because that timeframe's chart hadn't been used for a long time.

The test showed that SERIES_SYNCHRONIZED returns true even though the data for the current bar is missing. This raises the suspicion that SERIES_SYNCHRONIZED indicates synchronization of HCC data, not the data of a specific timeseries.

Exactly. It's HCC (M1) data.

  • If SERIES_SYNCHRONIZED is about HCC data, then why is it returned by SeriesInfoInteger(), which accepts a timeframe as one of its arguments? Why does the documentation describe SERIES_SYNCHRONIZED as a "Symbol/period data synchronization flag" instead of simply a "Symbol data synchronization flag"?

Why not ? 😁 I suppose it was not yet clear for them when they build the MQL API (MQL development is from 2009 !!!).

The API is SeriesInfoInteger() which requires a tf parameter, but it's ignored with SERIES_SYNCHRONIZE. EDIT: To confirm or not, I am investigating...

  • If each timeseries (i.e., chart of each timeframe) has its own independent SERIES_SYNCHRONIZED, then why does it return true for a timeseries that doesn't even have the current bar available?
No. It's independent of the timeframe. EDIT: To confirm or not, I am investigating...

    Main question: What specific data does SERIES_SYNCHRONIZED actually refer to?

    Already answered. EDIT: To confirm or not, I am investigating...

    Additional question: How does SERIES_SYNCHRONIZED differ from SymbolIsSynchronized()?

    Didn't even remember it was existing 😆

    It's the same as SeriesInfoInteger() with SERIES_SYNCHRONIZED. EDIT: I can already say it's NOT the same...will give more details later.

     
    Vladislav Boyko #:

    Here’s an interesting statement from a MetaQuotes employee (machine-translated):

    I’m not entirely sure whether he was referring to SERIES_SYNCHRONIZED. And unfortunately, he didn’t explain why the current chart’s symbol is guaranteed to be synchronized for EAs and indicators 😁

    He didn't talked mainly about SERIES_SYNCHRONIZED (so Terminal versus Server), but about how it works in the Terminal between data (symbols/timeseries) and applications (Indicators/EAs/Scripts).

    The current chart symbol is guarantee to be synchronised because it's what the platform do before calling OnTick() or OnCalculate().

    While the chart symbol is guarantee to be synchronized, ONLY the current series (chart timeframe) is guarantee to be ready, for the same symbol, ALL other series (timeframes different from the chart one) can FAIL (error 4401), due to the asynchronous nature of MT5/MQL5.

    The other symbols are not guaranteed to be synchronized, and whatever the timeframe it can always fail when trying to get data.

     
    Vladislav Boyko #:
    ...

    And here’s a quote from AlgoBook, where the author does exactly what Slava called pointless (unless I’m mistaken — which is entirely possible):

    The quote is a bit without context and seems strange. I will read this page of the book to see...

     
    Vladislav Boyko #:

    Here’s an interesting statement from a MetaQuotes employee (machine-translated):

    I’m not entirely sure whether he was referring to SERIES_SYNCHRONIZED. And unfortunately, he didn’t explain why the current chart’s symbol is guaranteed to be synchronized for EAs and indicators 😁

    And here’s a quote from AlgoBook, where the author does exactly what Slava called pointless (unless I’m mistaken — which is entirely possible):

    So about this. I tested with some code and...it's not entirely pointless, it happens ! The series for the current chart/symbol can be NOT synchronized (though it's rare and hard to reproduce).

    bool QuoteRefresh(const string symbol,const ENUM_TIMEFRAMES period)
     {
      if(_Symbol == symbol && _Period == period)
       {
        return (bool)SeriesInfoInteger(symbol, period, SERIES_SYNCHRONIZED);
       }
    //---
      return(false);
     }
    void OnTick()
     {
      if(!QuoteRefresh(Symbol(),Period()))
       {
        printf("%s: WARNING! QuoteRefresh(%s,%s) RETURNED FALSE !!!",__FUNCTION__,Symbol(),EnumToString(Period()));
       }
     }

    2025.05.29 00:41:16.003    CheckSynchronization (BTCEUR,H1)    OnTick: WARNING! QuoteRefresh(BTCEUR,PERIOD_H1) RETURNED FALSE !!!

     
    Alain Verleyen #:

    Didn't even remember it was existing 😆

    It's the same as SeriesInfoInteger() with SERIES_SYNCHRONIZED. EDIT: I can already say it's NOT the same...will give more details later.

    About this.

    I can already say it's NOT the same.

    2025.05.29 00:50:58.415    CheckSynchronization (XAUUSD,H1)    FROM INIT : XAUUSD/PERIOD_M4 isSymbolSynchronized=false isSeriesSynchronized=false
    2025.05.29 00:50:59.465    CheckSynchronization (XAUUSD,H1)    FROM ONTICK : XAUUSD/PERIOD_M4 isSymbolSynchronized=true DIFFERENT isSeriesSynchronized=false
    2025.05.29 00:50:59.667    CheckSynchronization (XAUUSD,H1)    FROM ONTICK : XAUUSD ALL is SYNCHRONIZED.

    Firstly both false, then one true to other false, and finally both true (the log shows only M4 to avoid flooding but all MT5 timeframes are tested).
     
    Alain Verleyen #:

    So about this. I tested with some code and...it's not entirely pointless, it happens ! The series for the current chart/symbol can be NOT synchronized (though it's rare and hard to reproduce).

    2025.05.29 00:41:16.003    CheckSynchronization (BTCEUR,H1)    OnTick: WARNING! QuoteRefresh(BTCEUR,PERIOD_H1) RETURNED FALSE !!!

    An other example from an indicator :

    2025.05.29 01:09:08.522    CheckSynchronizationIndi (XAUUSD,H1)    OnCalculate: WARNING! QuoteRefresh(XAUUSD,PERIOD_H1) RETURNED FALSE !!!

     
    Alain Verleyen #:

    He didn't talked mainly about SERIES_SYNCHRONIZED (so Terminal versus Server), but about how it works in the Terminal between data (symbols/timeseries) and applications (Indicators/EAs/Scripts).

    The current chart symbol is guarantee to be synchronised because it's what the platform do before calling OnTick() or OnCalculate().

    While the chart symbol is guarantee to be synchronized, ONLY the current series (chart timeframe) is guarantee to be ready, for the same symbol, ALL other series (timeframes different from the chart one) can FAIL (error 4401), due to the asynchronous nature of MT5/MQL5.

    The other symbols are not guaranteed to be synchronized, and whatever the timeframe it can always fail when trying to get data.

    Confirmation that a CopyXXX can fail on a symbol/timeframe not being the one of the chart :

    2025.05.29 01:22:36.140    CheckSynchronizationIndi (XAUUSD,H1)    FROM OnCalculate : NZDCAD/PERIOD_MN1 COPIED=-1 4401
    2025.05.29 01:22:36.140    CheckSynchronizationIndi (XAUUSD,H1)    FROM OnCalculate : NZDCAD ALL is SYNCHRONIZED.

     
    Alain Verleyen #:

    So about this. I tested with some code and...it's not entirely pointless, it happens ! The series for the current chart/symbol can be NOT synchronized (though it's rare and hard to reproduce).

    2025.05.29 00:41:16.003    CheckSynchronization (BTCEUR,H1)    OnTick: WARNING! QuoteRefresh(BTCEUR,PERIOD_H1) RETURNED FALSE !!!

    Also, an important thing is overlooked - almost all utility tools (such as QuoteRefresh) in the book are general purpose and should work properly in different scenarios, specifically can be used in any event handler (if not explicitly stated otherwise), not necessarily in OnTick or OnCalculate.

    Besides, MT5 is a highly asynchronous beast, where thousands of threads communicate by sending and queuing messages, and events like OnTick or OnCalculate are posted to the queue of your MQL5 program when a corresponding tick is processed by the terminal (series are in sync), but at the moment when the event is actually handled there can be another tick(s) and series are not in sync. So, in general, you have no any guarantees and should always check all preconditions important for your code fragment.