Is it mystical?! It is!

 

Total confused.

This doesn't work (result >> bars=0):

int OnInit()
  {
   string chartSymbol=_Symbol;
   int bars=Bars(chartSymbol,_Period);
   Print("Bars: ",bars);   
   return(INIT_SUCCEEDED);
  }

This works (result >> bars=the proper value):

int OnInit()
  {
   int bars=Bars(_Symbol,_Period);
   Print("Bars: ",bars);   
   return(INIT_SUCCEEDED);
  }

Can you explain, why?

 

Note

If data for the timeseries with specified parameters are not formed in the terminal by the time of the Bars() function call, or data of the timeseries are not synchronized with a trade server by the moment of the function call, the function returns a zero value.

 

I read that, but I think that is not the problem here.

I tried many times both cases, _Symbol worked always, chartSymbol did not. Why?

 

This my code (based on the documentation) run 50(!) attempts, and gave 0. My internet and broker connection is ready. Why did I get 0?

int OnInit()
  {
   string chartSymbol=_Symbol;
   int bars=Bars(chartSymbol,_Period);   
   if(bars<=0) //no available bars
     {      
      //--- data on the symbol might be not synchronized with data on the server
      bool synchronized=false;
      //--- loop counter
      int attempts=0;
      // make 50 attempts to wait for synchronization
      while(attempts<50)
        {
         if(SeriesInfoInteger(Symbol(),0,SERIES_SYNCHRONIZED))
           {
            //--- synchronization done, exit
            synchronized=true;
            break;
           }
         //--- increase the counter
         Print("ATTEMPTS: ",attempts);
         attempts++;         
         //--- wait 10 milliseconds till the next iteration
         Sleep(10);
        }
      //--- exit the loop after synchronization
      if(synchronized)
        {
         Print("Number of bars in the terminal history for the symbol-period at the moment = ",bars);
         Print("The first date in the terminal history for the symbol-period at the moment = ",
               (datetime)SeriesInfoInteger(Symbol(),0,SERIES_FIRSTDATE));
         Print("The first date in the history for the symbol on the server = ",
               (datetime)SeriesInfoInteger(Symbol(),0,SERIES_SERVER_FIRSTDATE));
        }
      //--- synchronization of data didn't happen
      else
        {
         Print("Failed to get number of bars for ",_Symbol);
        }
     }
   Print("bars: ",bars);
   return(INIT_SUCCEEDED);
  }
 

Try to synchronize data in OnCalculate() or OnTick(), not OnInit(). Data isn't always ready in OnInit().

I often do start a load of data in OnInit() using CopyTime() to ensure the Tester has access to the currency, but I never check for bars returned in OnInit().

https://www.mql5.com/en/forum/286608#comment_9184731

 
Anthony Garot:

Try to synchronize data in OnCalculate() or OnTick(), not OnInit(). Data isn't always ready in OnInit().

I often do start a load of data in OnInit() using CopyTime() to ensure the Tester has access to the currency, but I never check for bars returned in OnInit().

https://www.mql5.com/en/forum/286608#comment_9184731

Thank you for the answer, I will try it in the OnCalculate().

BTW, why do you use CopyTime(), why not CopyRates()?

 

Copy time will return the copied data count or -1 if it fails so when you get a -1 you can conclude that the history wasn't available.

Note

If the whole interval of requested data is out of the available data on the server, the function returns -1. If data outside TERMINAL_MAXBARS (maximal number of bars on the chart) is requested, the function will also return -1.

When requesting data from the indicator, if requested timeseries are not yet built or they need to be downloaded from the server, the function will immediately return -1, but the process of downloading/building will be initiated.

 
Marco vd Heijden:

Copy time will return the copied data count or -1 if it fails so when you get a -1 you can conclude that the history wasn't available.

Note

If the whole interval of requested data is out of the available data on the server, the function returns -1. If data outside TERMINAL_MAXBARS (maximal number of bars on the chart) is requested, the function will also return -1.

When requesting data from the indicator, if requested timeseries are not yet built or they need to be downloaded from the server, the function will immediately return -1, but the process of downloading/building will be initiated.

Yes, but he wrote this: "I often do start a load of data in OnInit() using CopyTime()". So, he wanted to get data, not only check if those are available, if I understand correctly.
 
linux80s:

Thank you for the answer, I will try it in the OnCalculate().

BTW, why do you use CopyTime(), why not CopyRates()?

I think either would work. The documentation says for both:

When requesting data from an Expert Advisor or script, downloading from the server will be initiated, if  the terminal does not
have these data locally, or building of a required timeseries will start, if data can be built from the local history but they are not ready yet.

CopyTime is simpler, in my opinion. I don't actually use the data pulled into the buffer. I use CopyRates() or CopyTime() or CopyHigh() or whatever elsewhere (not in OnInit()) to get the data I need.