Bollinger bands based on EMA - custom indicator

 

Hi all, 


Can't seem to get this custom indicator to work. When I try to load it on MT5 nothing comes up at all. I've built some EAs but never made a custom indicator, honestly it could be something really basic that's wrong with my code. If anybody has any tips, I'd really appreciate it. Thanks


#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   3

//--- plot EMA
#property indicator_label1  "EMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- plot upperBB
#property indicator_label2  "upperBB"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//--- plot lowerBB
#property indicator_label3  "lowerBB"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

//--- input parameters
input int EMA = 50; //--Period
input double upperBB = 2.0; //--Upper BB standard deviation
input double lowerBB = 2.0; //--Lower BB standard deviation

//--global variables
int PlotBegin = 0;

//--- indicator buffers
double EMA_Buffer[];
double upperBB_Buffer[];
double lowerBB_Buffer[];
double Standard_Deviation_Buffer[];

void OnInit()
   {
//--- indicator buffers mapping
   SetIndexBuffer(0,EMA_Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,upperBB_Buffer,INDICATOR_DATA);
   SetIndexBuffer(2,lowerBB_Buffer,INDICATOR_DATA);
   SetIndexBuffer(3,Standard_Deviation_Buffer, INDICATOR_DATA);
   
   PlotIndexSetString(0, PLOT_LABEL, string(EMA)+(" EMA"));
   PlotIndexSetString(1, PLOT_LABEL, "upperBB");
   PlotIndexSetString(2, PLOT_LABEL, "lowerBB");
   
   IndicatorSetString(INDICATOR_SHORTNAME, "EMA Bollinger Bands");
   
   PlotBegin = EMA - 1;
   PlotIndexSetInteger(0, PLOT_LINE_COLOR,EMA);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR,EMA);
   PlotIndexSetInteger(2, PLOT_LINE_COLOR,EMA);   
   
   }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
   {  

   
//--- return value of prev_calculated for next call
   int pos;
   
   if(PlotBegin != EMA + begin)
      {
      PlotBegin = EMA + begin;  
      PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, PlotBegin);
      PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, PlotBegin);
      PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, PlotBegin);
      }
     
//--Check for bars count
   if(rates_total < PlotBegin)
      {
      return(0);
      }
      
   if(prev_calculated > 1)
      {
      pos = prev_calculated - 1;
      }
   else
      {
      pos = 0;
      }
       
//--calculate standard deviation, upperBB and lowerBB
   for(int i = 0; i < rates_total; i++)
      {
      EMA_Buffer[i] = iMA(_Symbol, PERIOD_CURRENT, EMA, i, 1, PRICE_CLOSE);
      Standard_Deviation_Buffer[i] = iStdDev(_Symbol, PERIOD_CURRENT, EMA, i, 1, PRICE_CLOSE);
      upperBB_Buffer[i] = EMA_Buffer[i] + (upperBB * Standard_Deviation_Buffer[i]);
      lowerBB_Buffer[i] = EMA_Buffer[i] - (lowerBB * Standard_Deviation_Buffer[i]);
      }
      
   return(rates_total);   
      
      
      
      
   }
 
  1.      EMA_Buffer[i] = iMA(_Symbol, PERIOD_CURRENT, EMA, i, 1, PRICE_CLOSE);
    

    Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. 2004
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick (after the indicator has updated its buffers,) you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 2020.03.08
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 2020.07.05
              How to call indicators in MQL5 - MQL5 Articles 12 March 2010

  2. int OnCalculate(const int rates_total,
                    const int prev_calculated,
                    const int begin,
                    const double &price[])]{  
       int pos;
       
       if(PlotBegin != EMA + begin)
          {
          PlotBegin = EMA + begin;  
          PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, PlotBegin);
    You alread set that in OnInit. Why are you setting it again?

  3.    for(int i = 0; i < rates_total; i++)
    Why are you computing all bars each tick?
              How to do your lookbacks correctly #9 - #14 & #19
 
William Roeder:
  1. Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. 2004
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick (after the indicator has updated its buffers,) you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 2020.03.08
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 2020.07.05
              How to call indicators in MQL5 - MQL5 Articles 12 March 2010

  2. You alread set that in OnInit. Why are you sett9ng it again?
  3. Why are you computing all bars each tick?
              How to do your lookbacks correctly #9 - #14 & #19 

I did not read anything from the first three links that you attached, but I'll look into the other stuff that you sent through. I see now that including the iMa and IStdDev functions in the OnCalculate section, and not including handles, was a pretty dumb mistake, thanks for pointing it out.

Reason: