iBandsOnArray in combination with MTF: what am I doing wrong?

 

Hi, I want to display the values of the RSI from the 1 hour chart on all lower time frames, and also the values of a Bollinger Band calculated on the H1 RSI. So both values come from the H1 chart. Could you tell me what I am doing wrong please? I can manage to display the RSI but the iBandsOnArray values change when I change i.e. from M15 to M5, so something is wrong:

 

#property indicator_separate_window
#property indicator_buffers  4
#property indicator_color1 DodgerBlue
#property indicator_color2 Red
#property indicator_color3 Red
#property indicator_color4 Red
#property indicator_maximum 100
#property indicator_minimum 0
#property indicator_level1 80
#property indicator_level2 20
#property indicator_levelcolor Silver
#property indicator_levelstyle STYLE_DOT



extern int RSIperiod=2;
extern int Bollingerperiod=20;
extern int BollingerDeviations=1;
double RSIbuffer[];
double UpBol[];
double MidBol[];
double LowBol[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
{
   SetIndexBuffer(0,RSIbuffer);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,UpBol);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,MidBol);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(3,LowBol);
   SetIndexStyle(3,DRAW_LINE);
      
   return(0);
}
int deinit() { return(0); }

int start()
{
   int counted_bars=IndicatorCounted();
   int i,limit;
   if(counted_bars<0) return(-1);
   limit=Bars-1-MathMax(10, counted_bars);
   
   for(i=limit; i>=0; i--)
   {
      int shift=iBarShift(0,PERIOD_H1,iTime(Symbol(),Period(),i));
      if (shift == -1) continue;
      
      RSIbuffer[i]=iRSI(NULL,PERIOD_H1,RSIperiod,PRICE_CLOSE,iBarShift(NULL,PERIOD_H1,Time[i]));
      //RSIbuffer[i]=iRSI(NULL,PERIOD_H1,RSIperiod,PRICE_CLOSE,shift);
   }
 
    for(i=limit; i>=0; i--)
   {
      MidBol[i]=iBandsOnArray(RSIbuffer,0,Bollingerperiod,BollingerDeviations,0,MODE_MAIN,iBarShift(NULL,PERIOD_H1,Time[i]));
      UpBol[i]=iBandsOnArray(RSIbuffer,0,Bollingerperiod,BollingerDeviations,0,MODE_UPPER,iBarShift(NULL,PERIOD_H1,Time[i]));
      LowBol[i]=iBandsOnArray(RSIbuffer,0,Bollingerperiod,BollingerDeviations,0,MODE_LOWER,iBarShift(NULL,PERIOD_H1,Time[i]));
   }
 
  return(0);
}
 
Belmann:

 the iBandsOnArray values change when I change i.e. from M15 to M5, so something is wrong:

 

The RSI array is not the same in the 2 time-frames

The M15 array will have the value from a single H1 bar spread across 4 elements of the array.

In M5 it will be spread across 12 elements.

 
  1. You can't generate your RSIbuffer like that and use OnArray. The buffer contains something like 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23, but On Array expects 20 21 22 23...
  2. You need an array[Bollingerperiod] filled with the last n H1 RSI values.
 
WHRoeder:
  1. You can't generate your RSIbuffer like that and use OnArray. The buffer contains something like 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23, but On Array expects 20 21 22 23...
  2. You need an array[Bollingerperiod] filled with the last n H1 RSI values.

 1) So first I need a way to detect the "n" value: the multiplier in minutes between the shorter time frame and the H1, like 4 for M15, 2 for M30, 12 for M5.. 

 

int  Nmult=60/Period();

 Like this?

 

2)  And then I need to create a new array filled with every n'th value of the RSIbuffer: probably something to do with the index number, and checking for divisibility:  x %% 4 == 0

Something like that? But then.. 

 

 


 
Belmann:

 1) So first I need a way to detect the "n" value: the multiplier in minutes between the shorter time frame and the H1, like 4 for M15, 2 for M30, 12 for M5.. 

 

 Like this?

 

2)  And then I need to create a new array filled with every n'th value of the RSIbuffer: probably something to do with the index number, and checking for divisibility:  x %% 4 == 0

Something like that? But then.. 

 

 


use iBarShift
 
eevviill:
use iBarShift
I did: read my code.
 
