Invalid Array Range in Indicator

 

Hi,

can someone try and run this code?

It's meant to show which of the bollinger bands are currently being touched by the price.


It doesn't run on my MT4 v4 build 890 running on WIne on LinuxMint. No Syntax errors.


The problem appears to be a status when debugging showing that buff5[i] and ExtMovingBuffer[i] both are "Invalid Array Range". Preceding buff1[] to buff4[] work fine but these two...not.


It actually falls over at first assignment within OnCalculate(). You can see at the if statement below text "//first time round?" it falls at buff5[i]=0; I have tried moving the position of the code further down, but it always fails on buff5[i] and ExtMovingBuffer[i].

thanks for any tips


//Breaks BB into 6 zones shows in which zones the price has touched.


#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum -4
#property indicator_maximum 4


#include <MovingAverages.mqh>
#property indicator_buffers 6
#property indicator_color1 clrMediumTurquoise   
#property indicator_color2 clrMediumTurquoise
#property indicator_color3 clrRed
#property indicator_color4 clrMediumTurquoise
#property indicator_color5 clrPink
#property indicator_color6 clrMediumTurquoise   

//--- indicator parameters
input int    InpBandsPeriod=20;      // Bands Period
input int    InpBandsShift=0;        // Bands Shift
input double InpBands_Outer_Deviations=2; // Bands Deviations
input double InpBands_Inner_Deviations=1.5; // Bands Deviations

//--- buffers
double buff0[];//display buffers
double buff1[];//display buffers
double buff2[];//display buffers
double buff3[];//display buffers
double buff4[];//display buffers
double buff5[];//display buffers

double ExtMovingBuffer[];//BB calc basis
double ExtStdDevBuffer[];//BB calc basis

bool on=1;
bool off=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   IndicatorShortName("_Bands_Zoned");
   IndicatorDigits(Digits);
