#property copyright "www.forex-station.com"
#property link      "www.forex-station.com"

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_label1  "Rsi strong up"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrLimeGreen
#property indicator_width1  2

#property indicator_label2  "Rsi weak up"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrLimeGreen

#property indicator_label3  "Rsi strong down"
#property indicator_type3   DRAW_HISTOGRAM
#property indicator_color3  clrOrange
#property indicator_width3  2

#property indicator_label4  "Rsi weak down"
#property indicator_type4   DRAW_HISTOGRAM
#property indicator_color4  clrOrangeRed

#property indicator_label5  "Rsi weak down"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrGray
#property indicator_width5  2
#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES   TimeFrame    = PERIOD_CURRENT;    // Time frame
input int                RsiPeriod    = 14;                // Rsi period
input ENUM_APPLIED_PRICE RsiPrice     = PRICE_CLOSE;       // Price to use
input bool               Interpolate  = true;              // Interpolate in multi time frame mode

double huu[],hud[],hdd[],hdu[],val[],valc[],count[]; 
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,RsiPeriod,RsiPrice,_buff,_ind)

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int OnInit()
{
    IndicatorBuffers(7);
    SetIndexBuffer(0,huu,INDICATOR_DATA); 
    SetIndexBuffer(1,hud,INDICATOR_DATA); 
    SetIndexBuffer(2,hdd,INDICATOR_DATA);
    SetIndexBuffer(3,hdu,INDICATOR_DATA);
    SetIndexBuffer(4,val,INDICATOR_DATA);
    SetIndexBuffer(5,valc);
    SetIndexBuffer(6,count);
   
    indicatorFileName = WindowExpertName();
    TimeFrame         = fmax(TimeFrame,_Period); 
 
    IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(TimeFrame)+" Rsi");
return (INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

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[])
{
   int i=rates_total-prev_calculated+1; if (i>=rates_total) i=rates_total-1; count[0]=i;
      if (TimeFrame!=_Period)
      {
         i = (int)fmax(i,fmin(rates_total-1,_mtfCall(6,0)*TimeFrame/_Period));
         for (; i>=0 && !_StopFlag; i--)
         {
             int y = iBarShift(_Symbol,TimeFrame,time[i]);
                huu[i] = _mtfCall(0,y);
                hud[i] = _mtfCall(1,y);
                hdd[i] = _mtfCall(2,y);
                hdu[i] = _mtfCall(3,y);  
                val[i] = _mtfCall(4,y);
                    
                //
                //
                //
                     
                if (!Interpolate || (i>0 && y==iBarShift(_Symbol,TimeFrame,time[i-1]))) continue;
                  #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                  int n,k; datetime btime = iTime(_Symbol,TimeFrame,y);
                     for(n = 1; (i+n)<rates_total && time[i+n] >= btime; n++) continue;	
                     for(k = 1; k<n && (i+n)<rates_total && (i+k)<rates_total; k++) 
                     {
                        _interpolate(val); 
                        if (huu[i]!= EMPTY_VALUE) huu[i+k] = val[i+k];
                        if (hud[i]!= EMPTY_VALUE) hud[i+k] = val[i+k];
  	                     if (hdd[i]!= EMPTY_VALUE) hdd[i+k] = val[i+k];
  	                     if (hdu[i]!= EMPTY_VALUE) hdu[i+k] = val[i+k];
                     }                                                                    
              }  
   
   return(rates_total);
   }
   
   //
   //
   //
 
   for (; i>=0 && !_StopFlag; i--)
   {
      double _price  = (high[i]+low[i])*0.5;
      val[i]  = iRSI(_Symbol,_Period,RsiPeriod,RsiPrice,i)-50;
      valc[i] = (i<rates_total-1) ? (val[i]>0) ? (val[i]>val[i+1]) ? 0 : 1 : (val[i]<val[i+1]) ? 2 : 3 : 0;
      huu[i] = (valc[i] == 0) ? val[i] : EMPTY_VALUE;
      hud[i] = (valc[i] == 1) ? val[i] : EMPTY_VALUE;
      hdd[i] = (valc[i] == 2) ? val[i] : EMPTY_VALUE;
      hdu[i] = (valc[i] == 3) ? val[i] : EMPTY_VALUE;  
   }
return(rates_total);
}
      
//
//
//
//
//

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("");
}
