SVE_RSI_I-Fish

Author: Copyright � 2011, MaryJane
SVE_RSI_I-Fish

Overview

The Smoothed RSI Inverse Fisher Transform is a technical analysis tool designed to identify market trends by refining standard momentum indicators. Its primary goal is to filter out "market noise"—the small, erratic price fluctuations that can often lead to false signals—to provide a clearer picture of the underlying price movement.

The Logic Process

The script processes data through four distinct stages to arrive at its final visual output:

1. Advanced Price Smoothing (The "Rainbow" Curve) Instead of looking at raw price data, which is often volatile, the script applies multiple layers of Weighted Moving Averages (WMA). It calculates these averages repeatedly to create a highly smoothed price curve. By weighting these averages differently, it ensures that more recent price data carries specific importance while still maintaining a smooth flow. This resulting "Rainbow" curve acts as the foundation for all subsequent calculations.

2. RSI Calculation The script then applies a Relative Strength Index (RSI) calculation to the smoothed Rainbow curve rather than the standard price. Because it starts with a smoothed curve, the resulting RSI is less prone to the "jagged" movements seen in standard RSI indicators. The value is then adjusted to center around a neutral midpoint.

3. Zero-Lag Smoothing To ensure the indicator reacts quickly enough to be useful for trading without sacrificing smoothness, the script employs a "Zero-Lag" Moving Average technique. This mathematical approach helps remove the inherent delay typically found in moving averages, allowing the indicator to stay as close to real-time price action as possible while remaining stable.

4. The Inverse Fisher Transform The final step applies an "Inverse Fisher Transform." This is a mathematical formula used to convert the smooth momentum data into a more dramatic and readable format. It essentially "stretches" the movement so that when the trend changes, it is more visually apparent. This results in a line that oscillates, providing clear visual cues for overbought or oversold conditions.

Alerts and Notifications

The script includes an automated monitoring system to notify the user of significant market shifts. It specifically looks for "crosses" where the indicator moves past specific thresholds (defined by the user, such as 12 and 88).

  • Upward Cross: If the line breaks above a high threshold, it signals a potential bullish momentum shift.
  • Downward Cross: If the line breaks below a low threshold, it signals a potential bearish momentum shift.

Depending on your settings, the script can trigger a pop-up alert on your trading platform or send an automated email notification, allowing you to monitor the market even when you are not looking at your screen.

Indicators Used
Moving average indicatorMoving average indicatorRelative strength index
Miscellaneous
Implements a curve of type %1It sends emails
9 Views
0 Downloads
0 Favorites
SVE_RSI_I-Fish
//+------------------------------------------------------------------+
//|                        Smoothed RSI Inverse Fisher Transform.mq4 |
//|                                     © 2011 MaryJane@ForexFactory |
//|   Indicator formula © 2010 Sylvain Vervoort, http://stocata.org/ |
//|                                Alert routine code © 2011 hanover |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, MaryJane"
#property link      "http://www.forexfactory.com/MaryJane"

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 1
#property indicator_color1 Blue
#property indicator_width1 3
#property indicator_level1 12
#property indicator_level2 88
#property indicator_levelcolor DimGray
//--- input parameters
extern int     RsiPeriod=4;
extern int     EmaPeriod=4;
extern int     AlertCandle         = 1;  
extern int     AlertLevelUp        = 12;                                                
extern int     AlertLevelDown      = 88; 
extern bool    ShowChartAlerts     = false;                                              
extern string  AlertEmailSubject   = "";   
extern int     BarCount            = 500;                                              
                                                                                         
datetime       OldTime;
datetime       LastAlertTime       = -999999;                                            
string         AlertTextCrossUp    = "SVE RSI I-Fish UP";                          
string         AlertTextCrossDown  = "SVE RSI I-Fish DOWN";                        
 
//--- buffers
double wma0[], wma1[], wma2[], wma3[], wma4[], wma5[], wma6[], wma7[], wma8[], wma9[];
double ema0[], ema1[], rainbow[], rsi[], srsi[], fish[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
   {
   IndicatorShortName(StringConcatenate("SVE RSI I-Fish (", RsiPeriod, ",", EmaPeriod, ")"));
//---- 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);
   ArrayResize(wma0, BarCount); ArraySetAsSeries(wma0, true);
   ArrayResize(wma1, BarCount); ArraySetAsSeries(wma1, true);
   ArrayResize(wma2, BarCount); ArraySetAsSeries(wma2, true);
   ArrayResize(wma3, BarCount); ArraySetAsSeries(wma3, true);
   ArrayResize(wma4, BarCount); ArraySetAsSeries(wma4, true);
   ArrayResize(wma5, BarCount); ArraySetAsSeries(wma5, true);
   ArrayResize(wma6, BarCount); ArraySetAsSeries(wma6, true);
   ArrayResize(wma7, BarCount); ArraySetAsSeries(wma7, true);
   ArrayResize(wma8, BarCount); ArraySetAsSeries(wma8, true);
   ArrayResize(wma9, BarCount); ArraySetAsSeries(wma9, true);
   //---- reset counter  
   OldTime = Time[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 = MathMin(BarCount, Bars - 1 - counted_bars);
//---- resize/shift extra buffers on first and every next bar
   if (Time[0] != OldTime) SyncExtraBuffers();
//---- 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--)
      {
      rainbow[i] = (5 * wma0[i] + 4 * wma1[i] + 3 * wma2[i] + 2 * wma3[i] + wma4[i] + wma5[i] + wma6[i] + wma7[i] + wma8[i] + wma9[i]) / 20;
      }
//---- 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;
//----
   ProcessAlerts();
//----
   return(0);
   }
//+------------------------------------------------------------------+
//| Shift array elements on new bar                                  |
//+------------------------------------------------------------------+
void SyncExtraBuffers()
   {
   for (int i = BarCount - 1; i >= 0; i--)
      {
      wma0[i + 1] = wma0[i];
      wma1[i + 1] = wma1[i];
      wma2[i + 1] = wma2[i];
      wma3[i + 1] = wma3[i];
      wma4[i + 1] = wma4[i];
      wma5[i + 1] = wma5[i];
      wma6[i + 1] = wma6[i];
      wma7[i + 1] = wma7[i];
      wma8[i + 1] = wma8[i];
      wma9[i + 1] = wma9[i];
      }
//---- reset counter   
   OldTime = Time[0];
   }
//+------------------------------------------------------------------+
//  Alert routine by hanover
//  http://www.forexfactory.com/showthread.php?t=299520
//+------------------------------------------------------------------+                                                                          //
int ProcessAlerts()   {                                                                                                                         //
//+------------------------------------------------------------------+                                                                          //
  if (AlertCandle >= 0  &&  Time[0] > LastAlertTime)   {                                                                                        //
                                                                                                                                                //
    // === Alert processing for crossover UP (indicator line crosses ABOVE signal line) ===                                                     //
    if (fish[AlertCandle] > AlertLevelUp  &&  fish[AlertCandle+1] <= AlertLevelUp)  {                                                           //
      string AlertText = Symbol() + "," + TFToStr(Period()) + ": " + AlertTextCrossUp;                                                          //
      if (ShowChartAlerts)          Alert(AlertText);                                                                                           //
      if (AlertEmailSubject > "")   SendMail(AlertEmailSubject,AlertText);                                                                      //
    }                                                                                                                                           //
                                                                                                                                                //
    // === Alert processing for crossover DOWN (indicator line crosses BELOW signal line) ===                                                   //
    if (fish[AlertCandle] < AlertLevelDown  &&  fish[AlertCandle+1] >= AlertLevelDown)  {                                                       //
      AlertText = Symbol() + "," + TFToStr(Period()) + ": " + AlertTextCrossDown;                                                               //
      if (ShowChartAlerts)          Alert(AlertText);                                                                                           //
      if (AlertEmailSubject > "")   SendMail(AlertEmailSubject,AlertText);                                                                      //
    }                                                                                                                                           //
                                                                                                                                                //
    LastAlertTime = Time[0];                                                                                                                    //
  }                                                                                                                                             //
  return(0);                                                                                                                                    //
}                                                                                                                                               //
                                                                                                                                                //
//+------------------------------------------------------------------+                                                                          //
string TFToStr(int tf)   {                                                                                                                      //
//+------------------------------------------------------------------+                                                                          //
  if (tf == 0)        tf = Period();                                                                                                            //
  if (tf >= 43200)    return("MN");                                                                                                             //
  if (tf >= 10080)    return("W1");                                                                                                             //
  if (tf >=  1440)    return("D1");                                                                                                             //
  if (tf >=   240)    return("H4");                                                                                                             //
  if (tf >=    60)    return("H1");                                                                                                             //
  if (tf >=    30)    return("M30");                                                                                                            //
  if (tf >=    15)    return("M15");                                                                                                            //
  if (tf >=     5)    return("M5");                                                                                                             //
  if (tf >=     1)    return("M1");                                                                                                             //
  return("");                                                                                                                                   //
}                                                                                                                                               //
// ============================================================================================================================================ //

Comments