//--- indicator buffers mapping
   SetIndexBuffer(1,buff0);
   SetIndexBuffer(2,buff1);
   SetIndexBuffer(3,buff2);
   SetIndexBuffer(4,buff3);
   SetIndexBuffer(5,buff4);
   SetIndexBuffer(6,buff5);

   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexStyle(4,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexStyle(5,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexStyle(6,DRAW_HISTOGRAM,STYLE_SOLID,3);

//--- check for input parameter
   if(InpBandsPeriod<=0)
     {
      Print("Wrong input parameter Bands Period=",InpBandsPeriod);
      return(INIT_FAILED);
     }
//--- check for input parameter
   if(InpBandsPeriod<=0)
     {
      Print("Wrong input parameter Bands Period=",InpBandsPeriod);
      return(INIT_FAILED);
     }
//---
   SetIndexDrawBegin(1,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(2,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(3,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(4,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(5,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(6,InpBandsPeriod+InpBandsShift);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {

   int i=0,pos=0;
   double BBUO=0,BBUI=0,BBLI=0,BBLO=0;

//--- counting from 0 to rates_total
   if(rates_total<=InpBandsPeriod || InpBandsPeriod<=0)
      return(0);

//---  Set Array 
   IndicatorBuffers(12);
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(ExtMovingBuffer,false);
   ArraySetAsSeries(ExtStdDevBuffer,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(buff0,false);
   ArraySetAsSeries(buff1,false);
   ArraySetAsSeries(buff2,false);
   ArraySetAsSeries(buff3,false);
   ArraySetAsSeries(buff4,false);
   ArraySetAsSeries(buff5,false);
   ArraySetAsSeries(close,false);

//first time round?   
   if(prev_calculated<1)
     {
      buff5[i]=on;
      ExtMovingBuffer[i]=0; 
      buff0[i]=on;
      buff1[i]=on;
      buff2[i]=on;
      buff3[i]=on;
      buff4[i]=on;

     }

//--- starting calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;

   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      //--- middle line
      ExtMovingBuffer[i]=SimpleMA(i,InpBandsPeriod,close);
      //--- calculate and write down StdDev
      ExtStdDevBuffer[i]=StdDev_Func(i,close,ExtMovingBuffer,InpBandsPeriod);
      //--- load the array with the current BB values 
      //--- upper outer line
      BBUO=ExtMovingBuffer[i]+InpBands_Outer_Deviations*ExtStdDevBuffer[i];
      //--- upper inner 
      BBUI=ExtMovingBuffer[i]+InpBands_Inner_Deviations*ExtStdDevBuffer[i];
      //--- lower inner       
      BBLI=ExtMovingBuffer[i]-InpBands_Inner_Deviations*ExtStdDevBuffer[i];
      //--- lower outer 
      BBLO=ExtMovingBuffer[i]-InpBands_Outer_Deviations*ExtStdDevBuffer[i];
      //---
     }

//--- set the display buffers

   if(high[i]<BBUO) buff0[i]=off;//top down leaving the bottom one alone
   if(high[i]<BBUI) buff1[i]=off;
   if(high[i]<ExtMovingBuffer[i]) buff2[i]=off;
   if(high[i] < BBLI) buff3[i]=off;
   if(high[i] < BBLO) buff4[i]=off;

   if(low[i]>BBLO) buff4[i]=off;//bottom up leaving the top one alone
   if(low[i]>BBLI) buff3[i]=off;
   if(low[i]<ExtMovingBuffer[i]) buff2[i]=off;
   if(low[i] < BBUI) buff1[i]=off;
   if(low[i] > BBUO) buff0[i]=off;




   return(rates_total);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Calculate Standard Deviation                                     |
//+------------------------------------------------------------------+
double StdDev_Func(int position,const double &price[],const double &MAprice[],int period)
  {
//--- variables
   double StdDev_dTmp=0.0;
//--- check for position
   if(position>=period)
     {
      //--- calcualte StdDev
      for(int i=0; i<period; i++)
         StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);
      StdDev_dTmp=MathSqrt(StdDev_dTmp/period);
     }
//--- return calculated value
   return(StdDev_dTmp);
  }
//+------------------------------------------------------------------+
 



Screenshot of my debugger window.




appress:

Hi,

can someone try and run this code?

It's meant to show which of the bollinger bands are currently being touched by the price.


It doesn't run on my MT4 v4 build 890 running on WIne on LinuxMint. No Syntax errors.


The problem appears to be a status when debugging showing that buff5[i] and ExtMovingBuffer[i] both are "Invalid Array Range". Preceding buff1[] to buff4[] work fine but these two...not.


It actually falls over at first assignment within OnCalculate(). You can see at the if statement below text "//first time round?" it falls at buff5[i]=0; I have tried moving the position of the code further down, but it always fails on buff5[i] and ExtMovingBuffer[i].

thanks for any tips


 
appress
this is an updated version, only using two buffers, this time only one buffer works and two do not, presenting same error.
//+------------------------------------------------------------------+
//|                                                 _Bands_Zoned.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
//Breaks BB into 6 zones shows in which zones the price has touched.


#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum -4
#property indicator_maximum 4


#include <MovingAverages.mqh>
#property indicator_buffers 2
#property indicator_color1 clrMediumTurquoise   
#property indicator_color2 clrMediumTurquoise


//--- indicator parameters
input int    InpBandsPeriod=20;      // Bands Period
input int    InpBandsShift=0;        // Bands Shift
input double InpBands_Outer_Deviations=2; // Bands Deviations
input double InpBands_Inner_Deviations=1.5; // Bands Deviations

//--- buffers two of em
double buff0[];//display buffers
double buff1[];//display buffers


double ExtMovingBuffer[];//BB calc basis
double ExtStdDevBuffer[];//BB calc basis

double BBUX=3,BBUO=2,BBUI=1,BBLI=-1,BBLO=-2,BBLX=-3;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   IndicatorShortName("_Bands_Zoned");
   IndicatorDigits(Digits);
//--- indicator buffers mapping
   SetIndexBuffer(1,buff0);
   SetIndexBuffer(2,buff1);

   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,3);

//--- check for input parameter
   if(InpBandsPeriod<=0)
     {
      Print("Wrong input parameter Bands Period=",InpBandsPeriod);
      return(INIT_FAILED);
     }
//--- check for input parameter
   if(InpBandsPeriod<=0)
     {
      Print("Wrong input parameter Bands Period=",InpBandsPeriod);
      return(INIT_FAILED);
     }
//---
   SetIndexDrawBegin(1,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(2,InpBandsPeriod+InpBandsShift);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {

   int i=0,pos=0;
   double iBBUO=0,iBBUI=0,iBBLI=0,iBBLO=0;

//--- counting from 0 to rates_total
   if(rates_total<=InpBandsPeriod || InpBandsPeriod<=0)
      return(0);

//---  Set Array 
   IndicatorBuffers(12);
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(ExtMovingBuffer,false);
   ArraySetAsSeries(ExtStdDevBuffer,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(buff0,false);
   ArraySetAsSeries(buff1,false);
   ArraySetAsSeries(close,false);

//first time round?   
   if(prev_calculated<1)
     {

      ExtMovingBuffer[i]=0;
      buff0[i]=0;
      buff1[i]=0;


     }

//--- starting calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;

   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      //--- middle line
      ExtMovingBuffer[i]=SimpleMA(i,InpBandsPeriod,close);
      //--- calculate and write down StdDev
      ExtStdDevBuffer[i]=StdDev_Func(i,close,ExtMovingBuffer,InpBandsPeriod);
      //--- load the array with the current BB values 
      //--- upper outer line
      iBBUO=ExtMovingBuffer[i]+InpBands_Outer_Deviations*ExtStdDevBuffer[i];
      //--- upper inner 
      iBBUI=ExtMovingBuffer[i]+InpBands_Inner_Deviations*ExtStdDevBuffer[i];
      //--- lower inner       
      iBBLI=ExtMovingBuffer[i]-InpBands_Inner_Deviations*ExtStdDevBuffer[i];
      //--- lower outer 
      iBBLO=ExtMovingBuffer[i]-InpBands_Outer_Deviations*ExtStdDevBuffer[i];
      //---
     }

//--- set the display buffers

//top down leaving the bottom one alone
   if(high[i]<iBBUO)
     {
      if(high[i]<iBBUI)
        {
         if(high[i]<ExtMovingBuffer[i])
           {
            if(high[i]<iBBLI)
              {
               if(high[i]<iBBLO)
                 {
                  buff0[i]=BBLX;
                 }
               else
                 {
                  buff0[i]=BBLO;
                 }
              }
            else
              {
               buff0[i]=BBLI;
              }
           }
         else
           {
            buff0[i]=BBUI;
           }
        }
      else
        {
         buff0[i]=BBUO;
        }
     }
   else
     {
      buff0[i]=BBUX;
     }


//bottom up leaving the top one alone
   if(low[i]>iBBLO)
     {
      if(low[i]>iBBLI)
        {
         if(low[i]>ExtMovingBuffer[i])
           {
            if(low[i]>iBBUI)
              {
               if(low[i]>iBBUO)
                 {
                  buff1[i]=BBUX;
                 }
               else
                 {
                  buff1[i]=BBUO;
                 }
              }
            else
              {
               buff1[i]=BBUI;
              }
           }
         else
           {
            buff1[i]=BBLI;
           }
        }
      else
        {
         buff1[i]=BBLO;
        }
     }
   else
     {
      buff1[i]=BBLX;
     }





   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Calculate Standard Deviation                                     |
//+------------------------------------------------------------------+
double StdDev_Func(int position,const double &price[],const double &MAprice[],int period)
  {
//--- variables
   double StdDev_dTmp=0.0;
//--- check for position
   if(position>=period)
     {
      //--- calcualte StdDev
      for(int i=0; i<period; i++)
         StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);
      StdDev_dTmp=MathSqrt(StdDev_dTmp/period);
     }
//--- return calculated value
   return(StdDev_dTmp);
  }
//+------------------------------------------------------------------+
 
#property indicator_buffers 6
//--- indicator buffers mapping
   SetIndexBuffer(1,buff0);
   SetIndexBuffer(2,buff1);
   SetIndexBuffer(3,buff2);
   SetIndexBuffer(4,buff3);
   SetIndexBuffer(5,buff4);
   SetIndexBuffer(6,buff5);

Set the buffers numbered 0 to 5, not 1 to 6

double ExtMovingBuffer[];//BB calc basis
double ExtStdDevBuffer[];//BB calc basis

 These are declared, but are not sized or set as buffers

 
GumRai:

Set the buffers numbered 0 to 5, not 1 to 6

 These are declared, but are not sized or set as buffers

Hi Thanks very much GumRai, the first,

"Set the buffers numbered 0 to 5, not 1 to 6, "


is clear and have made the necessary changes. Second one


" These are declared, but are not sized or set as buffers"

I believe that as I do not want to show the actual values of MovBuffer and StdBuffer on the chart there is no need to declare as buffers. So this leaves me to resize... wip..will edit later


Here's latest code

 
appress:


I believe that as I do not want to show the actual values of MovBuffer and StdBuffer on the chart there is no need to declare as buffers. So this leaves me to resize. Tried ArrayResize() but while a step in the right direction, it doesn't show anything.

You can set more buffers, so you might as well set them as buffers as it is much easier than keep shifting values in arrays

Set style to DRAW_NONE and label to NULL, then they won't appear on the chart. 

 
GumRai:

You can set more buffers, so you might as well set them as buffers as it is much easier than keep shifting values in arrays

Set style to DRAW_NONE and label to NULL, then they won't appear on the chart. 

ok will try, I was so unsure about everything in my program, that I preferred to keep them out, but will note this for future...

Reason: