//+------------------------------------------------------------------+
//|                                         Ehlers non linear filter |
//|                                                                  |
//| original described in TASC 2001 volume 4                         |
//+------------------------------------------------------------------+
#property copyright "www.forex-tsd.com"
#property link      "www.forex-tsd.com"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  DeepSkyBlue
#property indicator_width1  2

//
//
//
//
//

extern int Length   = 20;
extern int Momentum =  5;
extern int Price    = PRICE_CLOSE;

//
//
//
//
//

double filter[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init() { SetIndexBuffer(0,filter); return(0); }
int start()
{
   int counted_bars = IndicatorCounted();
   int i,limit;

      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
           limit = MathMin(Bars-counted_bars,Bars-1);

   //
   //
   //
   //
   //
   
   for(i=limit; i>=0; i--) filter[i] = iEhlers(iMA(NULL,0,1,0,MODE_SMA,Price,i),Length,Momentum,0,i);
   return(0);
}



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

double  enlf_work[][1];

//
//
//
//
//

double  iEhlers(double price,int length, int momentumLength, int s, int i)
{   
   if (ArrayRange(enlf_work,0)!=Bars) ArrayResize(enlf_work,Bars);
   
   int r = Bars-i-1;
   
   //
   //
   //
   //
   //
      
      enlf_work[r][s] = price;

      double sumCoef = 0;
      double num     = 0;
         for (int k=0; k<length; k++)
         {
            double coeff    = MathAbs(enlf_work[r-k][s]-enlf_work[r-k-momentumLength][s]);
                   sumCoef += coeff;
                   num     += coeff*enlf_work[r-k][s];
         } 
      if (sumCoef !=0)
            return(num/sumCoef);
      else  return(0);       
}