How do I call the buffers for Bollinger Bands when applied to Previous Indicators Data?

 
Hello,

I have an indicator in a separate window and I apply the default MT4 Bollinger Band indicator in this Window i.e Applied to Previous Indicators Data. It works well for me seeing when the line goes outside the Bollinger Bands. I can see the two sets of data in DataWindow, but I would like to access these data in an EA. I am perplexed about how I actually do this. The complication being the BB are applied to this indicators values and not price in the chart proper.

I have obtained the MetaQuotes Bollinger Bands but can't see how to apply to Previous Indicators Data. I tried substituting the iMA with the alternative indicator data (but not averaged as I would like)

Can anyone point me in the right direction how to solve this? I really only want to have the Bollinger Bands mid-line as the moving average N periods of the other indicator and then have the envelopes x StdDev above and below.

//+------------------------------------------------------------------+
//|                                                        Bands.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_separate_window // Changed from Chart Window to Separate Window
#property indicator_buffers 3
#property indicator_color1 LightSeaGreen
#property indicator_color2 LightSeaGreen
#property indicator_color3 LightSeaGreen
//---- indicator parameters
extern int    BandsPeriod=10;
extern int    BandsShift=0;
extern double BandsDeviations=2.0;
//---- buffers
double MovingBuffer[];
double UpperBuffer[];
double LowerBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,MovingBuffer);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,UpperBuffer);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,LowerBuffer);
//----
   SetIndexDrawBegin(0,BandsPeriod+BandsShift);
   SetIndexDrawBegin(1,BandsPeriod+BandsShift);
   SetIndexDrawBegin(2,BandsPeriod+BandsShift);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Bollinger Bands                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    i,k,counted_bars=IndicatorCounted();
   double deviation;
   double sum,oldval,newres;
//----
   if(Bars<=BandsPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=BandsPeriod;i++)
        {
         MovingBuffer[Bars-i]=EMPTY_VALUE;
         UpperBuffer[Bars-i]=EMPTY_VALUE;
         LowerBuffer[Bars-i]=EMPTY_VALUE;
        }
//----
   int limit=Bars-counted_bars;
   if(counted_bars>0) limit++;
   for(i=0; i<limit; i++)
//    MovingBuffer[i]=iMA(NULL,0,BandsPeriod,BandsShift,MODE_SMA,PRICE_CLOSE,i); Substituted this with ....
      MovingBuffer[i]=iCustom(NULL,0,"DetrendIndicator", 10, true, 0,i);
