Indicators: Moving Average of RSI

 

Moving Average of RSI:

This powerful tool filters the classic RSI through a moving average, providing a smoother, more reliable signal line for pinpointing entries, exits, and trend direction with unparalleled clarity.

Moving Average of RSI

Author: Tonny Obare

 

Free code is much welcomed and other developers may find helpful. Thank you.

 
Automated-Trading:

Moving Average of RSI:

Author: Tonny Obare

How to install the software in a trading platform and use it 
 
ALLWYN MAGARE #:
How to install the software in a trading platform and use it 
Hello. You can install it right from your Metatrader terminal.
 
When accuracy matters...

//+------------------------------------------------------------------+
//|                                                  MA_of_RSI.mq5   |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   "1.04"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2

#property indicator_label1  "MA of Custom RSI"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLimeGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

#property indicator_label2  "RSI Line"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGray
#property indicator_style2  STYLE_DOT
#property indicator_width2  1

#property indicator_minimum 0
#property indicator_maximum 100

// Input parameters
input int                RSI1_Period        = 14;           // RSI1: Period
input ENUM_APPLIED_PRICE RSI1_Applied_Price = PRICE_CLOSE;  // RSI1: Applied Price
input int                MA_Period          = 10;           // MA Period

enum ENUM_MA_METHOD_SUPPORTED
{
   MA_SMA  = MODE_SMA,   // Simple MA
   MA_LWMA = MODE_LWMA   // Linear-Weighted MA
};
input ENUM_MA_METHOD_SUPPORTED MA_Method = MA_LWMA;             // MA Method
input double             RSI1_Oversold      = 30.0;         // Oversold Level
input double             RSI1_Overbought    = 70.0;         // Overbought Level

// Indicator buffers
double maBuffer[];
double rsiBuffer[];

// Handles
int rsi1Handle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   if(RSI1_Period < 1)
   {
      Print("Invalid RSI1_Period: ", RSI1_Period);
      return INIT_PARAMETERS_INCORRECT;
   }

   if(MA_Period < 1)
   {
      Print("Invalid MA_Period: ", MA_Period);
      return INIT_PARAMETERS_INCORRECT;
   }

   if(RSI1_Oversold < 0.0 || RSI1_Oversold > 100.0 ||
      RSI1_Overbought < 0.0 || RSI1_Overbought > 100.0)
   {
      Print("Oversold/Overbought must be within 0..100");
      return INIT_PARAMETERS_INCORRECT;
   }

   if(RSI1_Oversold >= RSI1_Overbought)
   {
      Print("Oversold must be < Overbought");
      return INIT_PARAMETERS_INCORRECT;
   }

   SetIndexBuffer(0, maBuffer,  INDICATOR_DATA);
   SetIndexBuffer(1, rsiBuffer, INDICATOR_DATA);

   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, RSI1_Period + MA_Period - 2);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, RSI1_Period - 1);

   IndicatorSetString(INDICATOR_SHORTNAME,
                      "MA of Custom RSI(" + string(RSI1_Period) + ") [" +
                      DoubleToString(RSI1_Oversold, 1) + "/" +
                      DoubleToString(RSI1_Overbought, 1) + "]");
   IndicatorSetInteger(INDICATOR_DIGITS, 2);

   IndicatorSetInteger(INDICATOR_LEVELS, 2);
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, RSI1_Oversold);
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, RSI1_Overbought);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE, STYLE_DOT);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR, clrSilver);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH, 1);

   IndicatorSetDouble(INDICATOR_MINIMUM, 0);
   IndicatorSetDouble(INDICATOR_MAXIMUM, 100);

   rsi1Handle = iCustom(_Symbol, _Period, "Examples\\RSI", RSI1_Period, RSI1_Applied_Price);
   if(rsi1Handle == INVALID_HANDLE)
   {
      Print("Error creating custom RSI handle: ", GetLastError());
      return INIT_FAILED;
   }

   PlotIndexSetString(0, PLOT_LABEL, "MA of RSI(" + string(RSI1_Period) + ")");
   PlotIndexSetString(1, PLOT_LABEL, "RSI(" + string(RSI1_Period) + ")");

   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Indicator deinitialization — release handle                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(rsi1Handle != INVALID_HANDLE)
   {
      IndicatorRelease(rsi1Handle);
      rsi1Handle = INVALID_HANDLE;
   }
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
{
   if(rates_total <= 0)
      return 0;

   ArraySetAsSeries(maBuffer,  true);
   ArraySetAsSeries(rsiBuffer, true);

   double tempRSI[];
   ArraySetAsSeries(tempRSI, true);

   int bars_ready = BarsCalculated(rsi1Handle);
   if(bars_ready <= 0)
      return prev_calculated;

   int copied = CopyBuffer(rsi1Handle, 0, 0, rates_total, tempRSI);
   if(copied <= 0)
   {
      Print("Error copying RSI buffer: ", GetLastError());
      return prev_calculated;
   }

   if(prev_calculated == 0)
   {
      ArrayInitialize(maBuffer,  EMPTY_VALUE);
      ArrayInitialize(rsiBuffer, EMPTY_VALUE);
   }

   int start;
   if(prev_calculated == 0)
   {
      start = copied - 1;
   }
   else
   {
      start = rates_total - prev_calculated;
      if(start < 1)
         start = 1;
      start += 1;
      if(start > copied - 1)
         start = copied - 1;
   }

   for(int i = start; i >= 0; --i)
   {
      if(i >= copied)
      {
         rsiBuffer[i] = EMPTY_VALUE;
         maBuffer[i]  = EMPTY_VALUE;
         continue;
      }

      rsiBuffer[i] = tempRSI[i];

      if(tempRSI[i] == EMPTY_VALUE)
      {
         rsiBuffer[i] = EMPTY_VALUE;
         maBuffer[i]  = EMPTY_VALUE;
         continue;
      }

      if(i + MA_Period - 1 >= copied)
      {
         maBuffer[i] = EMPTY_VALUE;
         continue;
      }

      bool valid_window = true;
      for(int j = 0; j < MA_Period; ++j)
      {
         if(tempRSI[i + j] == EMPTY_VALUE)
         {
            valid_window = false;
            break;
         }
      }

      if(!valid_window)
      {
         maBuffer[i] = EMPTY_VALUE;
         continue;
      }

      maBuffer[i] = CalculateMA(tempRSI, i, MA_Period, MA_Method);
   }

   return rates_total;
}

//+------------------------------------------------------------------+
//| Helper function to calculate MA values                           |
//+------------------------------------------------------------------+
double CalculateMA(double &data[], int index, int period, ENUM_MA_METHOD_SUPPORTED method)
{
   if(period < 1)
      return EMPTY_VALUE;

   if(index < 0 || index + period - 1 >= ArraySize(data))
      return EMPTY_VALUE;

   for(int k = 0; k < period; ++k)
   {
      if(data[index + k] == EMPTY_VALUE)
         return EMPTY_VALUE;
   }

   if(method == MA_SMA)
   {
      double sum = 0.0;
      for(int i = 0; i < period; i++)
         sum += data[index + i];
      return sum / period;
   }
   else if(method == MA_LWMA)
   {
      double sum     = 0.0;
      double weights = 0.0;

      for(int i = 0; i < period; i++)
      {
         double w  = period - i;
         sum      += data[index + i] * w;
         weights  += w;
      }
      return sum / weights;
   }

   return EMPTY_VALUE;
}
//+------------------------------------------------------------------+