Author: © mladen, 2018

Okay, here's a breakdown of what this MetaTrader script does, explained in a way that doesn't require any programming knowledge:

Overall Purpose:

This script is designed to create a custom indicator for the MetaTrader platform. An indicator is a tool that helps traders analyze price charts and make decisions about when to buy or sell. This particular indicator is called "Rocket RSI" (Relative Strength Index) and potentially applies a Fisher Transform to the RSI to enhance its signals.

Key Components and How They Work:

  1. Inputs (Customizable Settings):

    • Period: Determines how many past price data points are used to calculate the RSI. A larger period makes the indicator smoother but slower to react to price changes.
    • Smoothing: Applies a smoothing filter to the RSI value. This makes the indicator line less jagged and can help filter out short-term noise.
    • Price: Specifies which price to use for the calculations (e.g., closing price, opening price, high, low).
    • Levels: Defines overbought/oversold levels. When the indicator crosses these levels, it can signal potential buying or selling opportunities.
    • Color Change Mode: Sets the condition for changing the color of the indicator line. The color can change based on whether the indicator is increasing/decreasing (slope), crossing the zero line, or crossing the defined levels.
    • Calculating Mode: Selects whether the "Rocket RSI" calculation should be displayed by itself or whether it should be displayed with an applied "Fisher Transform".
  2. Calculations:

    • Price Selection: The script first selects the appropriate price data (close, open, high, low, etc.) based on the user's input settings.
    • "Rocket RSI" Calculation: This is the core of the indicator. It calculates the RSI, which measures the speed and change of price movements. The RSI typically ranges from -1 to 1, with extreme values suggesting overbought or oversold conditions. The RSI calculation in this indicator uses something called a momentum filter to help smooth the values.
    • Fisher Transform (Optional): If enabled via the "Calculating Mode", the script applies the Fisher Transform to the RSI values. The Fisher Transform converts the RSI into a Gaussian-like distribution which can make overbought/oversold signals more prominent.
  3. Coloring:

    • The script changes the color of the indicator line based on the "Color Change Mode" setting.
      • Slope: If the indicator line is moving upwards, it displays one color. If it's moving downwards, it displays another color.
      • Zero Cross: If the indicator line crosses above zero, it displays one color. If it crosses below zero, it displays another color.
      • Levels Cross: If the indicator crosses above a specified positive level (overbought), it displays one color. If it crosses below a specified negative level (oversold), it displays another color.
  4. Output:

    • The script displays the calculated "Rocket RSI" value as a line on a separate window of the MetaTrader chart. The color of the line changes according to the chosen "Color Change Mode."
    • The script also draws horizontal lines on the indicator window to represent the overbought and oversold levels, making it easier to identify potential trading signals.

In essence, this script provides a visual tool to help traders identify potential overbought and oversold conditions in the market, with added flexibility through customizable settings and color-coded signals.

3 Views
0 Downloads
0 Favorites
Rocket RSI
ÿþ//------------------------------------------------------------------

#property copyright "© mladen, 2018"

#property link      "mladenfx@gmail.com"

#property version   "1.00"

//------------------------------------------------------------------

#property indicator_separate_window

#property indicator_buffers 2

#property indicator_plots   1

#property indicator_label1  "Rocket RSI"

#property indicator_type1   DRAW_COLOR_LINE

#property indicator_color1  clrSilver,clrMediumSeaGreen,clrOrangeRed

#property indicator_width1  2



//

//---

//



enum enCalcMode

{

   calc_fisher  = 0, // Calculate fisher transform of "rocket" rsi

   calc_regular = 1  // Calculate "rocket" rsi only

};

enum enColorMode

{

   col_onSlope,  // Color change on slope change

   col_onZero,   // Color change on zero cross

   col_onLevels  // Color change on levels cross

};

input int                inpPeriod    = 10;           // Period

input int                inpSmooth    = 10;           // Smoothing

input ENUM_APPLIED_PRICE inpPrice     = PRICE_CLOSE;  // Price

input double             inpLevel     = 2;            // Levels (will be used as +- level)

input enColorMode        inpColorMode = col_onLevels; // Color change mode

input enCalcMode         inpCalcMode  = calc_fisher;  // Calculating mode



//

//---

//



double val[],valc[]; string ª_names[] = {"Fisher transform of ",""};

int  ª_smoothPeriod,ª_rsiPeriod; 



//------------------------------------------------------------------ 

//  Custom indicator initialization function

//------------------------------------------------------------------



int OnInit()

{

   //

   //---- indicator buffers mapping

   //

         SetIndexBuffer(0,val ,INDICATOR_DATA);

         SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX);

            ª_smoothPeriod = (inpSmooth>0) ? inpSmooth : 1;

            ª_rsiPeriod    = (inpPeriod>0) ? inpPeriod : 1;

            IndicatorSetInteger(INDICATOR_LEVELS,2);

               IndicatorSetDouble(INDICATOR_LEVELVALUE,0, inpLevel);

               IndicatorSetDouble(INDICATOR_LEVELVALUE,1,-inpLevel);

   //            

   //----

   //

   IndicatorSetString(INDICATOR_SHORTNAME,ª_names[inpCalcMode]+"Rocket RSI ("+(string)ª_rsiPeriod+","+(string)ª_smoothPeriod+")");

   return(INIT_SUCCEEDED);

}



//------------------------------------------------------------------

//  Custom indicator iteration function

//------------------------------------------------------------------

//

//---

//



#define _setPrice(_priceType,_where,_index) { \

   switch(_priceType) \

   { \

      case PRICE_CLOSE:    _where = close[_index];                                              break; \

      case PRICE_OPEN:     _where = open[_index];                                               break; \

      case PRICE_HIGH:     _where = high[_index];                                               break; \

      case PRICE_LOW:      _where = low[_index];                                                break; \

      case PRICE_MEDIAN:   _where = (high[_index]+low[_index])/2.0;                             break; \

      case PRICE_TYPICAL:  _where = (high[_index]+low[_index]+close[_index])/3.0;               break; \

      case PRICE_WEIGHTED: _where = (high[_index]+low[_index]+close[_index]+close[_index])/4.0; break; \

      default : _where = 0; \

   }}



//

//---

//



int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

{

   int i= prev_calculated-1; if (i<0) i=0; for (; i<rates_total && !_StopFlag; i++)

   {

      double _price; _setPrice(inpPrice,_price,i);

      val[i] = iRocketRsi(_price,ª_rsiPeriod,ª_smoothPeriod,inpCalcMode,i,rates_total);

      switch (inpColorMode)

      {

         case col_onSlope :  valc[i] = (i>0) ? (val[i]>val[i-1]) ? 1 : (val[i]<val[i-1]) ? 2 : valc[i-1]: 0 ; break;

         case col_onZero  :  valc[i] = (val[i]>0) ? 1 : (val[i]<0) ? 2 : 0;                                   break;

         default :           valc[i] = (val[i]>inpLevel) ? 1 : (val[i]<-inpLevel) ? 2 : 0;

      }

   }

   return(i);

}



//------------------------------------------------------------------

//  Custom function(s)

//------------------------------------------------------------------

//

//---

//



double iRocketRsi(double price, int period, double smooth, int mode, int i, int bars, int instance=0)