//----
   i=Bars-BandsPeriod+1;
   if(counted_bars>BandsPeriod-1) i=Bars-counted_bars-1;
   while(i>=0)
     {
      sum=0.0;
      k=i+BandsPeriod-1;
      oldval=MovingBuffer[i];
      while(k>=i)
        {
         newres=Close[k]-oldval;
         sum+=newres*newres;
         k--;
        }
      deviation=BandsDeviations*MathSqrt(sum/BandsPeriod);
      UpperBuffer[i]=oldval+deviation;
      LowerBuffer[i]=oldval-deviation;
      i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
NewtonLeo:
Hello,

I have an indicator in a separate window and I apply the default MT4 Bollinger Band indicator in this Window i.e Applied to Previous Indicators Data. It works well for me seeing when the line goes outside the Bollinger Bands. I can see the two sets of data in DataWindow, but I would like to access these data in an EA. I am perplexed about how I actually do this. The complication being the BB are applied to this indicators values and not price in the chart proper.

I have obtained the MetaQuotes Bollinger Bands but can't see how to apply to Previous Indicators Data. I tried substituting the iMA with the alternative indicator data (but not averaged as I would like)

Can anyone point me in the right direction how to solve this? I really only want to have the Bollinger Bands mid-line as the moving average N periods of the other indicator and then have the envelopes x StdDev above and below.



You have to create new Bollinger Bands, collect the indicator data using iCustom(), then use iMAOnArray() for bands middle line and iBandsOnArray() for bands upper/lower line.

 
phi.nuts:


You have to create new Bollinger Bands, collect the indicator data using iCustom(), then use iMAOnArray() for bands middle line and iBandsOnArray() for bands upper/lower line.

Thanks for taking the time to reply phi.nuts.

Trying one step at a time (getting the midline right first), I replaced

//    MovingBuffer[i]=iMA(NULL,0,BandsPeriod,BandsShift,MODE_SMA,PRICE_CLOSE,i); commented out original 
      MovingBuffer[i]=iCustom(NULL,0,"DetrendIndicator", 10, true, 0,i);

with

double  DI = iCustom(NULL,0,"DetrendIndicator", 10, true, 0,i); // Collect the indicator data
MovingBuffer[i]=iMAOnArray(DI,0,BandsPeriod, BandsShift, MODE_SMA, i); //(I also tried ... MovingBuffer[i]=iMAOnArray(DI,0,BandsPeriod, BandsShift, MODE_SMA, 0,i);)

but all my attempts are not working out. I read the three links you gave and one referenced called ArraySetAsSeries but I'm not successful.
 
NewtonLeo:
Thanks for taking the time to reply phi.nuts.

Trying one step at a time (getting the midline right first), I replaced


but all my attempts are not working out. I read the three links you gave and one referenced called ArraySetAsSeries but I'm not successful.


I said create a new one - from a scratch.

double data[], middle[], upper[], lower[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(4);
   SetIndexBuffer (0, data);
   SetIndexBuffer (1, middle);
   SetIndexBuffer (2, upper);
   SetIndexBuffer (3, lower);
   
   SetIndexStyle (1, DRAW_LINE);
   SetIndexStyle (2, DRAW_LINE);
   SetIndexStyle (3, DRAW_LINE);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() { return(0);}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
 
   int pos, indicator_counted;
   
   // collecting data
   for (pos = Bars - indicator_counted - 1; pos >= 0; pos --)
      {
      Data [pos] = iCustom(NULL, 0, "DetrendIndicator", 10, true, 0, pos);
      }
   
   // creating middle band  
   for (pos = Bars - indicator_counted - 1; pos >= 0; pos --)
      {
      Middle [pos] = iMAOnArray (data, Bars, ... , pos);
      }
   
   // creating upper/lower band
   for (pos = Bars - indicator_counted - 1; pos >= 0; pos --)
      {
      Upper [pos] = iBandsOnArray (Data, Bars, ... , pos);
      Lower [pos] = iBandsOnArray (Data, Bars, ... , pos); 
      }
   
   indicator_counted = IndicatorCounted();
//----
   return(0);
  }
//+------------------------------------------------------------------+

I did not test all of the code let alone compile it - so do experimenting and hopes other forumer also helps you.

Experimenting like create Band with the code above except the data is the close price (Close[pos]) then compare the result with the standard Band from MT.

 
phi.nuts:


I said create a new one - from a scratch.

I did not test all of the code let alone compile it - so do experimenting and hopes other forumer also helps you.

Experimenting like create Band with the code above except the data is the close price (Close[pos]) then compare the result with the standard Band from MT.


Many thanks for taking time to do this. I really appreciate. I'll try it out now. Very pleased you have responded.
 
NewtonLeo:

Many thanks for taking time to do this. I really appreciate. I'll try it out now. Very pleased you have responded.
  I have tried many combinations to get this working (and I am learning new things).

  Changed the upper to lower case for "Data", "Upper", "Middle" and "Lower"  to agree with defined doubles (in lower case) below the properties.

  Read in docs.mql4 that "Bars" means all if 0 is used and  I experimented to find what was needed to substitute the "..." with to get it to compile properly.  I guess I got this wrong but it compiles without errors.

  The result is the middle line is identical to the source indicator data (DetrendIndicator) i.e. Buffer 0 data rather than the intended Moving Average 10 (Buffer 1) I expected. The Upper and Lower Bands do not appear.

  I hope the changes I made have not deviated from what I was expected to do and I ask if it is possible to guide me to achieving this indicator plotting the MA of the source indicator data and the upper and lower bands.

  Applying Bollinger Bands to any of several indicators in a separate window can be very useful.  If we can get this working properly, changing the source indicator name/properties would only required for this to be a very good indicator.


#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property indicator_separate_window

#property indicator_color1    Lime
#property indicator_color2    Tomato
#property indicator_color3    Orange

double data[], middle[], upper[], lower[]; // all lower case
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(4);
   SetIndexBuffer (0, data);
   SetIndexBuffer (1, middle);
   SetIndexBuffer (2, upper);
   SetIndexBuffer (3, lower);
   
   SetIndexStyle (1, DRAW_LINE);
   SetIndexStyle (2, DRAW_LINE);
   SetIndexStyle (3, DRAW_LINE);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() { return(0);}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
 
   int pos, indicator_counted;
   
   // collecting data
   for (pos = Bars - indicator_counted - 1; pos >= 0; pos --)
      {
      data [pos] = iCustom(NULL, 0, "DetrendIndicator", 10, true, 0, pos); // changed Data to data
      }
   
   // creating middle band  
   for (pos = Bars - indicator_counted - 1; pos >= 0; pos --)
      {
      middle [pos] = iMAOnArray (data, 0,10,0,MODE_SMA, pos); // changed Middle to middle
      }
   
   // creating upper/lower band
   for (pos = Bars - indicator_counted - 1; pos >= 0; pos --)
      {
      upper [pos] = iBandsOnArray (data, 0, 10,2,0, MODE_UPPER , pos); //changed Upper to upper
      lower [pos] = iBandsOnArray (data, 0, 10,2,0, MODE_LOWER , pos); // changed Lower to lower
      }
   
   indicator_counted = IndicatorCounted();
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
NewtonLeo:
  I have tried many combinations to get this working (and I am learning new things).

  Changed the upper to lower case for "Data", "Upper", "Middle" and "Lower"  to agree with defined doubles (in lower case) below the properties.

  Read in docs.mql4 that "Bars" means all if 0 is used and  I experimented to find what was needed to substitute the "..." with to get it to compile properly.  I guess I got this wrong but it compiles without errors.

  The result is the middle line is identical to the source indicator data (DetrendIndicator) i.e. Buffer 0 data rather than the intended Moving Average 10 (Buffer 1) I expected. The Upper and Lower Bands do not appear.

  I hope the changes I made have not deviated from what I was expected to do and I ask if it is possible to guide me to achieving this indicator plotting the MA of the source indicator data and the upper and lower bands.

  Applying Bollinger Bands to any of several indicators in a separate window can be very useful.  If we can get this working properly, changing the source indicator name/properties would only required for this to be a very good indicator.


Aha, good one NewtonLeo,

The other lines are not showing because we (actually I) forget to define number of buffer property. And lets make the data also show it self, so you don't have to attach your DeTrend Indicator and then attach the  BB for DeTrend Indicator.

Again I haven't test this yet but yours is compiled and that's good.

Don't forget to manually compare this with your DeTrend Indicator and BB Previous Indicator Data especially on live tick. 

#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property indicator_separate_window

#property indicator_buffers   4       // this is will make all lines showing up
#property indicator_color1    Yellow  // added line
#property indicator_color2    Lime
#property indicator_color3    Tomato
#property indicator_color4    Orange

// extern input                       // some inputs
extern string CI_Name = "DetrendIndicator";
extern int    DeTrend_Period = 10;
extern int    DeTrend_True = true;
// ..................................... and add some input for MA and BB here     

double data[], middle[], upper[], lower[]; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   //IndicatorBuffers(4);          // let's not use it anymore because ....
   SetIndexBuffer (0, data);       // ... we're going to show ...
   SetIndexBuffer (1, middle);
   SetIndexBuffer (2, upper);
   SetIndexBuffer (3, lower);
   
   SetIndexStyle (0, DRAW_LINE);   // ... DeTrend CI without attaching one.  :)
   SetIndexStyle (1, DRAW_LINE);
   SetIndexStyle (2, DRAW_LINE);
   SetIndexStyle (3, DRAW_LINE);
   
   SetIndexLabel (0, "Data");      // All of this ...
   SetIndexLabel (1, "Middle");    // ... will make ...
   SetIndexLabel (2, "Upper");     // ... the data of all lines ...
   SetIndexLabel (3, "Lower");     // ... show in MT4 Data Window (Ctrl + D)
   
   string name = WindowExpertName();  
   IndicatorShortName (name+" "+DeTrend_Period+" "+DeTrend_True);   // some displayed name
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() { return(0);}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
 
   int pos, indicator_counted;
   
   // collecting data
   for (pos = Bars - indicator_counted; pos >= 0; pos --)
      {
      data [pos] = iCustom(NULL, 0, CI_Name, DeTrend_Period, DeTrend_True, 0, pos); // Put the input in iCustom input parameter
      }
   
   // creating middle band  
   for (pos = Bars - indicator_counted; pos >= 0; pos --)
      {
      middle [pos] = iMAOnArray (data, 0,10,0,MODE_SMA, pos); 
      }
   
   // creating upper/lower band
   for (pos = Bars - indicator_counted; pos >= 0; pos --)
      {
      upper [pos] = iBandsOnArray (data, 0, 10,2,0, MODE_UPPER , pos); 
      lower [pos] = iBandsOnArray (data, 0, 10,2,0, MODE_LOWER , pos); 
      }
   
   indicator_counted = IndicatorCounted() - 1;  // change it a little does not really matter
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
phi.nuts:


Aha, good one NewtonLeo,

The other lines are not showing because we (actually I) forget to define number of buffer property. And lets make the data also show it self, so you don't have to attach your DeTrend Indicator and then attach the  BB for DeTrend Indicator.

Again I haven't test this yet but yours is compiled and that's good.

Don't forget to manually compare this with your DeTrend Indicator and BB Previous Indicator Data especially on live tick. 

 



Thanks very much phi.nuts.  This is encouraging for me that I wasn't so poor at implementing your code.  I will get right onto this advanced version and feed back.  Many thanks for your patience.

extern int    DeTrend_True = true;    Should this be extern bool DeTrend_True = true; ??
Update: On first run, it faithfully created the DeTrend perfectly. But none of the BollingerBands were present.  I changed the extern int to extern bool in case that was the problem but it did not bring the bans to show. 

... and then I spotted an error of mine and IT WORKS!!!!!  Thankyou so much.
 
NewtonLeo:

Thanks very much phi.nuts.  This is encouraging for me that I wasn't so poor at implementing your code.  I will get right onto this advanced version and feed back.  Many thanks for your patience.

Update: On first run, it faithfully created the DeTrend perfectly. But none of the BollingerBands were present.  I changed the extern int to extern bool in case that was the problem but it did not bring the bans to show. 

... and then I spotted an error of mine and IT WORKS!!!!!  Thankyou so much.

Congrats,

Yes it should be bool - according to your DeTrend Indicator, not int. I copy pasted from DeTrend_Period :(.  

 
phi.nuts:

Congrats,

Yes it should be bool - according to your DeTrend Indicator, not int. I copy pasted from DeTrend_Period :(.  

phi.nuts, thank you for your patience with me. I have learned a new thing thanks to you.  It was easy for me to do the same thing with a different indicator now that I understand the principle.  All very much appreciated.
Reason: