//------------------------------------------------------------------
#property copyright "mladen"
#property link      "www.forex-station.com"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1  clrLimeGreen
#property indicator_color2  clrOrange
#property indicator_color3  clrOrange
#property indicator_width1  3
#property indicator_width2  3
#property indicator_width3  3
#property strict

//
//
//
//
//

extern int                period     = 14;          // Calculating period
extern ENUM_APPLIED_PRICE price      = PRICE_CLOSE; // Price
extern int                linesWidth =  3;          // Lines width

double buffer[];
double bufferda[];
double bufferdb[];
double trend[];
double work[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int init()
{
   IndicatorBuffers(5);
   SetIndexBuffer(0,buffer,  INDICATOR_DATA); SetIndexStyle(0,EMPTY,EMPTY,linesWidth);
   SetIndexBuffer(1,bufferda,INDICATOR_DATA); SetIndexStyle(1,EMPTY,EMPTY,linesWidth);
   SetIndexBuffer(2,bufferdb,INDICATOR_DATA); SetIndexStyle(2,EMPTY,EMPTY,linesWidth);
   SetIndexBuffer(3,trend   ,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,work    ,INDICATOR_CALCULATIONS);
   IndicatorShortName("rsi Harris ("+(string)period+")");
   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-2);

   //
   //
   //
   //
   //

   if (trend[limit]==-1) CleanPoint(limit,bufferda,bufferdb);
   for(int i=limit; i>=0; i--)
   {
            buffer[i]   = iRsi(iMA(NULL,0,1,0,MODE_SMA,price,i),period,i);
            bufferda[i] = EMPTY_VALUE;
            bufferdb[i] = EMPTY_VALUE;
            trend[i]    = trend[i+1];
      
         //
         //
         //
         //
         //
         
         if (buffer[i]>buffer[i+1]) trend[i] =  1;
         if (buffer[i]<buffer[i+1]) trend[i] = -1;
         if (trend[i] == -1) PlotPoint(i,bufferda,bufferdb,buffer);
   }      
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
//

double workRsi[][1];
#define _price  0

double iRsi(double rprice, double rperiod, int i, int instanceNo=0)
{
   if (ArrayRange(workRsi,0)!=Bars) ArrayResize(workRsi,Bars); i = Bars-i-1;
   
   //
   //
   //
   //
   //
   
   workRsi[i][instanceNo+_price] = rprice;
      double avgUp=0,avgDn=0,up=0,dn=0;
         for(int k=0; k<rperiod && (i-k-1)>=0; k++)
         {
            double diff = workRsi[i-k][instanceNo+_price]- workRsi[i-k-1][instanceNo+_price];
            if(diff>0)
                  { avgUp += diff; up++; }
            else  { avgDn -= diff; dn++; }
         }
         if (up!=0) avgUp /= up;
         if (dn!=0) avgDn /= dn;
         double rs = 1;
            if (avgDn!=0) rs = avgUp/avgDn;
            return(100-100/(1.0+rs));
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

void CleanPoint(int i,double& first[],double& second[])
{
   if (i>=Bars-2) return;
   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
        second[i+1] = EMPTY_VALUE;
   else
      if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
          first[i+1] = EMPTY_VALUE;
}

//
//
//
//
//

void PlotPoint(int i,double& first[],double& second[],double& from[])
{
   if (i>=Bars-2) return;
   if (first[i+1] == EMPTY_VALUE)
         {
            if (first[i+2] == EMPTY_VALUE) 
                  { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
            else  { second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }
         }
   else  { first[i] = from[i]; second[i] = EMPTY_VALUE; }
}