//+------------------------------------------------------------------+
//|                                                 Zero_Lag_RSI.mq4 |
//|                               Copyright © 2015, Gehtsoft USA LLC |
//|                                            http://fxcodebase.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Gehtsoft USA LLC"
#property link      "http://fxcodebase.com"

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1  Green
#property indicator_color2  DarkGreen
#property indicator_color3  Red
#property indicator_color4  DarkRed

extern ENUM_TIMEFRAMES TimeFrame        = PERIOD_CURRENT;
extern int Smoothing1=15;
extern int Smoothing2=7;
extern double Factor1=0.05;
extern int RSI_Length1=8;
extern double Factor2=0.1;
extern int RSI_Length2=21;
extern double Factor3=0.16;
extern int RSI_Length3=34;
extern double Factor4=0.26;
extern int RSI_Length4=55;
extern double Factor5=0.43;
extern int RSI_Length5=89;
extern ENUM_APPLIED_PRICE Price=0;    // Applied price


double UU[], UD[], DU[], DD[];
double FastTrend[], SlowTrend[];
double SmoothConst1, SmoothConst2;
string indicatorFileName;
bool   returnBars;


int init()
{
 IndicatorBuffers(6);
 SetIndexBuffer(0,UU); SetIndexStyle(0,DRAW_HISTOGRAM);
 SetIndexBuffer(1,UD); SetIndexStyle(1,DRAW_HISTOGRAM);
 SetIndexBuffer(2,DU); SetIndexStyle(2,DRAW_HISTOGRAM);
 SetIndexBuffer(3,DD); SetIndexStyle(3,DRAW_HISTOGRAM);
 SetIndexBuffer(4,FastTrend);
 SetIndexBuffer(5,SlowTrend);
 
 SmoothConst1=(Smoothing1-1.)/Smoothing1;
 SmoothConst2=(Smoothing2-1.)/Smoothing2;
 indicatorFileName = WindowExpertName();
 returnBars        = TimeFrame==-99;
 TimeFrame         = MathMax(TimeFrame,_Period);
 IndicatorShortName(timeFrameToString(TimeFrame)+" ZeroLag RSI");

 return(0);
}

int deinit()
{

 return(0);
}

int start()
{
    int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
            int limit = MathMin(Bars - counted_bars,Bars-1);
            if (returnBars)  { UU[0] = limit+1; return(0); } 
            
    //
   //
   //
   //
   //

   if (TimeFrame == Period())
   {  
      for(int pos=limit; pos>=0; pos--) 
      {
      double RSI1 = iRSI(NULL,0,RSI_Length1,Price,pos);
      double RSI2 = iRSI(NULL,0,RSI_Length2,Price,pos);
      double RSI3 = iRSI(NULL,0,RSI_Length3,Price,pos);
      double RSI4 = iRSI(NULL,0,RSI_Length4,Price,pos);
      double RSI5 = iRSI(NULL,0,RSI_Length5,Price,pos);
  
      double Osc1=Factor1*RSI1;
      double Osc2=Factor1*RSI2;
      double Osc3=Factor1*RSI3;
      double Osc4=Factor1*RSI4;
      double Osc5=Factor1*RSI5;
  
      FastTrend[pos]=Osc1+Osc2+Osc3+Osc4+Osc5;
      SlowTrend[pos]=FastTrend[pos]/Smoothing1+SlowTrend[pos+1]*SmoothConst1;
      UU[pos]=(FastTrend[pos]-SlowTrend[pos])/(Smoothing2*Point)+UU[pos+1]*SmoothConst2;
      
      UD[pos]=EMPTY_VALUE;
      DU[pos]=EMPTY_VALUE;
      DD[pos]=EMPTY_VALUE;
  
      if (UU[pos]>0.)
      {
        if (UU[pos]<UU[pos+1])
      {
        UD[pos]=UU[pos];
   }
  }
  else
  {
   if (UU[pos]>UU[pos+1])
   {
    DU[pos]=UU[pos];
   }
   else
   {
    DD[pos]=UU[pos];
   }
  }
 } 
 return(0);
 }
 
 //
   //
   //
   //
   //
 
    limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/Period()));
    for(pos=limit; pos >= 0; pos--)  
    {
       int y = iBarShift(NULL,TimeFrame,Time[pos]);
          UU[pos] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Smoothing1,Smoothing2,Factor1,RSI_Length1,Factor2,RSI_Length2,Factor3,RSI_Length3,Factor4,RSI_Length4,Factor5,RSI_Length5,Price,0,y);
          UD[pos] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Smoothing1,Smoothing2,Factor1,RSI_Length1,Factor2,RSI_Length2,Factor3,RSI_Length3,Factor4,RSI_Length4,Factor5,RSI_Length5,Price,1,y); 
          DD[pos] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Smoothing1,Smoothing2,Factor1,RSI_Length1,Factor2,RSI_Length2,Factor3,RSI_Length3,Factor4,RSI_Length4,Factor5,RSI_Length5,Price,2,y);
          DU[pos] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Smoothing1,Smoothing2,Factor1,RSI_Length1,Factor2,RSI_Length2,Factor3,RSI_Length3,Factor4,RSI_Length4,Factor5,RSI_Length5,Price,3,y);                  
   }
return(0); 
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

