I want to make a very simple indicator to make a Spike Detector

 

This is what I have so far:

//+------------------------------------------------------------------+
//|                                              SpikeCalculator.mq5 |
//|                                        Guilherme Cunha Rodrigues |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright " Guilherme Cunha Rodrigues"
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Spikes
#property indicator_label1  "Up Spike"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLime
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
#property indicator_label2  "Down Spike"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters
input int InpDepth    =30;  // Depth
input double factor_k        =0.75; // factor k
//--- indicator buffers
double    HighMapBuffer[];     // Up Spike
double    LowMapBuffer[];      // Down Spike
double    handle_iATR;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,HighMapBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,LowMapBuffer,INDICATOR_DATA);
//--- set short name and digits
   string short_name=StringFormat("Spike (%d)",InpDepth);
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   PlotIndexSetString(0,PLOT_LABEL,short_name);
   PlotIndexSetString(1,PLOT_LABEL,short_name);
   IndicatorSetInteger(INDICATOR_DIGITS,5);
//--- set an empty value
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
//--- create handle of the indicator iATR
   handle_iATR=iATR(Symbol(),0,InpDepth);
//--- if the handle is not created
   if(handle_iATR==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iATR indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
     }
  }
//+------------------------------------------------------------------+
//|Spike calculation                                               |
//+------------------------------------------------------------------+
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[])
  {
   if(rates_total<InpDepth)
      return(0);
//---
   int    i=0;
   int    start=0;
   int    shift=InpDepth;
   double val=0;
   double last_high=0,last_low=0;
   double indATR[];
//--- initializing
   //--- verifica se todos os dados estão calculados
   if(BarsCalculated(handle_iATR)<rates_total) return(0);
//--- nós não podemos copiar todos os dados
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total;
   else
     {
      to_copy=rates_total-prev_calculated;
      //--- o último valor é sempre copiado
      to_copy++;
     }
//--- tenta copiar
   if(CopyBuffer(handle_iATR,0,0,to_copy,indATR)<=0) return(0);
   if(prev_calculated==0)
     {
      ArrayInitialize(HighMapBuffer,0.0);
      ArrayInitialize(LowMapBuffer,0.0);
      start=InpDepth;
     }
//--- searching for high and low extremes
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      Print(shift);
      //--- low
      val=low[Lowest(low,InpDepth,shift)];
      if(val==last_low)
         val=0.0;
      else
        {
         last_low=val;
         if((val-low[shift-1])>factor_k*indATR[shift-2] && low[shift]-low[shift-1]>factor_k*indATR[shift-2])
            LowMapBuffer[shift-1]=low[shift-1];
         else
           LowMapBuffer[shift-1]=0.0;
        }
      //--- high
      val=high[Highest(high,InpDepth,shift)];
      if(val==last_high)
         val=0.0;
      else
        {
         last_high=val;
         if((high[shift-1]-val)>factor_k*indATR[shift-2] && high[shift-1]-high[shift]>factor_k*indATR[shift-2])
           HighMapBuffer[shift-1]=high[shift-1];
         else
           HighMapBuffer[shift-1]=0.0;
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|  Search for the index of the highest bar                         |
//+------------------------------------------------------------------+
int Highest(const double &array[],const int depth,const int start)
  {
   if(start<0)
      return(0);

   double max=array[start];
   int    index=start;
//--- start searching
   for(int i=start-1; i>start-depth && i>=0; i--)
     {
      if(array[i]>max)
        {
         index=i;
         max=array[i];
        }
     }
//--- return index of the highest bar
   return(index);
  }
//+------------------------------------------------------------------+
//|  Search for the index of the lowest bar                          |
//+------------------------------------------------------------------+
int Lowest(const double &array[],const int depth,const int start)
  {
   if(start<0)
      return(0);

   double min=array[start];
   int    index=start;
//--- start searching
   for(int i=start-1; i>start-depth && i>=0; i--)
     {
      if(array[i]<min)
        {
         index=i;
         min=array[i];
        }
     }
//--- return index of the lowest bar
   return(index);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

Problems, nothing is drawn, error array out of range is showing all the time.


I want to put the following rule:

Spike = high[i-1] - highest(high,n)[i-2] > k*ATR(n)[i-2] && high[i-1] - high[i] > k*ATR(n)[i-2], vice-versa to low


More information:

 I debugged "shift" and it's calculating until 80830 than it turns 0, and  everything collapses.


Thanks for any suppport. I'm very new to mql5.