//+------------------------------------------------------------------+
//|                        Smoothed RSI Inverse Fisher Transform.mq4 |
//|                                     © 2011 MaryJane@ForexFactory |
//|   Indicator formula © 2010 Sylvain Vervoort, http://stocata.org/ |
//+------------------------------------------------------------------+

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red

//--- input parameters
extern int       RsiPeriod=4;
extern int       EmaPeriod=4;
//--- buffers
double wma0[], wma1[], wma2[], wma3[], wma4[], wma5[], wma6[], wma7[], wma8[], wma9[];
double ema0[], ema1[];
double rainbow[], rsi[], srsi[];
double fish[];
int OldBars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
   {
//---- indicators
   IndicatorBuffers(6); 
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, fish);
   SetIndexBuffer(1, rainbow);
   SetIndexBuffer(2, rsi);
   SetIndexBuffer(3, ema0);
   SetIndexBuffer(4, ema1);
   SetIndexBuffer(5, srsi);
//---- reset   
   OldBars = 0;
//----
   return(0);
   }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
   {
//----
   
//----
   return(0);
   }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
   {
   int counted_bars = IndicatorCounted();
   if (counted_bars < 0) return (-1);
   if (counted_bars > 0) counted_bars--;
   int limit = Bars - 1 - counted_bars;
//---- handle additional buffers if necessary (mladen, you're a star :-)))
   if (Bars != OldBars)
      {
      OldBars = Bars;
      ArraySetAsSeries(wma0, false); ArrayResize(wma0, Bars); ArraySetAsSeries(wma0, true);
      ArraySetAsSeries(wma1, false); ArrayResize(wma1, Bars); ArraySetAsSeries(wma1, true);
      ArraySetAsSeries(wma2, false); ArrayResize(wma2, Bars); ArraySetAsSeries(wma2, true);
      ArraySetAsSeries(wma3, false); ArrayResize(wma3, Bars); ArraySetAsSeries(wma3, true);
      ArraySetAsSeries(wma4, false); ArrayResize(wma4, Bars); ArraySetAsSeries(wma4, true);
      ArraySetAsSeries(wma5, false); ArrayResize(wma5, Bars); ArraySetAsSeries(wma5, true);
      ArraySetAsSeries(wma6, false); ArrayResize(wma6, Bars); ArraySetAsSeries(wma6, true);
      ArraySetAsSeries(wma7, false); ArrayResize(wma7, Bars); ArraySetAsSeries(wma7, true);
      ArraySetAsSeries(wma6, false); ArrayResize(wma6, Bars); ArraySetAsSeries(wma6, true);
      ArraySetAsSeries(wma8, false); ArrayResize(wma8, Bars); ArraySetAsSeries(wma8, true);
      ArraySetAsSeries(wma9, false); ArrayResize(wma9, Bars); ArraySetAsSeries(wma9, true);
      }
//---- prepare partial averages
   for (int i = limit; i >= 0; i--) wma0[i] = iMA(NULL, 0, 2, 0, MODE_LWMA, PRICE_CLOSE, i);
   for (i = limit; i >= 0; i--) wma1[i] = iMAOnArray(wma0, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma2[i] = iMAOnArray(wma1, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma3[i] = iMAOnArray(wma2, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma4[i] = iMAOnArray(wma3, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma5[i] = iMAOnArray(wma4, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma6[i] = iMAOnArray(wma5, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma7[i] = iMAOnArray(wma6, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma8[i] = iMAOnArray(wma7, 0, 2, 0, MODE_LWMA, i);
   for (i = limit; i >= 0; i--) wma9[i] = iMAOnArray(wma8, 0, 2, 0, MODE_LWMA, i);
//---- weigh the averages
   for (i = limit; i >= 0; i--)
      {
      double rb_val =  5 * wma0[i] + 4 * wma1[i] + 3 * wma2[i] + 2 * wma3[i] + wma4[i] + wma5[i] + wma6[i] + wma7[i] + wma8[i] + wma9[i];
      rb_val /= 20;
      rainbow[i] = rb_val;
      }
//---- calculate rsi from rainbow smoothed price curve 
   for (i = limit; i >= 0; i--) rsi[i] = 0.1 * (iRSIOnArray(rainbow, 0, RsiPeriod, i) - 50);
//---- smooth the rsi with Vervoort zero lag MA
   for (i = limit; i >= 0; i--) ema0[i] = iMAOnArray(rsi, 0, EmaPeriod, 0, MODE_EMA, i);
   for (i = limit; i >= 0; i--) ema1[i] = iMAOnArray(ema0, 0, EmaPeriod, 0, MODE_EMA, i);
   for (i = limit; i >= 0; i--) srsi[i] = ema0[i] + (ema0[i] - ema1[i]);
//---- do the fish
   for (i = limit; i >= 0; i--) fish[i] = ((MathExp(2 * srsi[i]) - 1) / (MathExp(2 * srsi[i]) + 1) + 1) * 50;
//----
   return(0);
   }
//+------------------------------------------------------------------+