iBarShift() returns -1 - multiple timeframes

 

I have an indicator running on M15 timeframe.

I am selecting a 15minute bar [i] and getting the time of the bar.

I am tring to use the time of the bar (rounded down to the nearest full hour) to identify the corresponding bar on the H1 timeframe.

Its not working.... ANy help please.

//Search bar by time. The function returns the index of the bar corresponding to the specified time.
      int M15_bar = iBarShift(Symbol(),PERIOD_M15,time[i]);

      //Returns the opening time of the bar (indicated by the 'shift' parameter) on the corresponding chart.
      datetime time_of_M15_bar = iTime(Symbol(),PERIOD_M15,M15_bar);

      // Convert datetime to seconds since epoch
      double time_in_seconds = (double)time_of_M15_bar;

      // Round to the nearest 3600 seconds (1 hour)
      double rounded_seconds = MathFloor(time_in_seconds / 3600.0) * 3600.0;

      // Convert back to datetime - minutes removed
      datetime time_of_H1_bar = (datetime)rounded_seconds;

      // identify the correct bar
      int H1_bar_1 = iBarShift(Symbol(),PERIOD_H1,time_of_H1_bar);


      int error=GetLastError();
      if(error!=0)
        {
         PrintFormat("iBarShift(): GetLastError=%d - The requested date %s "+
                     "for %s %s is not found in the available history",
                     error,TimeToString(time_of_H1_bar),"EURUSD",EnumToString(PERIOD_H1));
         //return;
        }


This is the error returned:

2025.11.12 13:39:37.391 iBarShift(): GetLastError=4401 - The requested date 2025.11.12 14:00 for EURUSD PERIOD_H1 is not found in the available history


EURUSD (Euro vs US Dollar): Live Forex Charts
EURUSD (Euro vs US Dollar): Live Forex Charts
  • 2025.11.12
  • www.mql5.com
EURUSD exchange rate has changed by -0.05% for today. During the day, the instrument was traded at a low of 1.15649 and at a high of 1.15886
 
G Toner:

I have an indicator running on M15 timeframe.

I am selecting a 15minute bar [i] and getting the time of the bar.

I am tring to use the time of the bar (rounded down to the nearest full hour) to identify the corresponding bar on the H1 timeframe.

Its not working.... ANy help please.


This is the error returned:

2025.11.12 13:39:37.391 iBarShift(): GetLastError=4401 - The requested date 2025.11.12 14:00 for EURUSD PERIOD_H1 is not found in the available history


In order to call multiple timeframes of the same symbol, you need to synchronize the data from both timeframes.

Alternatively, put your second timeframe within a custom function:

Forum on trading, automated trading systems and testing trading strategies

most efficient way to call daily ATR from lower timeframes?

Mladen Rakic, 2017.12.25 21:12

Using handles to indicators like that tends to be clumsy (what if we decide to change the time frame or the period "on the fly" - new handle? ... yeeah ...)

More or less mt5 is making us code a bit more to get better results - ATR is a simple case (excluding the time frame and the period, it is not so much lines of code after all, and allows us flexibility that handle usage would not let us). I did not bother with the case explanation when there is less data available than the ATR desired period+1 rates available in the target time frame data - that is the case that built in ATR does not solve intuitively, and this simple code does that better (at least that is my opinion ...). Making this a function is no big deal either and will work better, faster, and in more flexible way than the built in ATR ...

ENUM_TIMEFRAMES _atrTimeFrame = PERIOD_D1;
int             _atrPeriod    = 20;
double          _atrValue     = 0;
   MqlRates _rates[]; int _ratesCopied = CopyRates(_Symbol,_atrTimeFrame,0,_atrPeriod+1,_rates);
                      if (_ratesCopied>0)
                           for (int i=1; i<_ratesCopied; i++) _atrValue += MathMax(_rates[i].high,_rates[i-1].close)-MathMin(_rates[i].low,_rates[i-1].close);
                                                              _atrValue /= MathMax(_ratesCopied,1);


 
How can I apply this to achieve what I am trying to do?
 
G Toner #How can I apply this to achieve what I am trying to do?
Please take the time to refer to the documentation on data synchronisation... Documentation on MQL5: Organizing Data Access / Timeseries and Indicators Access
Documentation on MQL5: Organizing Data Access / Timeseries and Indicators Access
Documentation on MQL5: Organizing Data Access / Timeseries and Indicators Access
  • www.mql5.com
In this section questions connected with obtaining, storing and requesting price data ( timeseries ) are considered. Before price data become...
 
G Toner #:
How can I apply this to achieve what I am trying to do?

In the spirit of Mladen Rakic's code, and based on the code fragment that you provided...

I'm not even sure if iBarShift() can be used in this way, but this is what I worked up--uncompiled and untested.

//globals
int H1_bar_1;

//Search bar by time. The function returns the index of the bar corresponding to the specified time.
      int M15_bar = iBarShift(Symbol(),PERIOD_M15,time[i]);

      //Returns the opening time of the bar (indicated by the 'shift' parameter) on the corresponding chart.
      datetime time_of_M15_bar = iTime(Symbol(),PERIOD_M15,M15_bar);

      // Convert datetime to seconds since epoch
      double time_in_seconds = (double)time_of_M15_bar;

      // Round to the nearest 3600 seconds (1 hour)
      double rounded_seconds = MathFloor(time_in_seconds / 3600.0) * 3600.0;

      // Convert back to datetime - minutes removed
      datetime time_of_H1_bar = (datetime)rounded_seconds;

      // identify the correct bar
      H1_bar_1=H1_function(time_of_H1_bar);
      //int H1_bar_1 = iBarShift(Symbol(),PERIOD_H1,time_of_H1_bar);


      int error=GetLastError();
      if(error!=0)
        {
         PrintFormat("iBarShift(): GetLastError=%d - The requested date %s "+
                     "for %s %s is not found in the available history",
                     error,TimeToString(time_of_H1_bar),"EURUSD",EnumToString(PERIOD_H1));
         //return;
        }

void H1_function(datetime H1_bar_time)
{
 ENUM_TIMEFRAMES _higherTimeFrame = PERIOD_H1;
    MqlRates _rates[]; int _ratesCopied = CopyRates(_Symbol,_higherimeFrame,0,0,_rates);
                       if (_ratesCopied>0)
                            for (int i=1; i<_ratesCopied; i++)
                               {
                                if(_rates[i].time>=H1_bar_time)
                                   {
                                    H1_bar_1=iBarShift(_Symbol,_higherTimeFrame,H1_bar_time);
                                   }
                               }
}
Edit: Time expressed in seconds is technically a ulong, and datetimes should be typecast to ulongs for math evaluations. The H1_function() goes below your entire OnCalculate() function.
 
//globals
int H1_bar_1;

//Search bar by time. The function returns the index of the bar corresponding to the specified time.
      int M15_bar = iBarShift(Symbol(),PERIOD_M15,time[i]);

      //Returns the opening time of the bar (indicated by the 'shift' parameter) on the corresponding chart.
      datetime time_of_M15_bar = iTime(Symbol(),PERIOD_M15,M15_bar);

      // Convert datetime to seconds since epoch
      ulong time_in_seconds = (ulong)time_of_M15_bar;

      // Round to the nearest 3600 seconds (1 hour)
      ulong rounded_seconds = (ulong)(MathFloor(time_in_seconds / 3600.0) * 3600.0);

      // Convert back to datetime - minutes removed
      datetime time_of_H1_bar = (datetime)rounded_seconds;

      // identify the correct bar
      H1_bar_1 = H1_function(time_of_H1_bar);


      int error=GetLastError();
      if(error!=0)
        {
         PrintFormat("iBarShift(): GetLastError=%d - The requested date %s "+
                     "for %s %s is not found in the available history",
                     error,TimeToString(time_of_H1_bar),"EURUSD",EnumToString(PERIOD_H1));
        }

      //testing...
      Print("time_of_M15_bar ", time_of_M15_bar); //working
      Print("time_of_H1_bar ", time_of_H1_bar); //working
      Print("H1_bar_1 ", H1_bar_1); //RETURNS 0 every time
      Print("H1_bar_1_HIGH ", iHigh(Symbol(),PERIOD_H1,H1_bar_1)); //Returns the high of the current bar '0'?