Belmann:

 1) So first I need a way to detect the "n" value: the multiplier in minutes between the shorter time frame and the H1, like 4 for M15, 2 for M30, 12 for M5.. 

 Like this?
int  Nmult=60/Period();

2) And then I need to create a new array filled with every n'th value of the RSIbuffer: probably something to do with the index number, and checking for divisibility: x %% 4 == 0 Something like that? But then.
  1. That assumes that there are no missing bars. "Free-of-Holes" Charts - MQL4 Articles
  2. Create your RSI(TF) array and then use iBarsShift to translate chart shift to the proper TF shift.
 
WHRoeder:
Belmann:

 1) So first I need a way to detect the "n" value: the multiplier in minutes between the shorter time frame and the H1, like 4 for M15, 2 for M30, 12 for M5.. 

 Like this?

2) And then I need to create a new array filled with every n'th value of the RSIbuffer: probably something to do with the index number, and checking for divisibility: x %% 4 == 0Something like that? But then.
  1. That assumes that there are no missing bars. "Free-of-Holes" Charts - MQL4 Articles
  2. Create your RSI(TF) array and then use iBarsShift to translate chart shift to the proper TF shift.
I don't know how to do this. Why is something so simple so hard in mql4...
 
Belmann:
I don't know how to do this. Why is something so simple so hard in mql4...
The simplest way would be to code a non MTF that calculates the Bollinger on array, then use an iCustom call on the new indicator.
 
Belmann: I don't know how to do this. Why is something so simple so hard in mql4...
  1. If it's so simple, why don't you know how to do it? learn to code it, or pay someone. We're not going to code it FOR you. We are willing to HELP you when you post your attempt (using SRC) and the nature of your problem.
  2. GumRai's suggestion is the simplest, but it doesn't need to be a separate indicator if one of the externs is the timeframe.
    extern ENUM_TIMEFRAMES TF=PERIOD_CURRENT;
    enum buffers{RSI, MID, ...); // Corresponds to order of buffers
    
    if(tf == PERIOD_CURRENT) tf = _Period;
    if(tf == _Period) for(i=limit; i>=0; i--){
       RSIbuffer[i] = iRSI(NULL,0,RSIperiod,PRICE_CLOSE, i); 
       H1Mid[H1Bar] = iBandsOnArray(RSIbuffer,0,Bollingerperiod,BollingerDeviations,0,MODE_MAIN,i);
       :
    }
    else for(i=limit; i>=0; i--){
       int TFBar=iBarShift(NULL,TF,Time[i]));
       RSIbuffer[i] = iCustom(NULL, TF, WindowExpertName(), PERIOD_CURRENT, ..., RSI, TFBar);
       H1Mid[i]     = iCustom(NULL, TF, WindowExpertName(), PERIOD_CURRENT, ..., MID, TFBar);
       :
    }

  3. What part of "Create your RSI(TF) array and then use iBarsShift to translate chart shift to the proper TF shift." was unclear?
       int H1Bar = iBars(NULL, PERIOD_H1);
       // These can't be buffers because (different chart.)
       double H1RSI[]; ArrayResize(H1RSI, H1Bar); ArraySetAsSeries(H1RSI, true);
       double H1Mid[]; ArrayResize(H1Mid, H1Bar); ArraySetAsSeries(H1Mid, true);
       :
       while(--H1Bar >= 0){
         H1RSI[H1Bar] = iRSI(NULL,PERIOD_H1,RSIperiod,PRICE_CLOSE, H1Bar); 
         H1Mid[H1Bar] = iBandsOnArray(H1RSI,0,Bollingerperiod,BollingerDeviations,0,MODE_MAIN,H1Bar);
         :
       }
       i = Bars - 1 - counted_bars; // If this corresponds to H1 bar zero 
                                    // Must redraw all corresponding candles.
       datetime H1TimeI = Time[i] - Time[i] % PeriodSeconds(PERIOD_H1);
       limit=iBarShift(NULL,PERIOD_CURRENT,H1TimeI);
       for(i=limit; i>=0; i--){
          H1Bar=iBarShift(NULL,PERIOD_H1,Time[i]));      
          RSIbuffer[i]=H1RSI[H1Bar];
          MidBol[i]   =H1Mid[H1Bar];
          :
       }
Reason: