Custom Indicator showing ZERO level, though not defined anywhere in the code

 

Custom Indicator showing ZERO level, though not defined anywhere in the code

  #property description "Bollinger %b Indicator"
//+----------------------------------------------------------------------------------------------------------+
//| Define Input Parameters
//+----------------------------------------------------------------------------------------------------------+
  input group "iBand Indicator Parameters"
  input int               BB_Period = 21;       // Bollinger Middle Averaging Period
  input int               BB_Shift  = 0;        // Horizontal Shift
  input double            BB_Deviation = 2.0;   // 
//+----------------------------------------------------------------------------------------------------------+
//| Define Indicator Properties
//+----------------------------------------------------------------------------------------------------------+
  #property indicator_separate_window
  #property indicator_buffers 3
  #property indicator_plots   1
//+----------------------------------------------------------------------------------------------------------+
//| Define Indicator Handle(s) and Buffer(s)
//+----------------------------------------------------------------------------------------------------------+
  int       hBollinger;
  double    bBBPercentB[];
//+--------------------------------------------------------------------------------------------------------+
//| Define Indicator Calculation Array(s) and Variable(s)
//+--------------------------------------------------------------------------------------------------------+
  double    aBBUpper[];
  double    aBBLower[];
//+----------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function
//+----------------------------------------------------------------------------------------------------------+
int OnInit()
{
  //+--------------------------------------------------------------------------------------------------------+
  //| Functions for Indicator SubWindow properties (used instead of #property)
  //+--------------------------------------------------------------------------------------------------------+
    //--- Common Indicator Properties
    IndicatorSetString(INDICATOR_SHORTNAME,"iFx %b BB ("+(string)BB_Period+") period ");
    IndicatorSetInteger(INDICATOR_DIGITS,_Digits);            // Sets required accuracy of display of indicator values
    //--- Indicator Height, Min and Max values
    IndicatorSetInteger(INDICATOR_HEIGHT,150);                 // The fixed value of the subwindow height
    //--- Indicator Levels Properties
    IndicatorSetInteger(INDICATOR_LEVELS,3);                 // Sets No of levels in the indicator window
    IndicatorSetDouble(INDICATOR_LEVELVALUE,0,0.8);          // Vertical axis value for N1 level
    IndicatorSetDouble(INDICATOR_LEVELVALUE,1,0.5);          // Vertical axis value for N2 level
    IndicatorSetDouble(INDICATOR_LEVELVALUE,2,0.2);          // Vertical axis value for N3 level
  //+--------------------------------------------------------------------------------------------------------+
  //| Functions for Plotting Indicator Lables in SubWindow (used instead of #property)
  //+--------------------------------------------------------------------------------------------------------+
    PlotIndexSetString(0,PLOT_LABEL,"%b (BB)");              // Short name of the number N plot. It is displayed in DataWindow and in the pop-up tooltip when pointing the mouse cursor over it
    PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);         // Line type for N plot
    PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);      // Line style for N plot
    PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrGoldenrod);     // Line color for N plot
    PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);                // Line width for N plot
    PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,BB_Period);        // Number of initial bars without drawing and values in the DataWindow
    PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);      // An empty value for plotting, for which there is no drawing
  //+--------------------------------------------------------------------------------------------------------+
  //| Set and Plot Indicator Buffers binding with declared array, in which we will store the values of data
  //+--------------------------------------------------------------------------------------------------------+
    SetIndexBuffer(0,bBBPercentB,INDICATOR_DATA);
    SetIndexBuffer(1,aBBUpper,INDICATOR_CALCULATIONS);
    SetIndexBuffer(2,aBBLower,INDICATOR_CALCULATIONS);
  //+--------------------------------------------------------------------------------------------------------+
  //| Indicator Plot Mapping ...
  //+--------------------------------------------------------------------------------------------------------+
    PlotIndexSetDouble(0,PLOT_EMPTY_VALUE, EMPTY_VALUE);
  //+--------------------------------------------------------------------------------------------------------+
  //| Indicator Properties
  //+--------------------------------------------------------------------------------------------------------+
    IndicatorSetString(INDICATOR_SHORTNAME,"iFx %b Bollinger ("+(string)BB_Period+") period ");
    IndicatorSetInteger(INDICATOR_DIGITS,Digits());
  //+--------------------------------------------------------------------------------------------------------+
  //| Indicator Levels
  //+--------------------------------------------------------------------------------------------------------+
    IndicatorSetInteger(INDICATOR_LEVELS,2);
    IndicatorSetInteger(INDICATOR_LEVELCOLOR,clrSilver);
    IndicatorSetInteger(INDICATOR_LEVELSTYLE,STYLE_DOT);
    IndicatorSetDouble(INDICATOR_LEVELVALUE,0,0.8);
    IndicatorSetDouble(INDICATOR_LEVELVALUE,1,0.2);
  //+--------------------------------------------------------------------------------------------------------+
  //| Define and Initialize Indicator Handles ...
  //+--------------------------------------------------------------------------------------------------------+
    hBollinger = iBands(_Symbol,PERIOD_CURRENT,BB_Period,BB_Shift,BB_Deviation,PRICE_CLOSE);
    if(hBollinger < 0)
      {
        Print(__LINE__,"Error creating hBollinger, code ",GetLastError()); return(INIT_FAILED);
      }
  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       start_Position = 0;
    int       limit = rates_total - prev_calculated;
  //+--------------------------------------------------------------------------------------------------------+
  //| Set Indicator Buffers / Arrays as Timeseries ...
  //+--------------------------------------------------------------------------------------------------------+
    ArraySetAsSeries(bBBPercentB,true);
    ArraySetAsSeries(aBBUpper,true);
    ArraySetAsSeries(aBBLower,true);
  //+--------------------------------------------------------------------------------------------------------+
  //| Indicator Buffers Initialize  ...
  //+--------------------------------------------------------------------------------------------------------+
    ArrayInitialize(bBBPercentB,EMPTY_VALUE);
    ArrayInitialize(aBBUpper,0);
    ArrayInitialize(aBBLower,0);
  //+--------------------------------------------------------------------------------------------------------+
  //| Indicator Data preparation ... Check all data calculated and then copy them into calculation arrays
  //+--------------------------------------------------------------------------------------------------------+
    if(BarsCalculated(hBollinger) < rates_total) return(0);
      if(CopyBuffer(hBollinger,UPPER_BAND,start_Position,rates_total,aBBUpper) <= 0) return(rates_total);
      //if(CopyBuffer(hBollinger,BASE_LINE,start_Position,rates_total,aBBMiddle) <= 0) return(rates_total);
      if(CopyBuffer(hBollinger,LOWER_BAND,start_Position,rates_total,aBBLower) <= 0) return(rates_total);
  //+--------------------------------------------------------------------------------------------------------+
  //| Indicator Main Loop ... additionally PercentB can be converted into Points by dividing Get_Points!!!
  //+--------------------------------------------------------------------------------------------------------+
    for(int i = start_Position; i < (rates_total - 1) && !IsStopped(); i++)
    {
      if((aBBUpper[i] - aBBLower[i]) != 0)
      {
        double barClose = iClose(_Symbol,PERIOD_CURRENT,i);
        bBBPercentB[i]  = NormalizeDouble((barClose - aBBLower[i]) / (aBBUpper[i] - aBBLower[i]),_Digits);
        //Print("BB %b ",bBBPercentB[i]);
      }
    //Print("Index [",i,"] PercentB ",bBBPercentB[i]," || Upper Band ",aBBUpper[i]," || Close Price ",barClose," || Lower Band ",aBBLower[i]);
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+----------------------------------------------------------------------------------------------------------+
 
It seems an MT5 feature without any way to disable or customize it.
 

Actually it's buggy, as this automatic 0 line doesn't respect what is defined in the code (style, color...).


 

It might be related to setting the number of indicator levels twice in OnInit() — first

IndicatorSetInteger(INDICATOR_LEVELS,3);                 // Sets No of levels in the indicator window

and then

    IndicatorSetInteger(INDICATOR_LEVELS,2);

Perhaps one is left orphaned instead of being deleted.

 

As designed. It is not level. It is grid.

Because it is important to see pass from + to - and vice versa

 
Fixed. "level 0" will not be appeared if grid is switched off
 
Ilyas #:
Fixed. "level 0" will not be appeared if grid is switched off
Thank you.
 
Slava #:

As designed. It is not level. It is grid.

Because it is important to see pass from + to - and vice versa

As a grid its should be in the background and not disable or hide a level.

An explicitly defined level 0 should have priority to a grid, see the screenshot, the indicator level 0 is not shown at all.

So beside the bug fixed as Ilyas reported, there is an other bug when the grid is on.


 
Alain Verleyen #:

As a grid its should be in the background and not disable or hide a level.

An explicitly defined level 0 should have priority to a grid, see the screenshot, the indicator level 0 is not shown at all.

So beside the bug fixed as Ilyas reported, there is an other bug when the grid is on.


Almost fixed in build 3191.

It remains a bug as I warned about it. To reproduce :

1 - On a chart, without a grid, attach the provided indicator. All is displayed correctly.


2 - Enable the grid. (CTRL+G or click on button...). The Level 0 line is NOT displayed. This is a bug. Disable the grid again, the level is shown.


The problem is the grid is not in the background. If you are using a dot line level it's BEHIND the grid, that's not correct. If you set a solid line it's shown as the grid can't mask it completely. A level should have priority on a grid.



Reason: