//https://forex-station.com/viewtopic.php?f=579495&p=1295478867#p1295478867
//https://www.mql5.com/en/forum/179991/page17#comment_4431431
//+------------------------------------------------------------------+
//|                                      fractal - channel histo.mq5 |
//+------------------------------------------------------------------+
#property copyright "www.forex-station.com"
#property link      "www.forex-station.com"

#property indicator_separate_window
#property indicator_height  21
#property indicator_buffers 2
#property indicator_plots   1
#property indicator_label1  "Fractal channel histo"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrDimGray,clrBlue,clrYellow
#property indicator_width1  3
#property indicator_minimum 0
#property indicator_maximum 1

//
//
//

input int FractalPeriod = 15;    // Fractals period

double histo[],histoc[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------
void OnInit()
{
   SetIndexBuffer(0,histo,INDICATOR_DATA);
   SetIndexBuffer(1,histoc,INDICATOR_COLOR_INDEX);
}
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[])
{
   //
   //
   //
   
   struct sFrStruct
   {
      double v1;
      double v2;
   };
   static sFrStruct wrk[];
   static int        wrkSize = -1;
                 if (wrkSize<rates_total) wrkSize = ArrayResize(wrk,rates_total+500);
   
   //
   //
   //
   
   int k,half = FractalPeriod/2; double compareTo;
   for (int i=(int)fmax(prev_calculated-half,half); i<rates_total && !_StopFlag; i++)
   {
         compareTo = high[i];
            for (k=1;k<=half && (i+k)<rates_total ;k++)
            {
               if (high[i+k]> compareTo) break;
               if (high[i-k]>=compareTo) break;
            }
            double frUp = (k==half+1) ? high[i] : EMPTY_VALUE;
         compareTo = low[i];
            for (k=1;k<=half && (i+k)<rates_total ;k++)
            {
               if (low[i+k]< compareTo) break;
               if (low[i-k]<=compareTo) break;
            }
            double frDn = (k==half+1) ? high[i] : EMPTY_VALUE;
         
            //
            //
            //
         
            wrk[i].v1 = (frUp != EMPTY_VALUE) ? high[i] : (i>0) ? wrk[i-1].v1 : high[i]; 
            wrk[i].v2 = (frDn != EMPTY_VALUE) ?  low[i] : (i>0) ? wrk[i-1].v2 :  low[i];
            histo[i]  = 1;    
            histoc[i] = (close[i]>wrk[i].v1) ? 1 :(close[i]<wrk[i].v2) ? 2 :0;
   }  
   return(rates_total);
}