//+------------------------------------------------------------------+
//|                                                     Trending.mq5 |
//|                                      Copyright 2010, Grebenev V. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, Grebenev V."
#property description "Trending Indicator"
#property version   "1.00"
#property indicator_separate_window
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_SECTION
#property indicator_type3   DRAW_SECTION
#property indicator_color1  LightSeaGreen
#property indicator_color2  DarkGreen
#property indicator_color3  DarkGreen
#property indicator_label1  "TrendingOpen"

//--- input parameters N – number of bars, used in calculation of trend
input int      N=30;


double ExtTRbuffer[];   // indicator values
double ExtTRbufferP[];  // upper bound
double ExtTRbufferM[];  // lower bound
double average[150000]; // average values
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator digits
//   IndicatorSetInteger(INDICATOR_DIGITS,0);
//--- indicator short name
   IndicatorSetString(INDICATOR_SHORTNAME,"Trending Open");
//---- index buffer
   SetIndexBuffer(0,ExtTRbuffer);
   SetIndexBuffer(1,ExtTRbufferP);
   SetIndexBuffer(2,ExtTRbufferM);
//--- set index draw begin
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1);
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,1);
   PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,1);
//---- Array Initialization
   ArrayInitialize(ExtTRbuffer,0);
   ArrayInitialize(ExtTRbufferP,0);
   ArrayInitialize(ExtTRbufferM,0);
   ArrayInitialize(average,0);
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {

   double pp=0,pm=0,mp=0,mm=0; // pp - number pf "++" chains, pm - "+-", mp – "-+", mm – "--"

  // fill averages with Open prices
   for(int i=prev_calculated;i<rates_total;i++) average[i]=open[i];

   for(int i=prev_calculated;i<rates_total;i++)
     {
      pp=0; pm=0; mp=0; mm=0;

      for(int j=0;j<N;j++)
        {
         if(i-j-2>=0) // check array index (range check)
           {
            if((average[i-j-1]-average[i-j-2])>0 && (average[i-j]-average[i-j-1])>0) pp++;
            if((average[i-j-1]-average[i-j-2])>0 && (average[i-j]-average[i-j-1])<0) pm++;
            if((average[i-j-1]-average[i-j-2])<0 && (average[i-j]-average[i-j-1])>0) mp++;
            if((average[i-j-1]-average[i-j-2])<0 && (average[i-j]-average[i-j-1])<0) mm++;
            // we have omitted the chains with "0"
           }
        }
      // fill indicator arrays 
      ExtTRbuffer[i]=pp+mm-pm-mp;
      ExtTRbufferP[i]=sqrt(N);
      ExtTRbufferM[i]=-sqrt(N);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
