//+------------------------------------------------------------------+
//|                                                   Swing line.mq4 |
//|                                                                  |
//| Avgust 2003 issue                                                |
//| Technical Analysis of Stocks and Commodities                     |
//| Giorgos Siligardos' article "Reverse Engineering RSI (II)”       |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  Red
#property indicator_width1  2

//
//
//
//
//

extern int SmaPeriod  = 45;
extern int WildPeriod = 14;
extern int Price      = PRICE_CLOSE;
extern int Shift      = 1;

double sma[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int init()
{
   SetIndexBuffer(0,sma); SetIndexShift(0,Shift);
   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);
         
   //
   //
   //
   //
   //
         
   for(int i=limit; i>=0; i--)
   {
      double price  = iMA(NULL,0,1,0,MODE_SMA,Price,i);
      double price1 = iMA(NULL,0,1,0,MODE_SMA,Price,i+1);
      double smaRsi = iSma(iRSI(NULL,0,WildPeriod,Price,i),SmaPeriod-1,i,0);
      double value1 = 0; if (price>price1) value1 = price-price1;
      double value2 = 0; if (price1>price) value2 = price1-price;
      double aup = iEma(value1,WildPeriod,i,0);
      double adp = iEma(value2,WildPeriod,i,1);
      
      //
      //
      //
      //
      //
      
      if ((100.0-smaRsi)!=0)
            double x = (WildPeriod-1.0)*(adp*smaRsi/(100.0-smaRsi)-aup);
      else         x = 0;       
      if (x>=0)
            sma[i] = price+x;
      else  
         if (smaRsi!=0)
               sma[i] = price+x*(100-smaRsi)/smaRsi;
         else  sma[i] = price;
   }
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

double workSma[][2];
double iSma(double price, int period, int r, int instanceNo=0)
{
   if (ArrayRange(workSma,0)!= Bars) ArrayResize(workSma,Bars); instanceNo *= 2; r = Bars-r-1;

   //
   //
   //
   //
   //
      
   workSma[r][instanceNo] = price;
   if (r>=period)
          workSma[r][instanceNo+1] = workSma[r-1][instanceNo+1]+(workSma[r][instanceNo]-workSma[r-period][instanceNo])/period;
   else { workSma[r][instanceNo+1] = 0; for(int k=0; k<period && (r-k)>=0; k++) workSma[r][instanceNo+1] += workSma[r-k][instanceNo];  
          workSma[r][instanceNo+1] /= k; }
   return(workSma[r][instanceNo+1]);
}

//
//
//
//
//

double workEma[][2];
double iEma(double price, double period, int r, int instanceNo=0)
{
   if (ArrayRange(workEma,0)!= Bars) ArrayResize(workEma,Bars);  r = Bars-r-1;

   //
   //
   //
   //
   //
      
   double alpha = 2.0 / (1.0+period);
          workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]);
   return(workEma[r][instanceNo]);
}

