//------------------------------------------------------------------
#property copyright "mladen"
#property link      "www.forex-tsd.com"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1  LimeGreen

extern ENUM_TIMEFRAMES    TimeFrame        = PERIOD_CURRENT;
extern int                RsiPeriod    = 3;
extern int                UpDownPeriod = 2;
extern int                ROCPeriod    = 100;
extern ENUM_APPLIED_PRICE Price        = PRICE_CLOSE;
extern double             SmoothPeriod = 25;

//
//
//
//
//

double rsi[];
double prices[];
double updown[];
double roc[];
string indicatorFileName;
bool   returnBars;


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   for (int i=0; i<indicator_buffers; i++) SetIndexStyle(i,DRAW_LINE);
   IndicatorBuffers(4);
   SetIndexBuffer(0,rsi);
   SetIndexBuffer(1,prices);
   SetIndexBuffer(2,updown); SetIndexEmptyValue(2,0);
   SetIndexBuffer(3,roc);
   
   //
   //
   //
   //
   //
      
      indicatorFileName = WindowExpertName();
      returnBars        = TimeFrame==-99;
      TimeFrame         = MathMax(TimeFrame,_Period);
      
   //
   //
   //
   //
   //
   
   IndicatorShortName(timeFrameToString(TimeFrame)+" Connors RSI of super smoother");
   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) { rsi[0] = limit+1; return(0); }

   //
   //
   //
   //
   //
   
   if (TimeFrame == Period())
   { 
     for(int i=limit; i>=0; i--)
     {
        prices[i] = iSsm(iMA(NULL,0,1,0,MODE_SMA,Price,i),SmoothPeriod,i);
           if (prices[i] == prices[i+1]) updown[i] = 0;
           if (prices[i] <  prices[i+1]) if (updown[i+1] > 0) updown[i] = -1; else updown[i] = updown[i+1]-1;
           if (prices[i] >  prices[i+1]) if (updown[i+1] < 0) updown[i] =  1; else updown[i] = updown[i+1]+1;
     }
     for(i=limit; i>=0; i--)
     {   
        double trsi = iRSIOnArray(prices,0,RsiPeriod,i);
        double ursi = iRSIOnArray(updown,0,UpDownPeriod,i);
        roc[i]  = 0;
           if (prices[i+1]!=0) roc[i] = (prices[i]/prices[i+1]-1.0)*100.0;

           double ROC_Percent = 0;
	        for (int k=1; k<=ROCPeriod; k++)
      		  if (roc[i] >= roc[i+k]) ROC_Percent++;
            	                     ROC_Percent = (ROC_Percent / ROCPeriod) * 100;

           //
           //
           //
           //
           //
         
           rsi[i] = (trsi + ursi + ROC_Percent) / 3.0;
     }         
   return(0);
  }
  
  //
   //
   //
   //
   //
   
   limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/Period()));
   for (i=limit;i>=0;i--)
   {
      int y = iBarShift(NULL,TimeFrame,Time[i]);
         rsi[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,RsiPeriod,UpDownPeriod,ROCPeriod,Price,SmoothPeriod,0,y);      
   }
   return(0);         
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

double workSsm[][6];
#define _price  0
#define _ssm    1

double workSsmCoeffs[][4];
#define _period 0
#define _c1     1
#define _c2     2
#define _c3     3
#define Pi 3.14159265358979323846264338327950288

//
//
//
//
//

double iSsm(double price, double period, int i, int instanceNo=0)
{
   if (period<=1) return(price);
   if (ArrayRange(workSsm,0) !=Bars)                 ArrayResize(workSsm,Bars);
   if (ArrayRange(workSsmCoeffs,0) < (instanceNo+1)) ArrayResize(workSsmCoeffs,instanceNo+1);
   if (workSsmCoeffs[instanceNo][_period] != period)
   {
      workSsmCoeffs[instanceNo][_period] = period;
      double a1 = MathExp(-1.414*Pi/period);
      double b1 = 2.0*a1*MathCos(1.414*Pi/period);
         workSsmCoeffs[instanceNo][_c2] = b1;
         workSsmCoeffs[instanceNo][_c3] = -a1*a1;
         workSsmCoeffs[instanceNo][_c1] = 1.0 - workSsmCoeffs[instanceNo][_c2] - workSsmCoeffs[instanceNo][_c3];
   }

   //
   //
   //
   //
   //

      i = Bars-i-1;
      int s = instanceNo*2;   
          workSsm[i][s+_price] = price;
          workSsm[i][s+_ssm]   = workSsmCoeffs[instanceNo][_c1]*(workSsm[i][s+_price]+workSsm[i-1][s+_price])/2.0 + 
                                 workSsmCoeffs[instanceNo][_c2]*workSsm[i-1][s+_ssm]                              + 
                                 workSsmCoeffs[instanceNo][_c3]*workSsm[i-2][s+_ssm];
   return(workSsm[i][s+_ssm]);
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

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("");
}

