//+------------------------------------------------------------------+
//|                                                    zerolagMA.mq4 |
//|                                    Copyright © 2010, Robert Hill |
//|                                                                  |
//|  Based on an article in TASC , November 2010 : pg 30 - 35        |
//|  by John Ehlers and Ric Way                                      |
//|  Translated from Easy Language code                              |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Robert Hill"


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 White
#property indicator_width1 2

#property indicator_color2 Red
#property indicator_width2 2


//---- input parameters
extern int     Length         = 10;
extern int     GainLimit = 50;
extern bool    ShowEMA = true;

double alpha = 0;
double Gain = 0;
double BestGain = 0;
double EX = 0;
double Error = 0;
double LeastError = 0;
double EMA = 0;
double EC = 0;


//---- indicator buffers
double EMABuffer[];
double ECBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
  int init()
  {
   string short_name;
//---- indicator line
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,EMABuffer);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ECBuffer);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
   short_name="ZeroLagDot("+Length+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,"EMA");
   SetIndexLabel(1,"ZLEMA");
//----

   alpha = 2.0/(Length + 1);
   return(0);
  }

//+------------------------------------------------------------------+
//| NonLagMA_v1                                                      |
//+------------------------------------------------------------------+
int start()
{
   int    i,shift, counted_bars=IndicatorCounted(),limit;
   
   
   if ( counted_bars > 0 )  limit=Bars-counted_bars;
   if ( counted_bars < 0 )  return(0);
   if ( counted_bars == 0 )  limit=Bars-Length-1; 
   if ( counted_bars < 1 ) 
   for(i=1;i<Length;i++) 
   {
   ECBuffer[Bars-i]=0;    
   }
   
   for(shift=limit;shift>=0;shift--) 
   {	
       
//      EMA = alpha * Close[shift] + (1.0 - alpha) * EMA;
      EMA = iMA(NULL, 0, Length, 0, MODE_EMA, PRICE_CLOSE, shift);
      if (ShowEMA) EMABuffer[shift] = EMA;
      LeastError = 1000000;
      for (i=-GainLimit;i<=GainLimit;i++)
	   { 
         Gain = i / 10.0;
         EC = alpha * (EMA + Gain * (Close[shift] - ECBuffer[shift+1])) + (1 - alpha) * ECBuffer[shift + 1];
         Error = Close[shift] - EC;
         if (MathAbs(Error) < LeastError)
         {
            LeastError = MathAbs(Error);
            BestGain = Gain;
         }
      }
      
      ECBuffer[shift] = alpha * (EMA + BestGain * (Close[shift] - ECBuffer[shift+1])) + (1 - alpha) * ECBuffer[shift+1];
   }
	return(0);	
}