{

   #define ¤ instance

   #define _functionInstances 1



      //

      //---

      //

      

      struct sRocketRsiCoeffs

      {

         int    initKey;

         double originalPeriod;

         double period;

         double coeff1;

         double coeff2;

         double coeff3;

      };

      struct sRocketRsiStruct

      {

         double price;

         double momentum;

         double filter;

         double diffp;

         double diffn;

         double sump;

         double sumn;

      };

      static sRocketRsiCoeffs m_coeffs[_functionInstances];

      static sRocketRsiStruct m_array[][_functionInstances];

      static int              m_arraySize=0;

         if (m_arraySize<bars)

         {

            int _res = ArrayResize(m_array,bars+500);

            if (_res<bars) return(0);

                        m_arraySize = _res;

         }

         if (m_coeffs[¤].originalPeriod!=smooth || m_coeffs[¤].initKey!=-99)

         {

            m_coeffs[¤].initKey        = -99;

            m_coeffs[¤].originalPeriod =  smooth;

            m_coeffs[¤].period         = (smooth>1) ? smooth : 1;

         

               //

               //---

               //

            

                  double a = MathExp(-1.414*M_PI/m_coeffs[¤].period);

            

               //

               //---

               //

            

            m_coeffs[¤].coeff2 = 2*a*MathCos(1.414*M_PI/m_coeffs[¤].period);;

            m_coeffs[¤].coeff3 = -a*a;

            m_coeffs[¤].coeff1 = 1-m_coeffs[¤].coeff2-m_coeffs[¤].coeff3;      

         }



   //

   //---

   //



      m_array[i][¤].price = price;

      if (i>period)

      {

         m_array[i][¤].momentum = m_array[i][¤].price-m_array[i-period+1][¤].price;

         m_array[i][¤].filter   = m_coeffs[¤].coeff1*((m_array[i][¤].momentum+m_array[i-1][¤].momentum)/2.0)+m_coeffs[¤].coeff2*m_array[i-1][¤].filter+m_coeffs[¤].coeff3*m_array[i-2][¤].filter;

         m_array[i][¤].diffp    = (m_array[i][¤].filter>m_array[i-1][¤].filter) ? m_array[i][¤].filter-m_array[i-1][¤].filter : 0;

         m_array[i][¤].diffn    = (m_array[i][¤].filter<m_array[i-1][¤].filter) ? m_array[i-1][¤].filter-m_array[i][¤].filter : 0;

         m_array[i][¤].sump     =  m_array[i-1][¤].sump+m_array[i][¤].diffp-m_array[i-period][¤].diffp;

         m_array[i][¤].sumn     =  m_array[i-1][¤].sumn+m_array[i][¤].diffn-m_array[i-period][¤].diffn;

      }

      else

      {

         m_array[i][¤].momentum = m_array[i][¤].price-m_array[0][¤].price;

         m_array[i][¤].filter   = (i>1) ? m_coeffs[¤].coeff1*((m_array[i][¤].momentum+m_array[i-1][¤].momentum)/2)+m_coeffs[¤].coeff2*m_array[i-1][¤].filter+m_coeffs[¤].coeff3*m_array[i-2][¤].filter : m_array[i][¤].momentum;

         m_array[i][¤].diffp    = (i>0) ? (m_array[i][¤].filter>m_array[i-1][¤].filter) ? m_array[i][¤].filter-m_array[i-1][¤].filter : 0 : 0;

         m_array[i][¤].diffn    = (i>0) ? (m_array[i][¤].filter<m_array[i-1][¤].filter) ? m_array[i-1][¤].filter-m_array[i][¤].filter : 0 : 0;

         m_array[i][¤].sump     = m_array[i][¤].diffp;

         m_array[i][¤].sumn     = m_array[i][¤].diffn;

         for (int k=1; k<period && i>=k; k++)

         {

            m_array[i][¤].sump += m_array[i-k][¤].diffp;

            m_array[i][¤].sumn += m_array[i-k][¤].diffn;

         }

      }



   //

   //---

   //

   

      double denom = m_array[i][¤].sump+m_array[i][¤].sumn;

      double rsi   = (denom!=0) ? (m_array[i][¤].sump-m_array[i][¤].sumn)/denom : 0;

      if (mode==0)

      {

         if (rsi >  0.999) rsi =  0.999;

         if (rsi < -0.999) rsi = -0.999;



         return(0.5*MathLog((1+rsi)/(1-rsi)));

      }         

      else return(rsi);

}

//------------------------------------------------------------------

Comments