//+------------------------------------------------------------------+
int H1_function(datetime H1_bar_time)
  {
   ENUM_TIMEFRAMES _higherTimeFrame = PERIOD_H1;
   MqlRates _rates[];
   int _ratesCopied = CopyRates(_Symbol,_higherTimeFrame,0,0,_rates);
   if(_ratesCopied>0)
      for(int i=1; i<_ratesCopied; i++)
        {
         if(_rates[i].time==H1_bar_time)
           {
            H1_bar_1=iBarShift(_Symbol,_higherTimeFrame,H1_bar_time);
           }
        }
   return H1_bar_1;
  }
//+------------------------------------------------------------------+



 This is what I have got so far.. 

 Print("H1_bar_1 ", H1_bar_1); //RETURNS 0 every time
 Print("H1_bar_1_HIGH ", iHigh(Symbol(),PERIOD_H1,H1_bar_1)); //Returns the high of the current bar '0'?

2025.11.13 12:25:23.197	 (EURUSD+,M15)	iBarShift(): GetLastError=4003 - The requested date 2025.11.13 14:00 for EURUSD PERIOD_H1 is not found in the available history



 

@G Toner, thanks for doing your own testing. As I thought was possible, iBarShift() is operating outside of the copied rates and does not work like CopyRates().

If you still don't want to synch multiple timeframe rates, there is a way that works without calling the H1 timeframes--using time, itself.

In this way no custom function is required.

MqlDateTime stm;
datetime tm=TimeCurrent(stm);
//--- output date components
Alert("Year: "        +(string)stm.year);
Alert("Month: "      +(string)stm.mon);
Alert("Day: "      +(string)stm.day);
Alert("Hour: "        +(string)stm.hour);
Alert("Minute: "     +(string)stm.min);
Alert("Second: "    +(string)stm.sec);
Alert("Day of the week: "+(string)stm.day_of_week);
Alert("Day of the year: "  +(string)stm.day_of_year);

Articles

MQL5 Programming Basics: Time

Dmitry Fedoseev, 2013.04.26 11:49

The article focuses on standard MQL5 functions for working with time, as well as programming techniques and practically useful functions for working with time that are required when creating Expert Advisors and indicators. Particular attention is paid to the general theory of time measurement. This article should be of interest primarily to novice MQL5 programmers.

Obviously, you won't be typecasting to strings but you can code something like:

if(stm.min==45)
 {
  //then do something
 }

Based on my experience, TimeCurrent()--server time will not work in the Tester but TimeLocal()--pc time will.

 

As another alternative, have a look at another MTF indicator's code that uses CopySeries(). This was just posted today.

Code Base

Confluence Detector

Conor Mcnamara, 2024.04.19 21:13

It will detect whether there's confluence between the current chart timeframe and two other timeframes.

 
G Toner:

I have an indicator running on M15 timeframe.

I am selecting a 15minute bar [i] and getting the time of the bar.

I am tring to use the time of the bar (rounded down to the nearest full hour) to identify the corresponding bar on the H1 timeframe.

Its not working.... ANy help please.


This is the error returned:

2025.11.12 13:39:37.391 iBarShift(): GetLastError=4401 - The requested date 2025.11.12 14:00 for EURUSD PERIOD_H1 is not found in the available history


https://www.mql5.com/ru/forum/1111/page3596#comment_55270431


 
Ryan L Johnson #:
synch multiple timeframe rates

I did try to sync multiple timeframe rates using the details here.

https://www.mql5.com/en/docs/series/timeseries_access

I created a script and loaded it on the chart. Still the same result.

Documentation on MQL5: Organizing Data Access / Timeseries and Indicators Access
Documentation on MQL5: Organizing Data Access / Timeseries and Indicators Access
  • www.mql5.com
In this section questions connected with obtaining, storing and requesting price data ( timeseries ) are considered. Before price data become...
 
G Toner #:

I did try to sync multiple timeframe rates using the details here.

https://www.mql5.com/en/docs/series/timeseries_access

I created a script and loaded it on the chart. Still the same result.

Try using Conor Mcnamara's code from my Post #7 above:

   CopySeries(Symbol(), timeframe_a, 0, rates_total, COPY_RATES_CLOSE, buf_a);
   CopySeries(Symbol(), timeframe_b, 0, rates_total, COPY_RATES_CLOSE, buf_b);
   CopySeries(Symbol(), timeframe_c, 0, rates_total, COPY_RATES_CLOSE, buf_c);

but with COPY_RATES_TIME.