Create RSI Average Indicator - Average does not plot

 

Hi,

Essentially I am using the following RSI periods:

  • 10,14,21

Now I want to create three plots using the averages from the three periods as follows:

  • Values of  (10 + 14 + 21) / 3 (For example)
  • Then take the average of this and add it to an array at position [i]

This is all relatively straight forward as you will see in the code I have added. However the issue I am now experiencing is that the band for the average is not plotting.
Any advice would be appreciated. 

Code:

//+------------------------------------------------------------------+
//|                                             Multi_Period_RSI.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//////////////////////////////////////////////////////////////////////
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
#property indicator_levelcolor clrWhite
#property indicator_levelstyle STYLE_DOT
#property indicator_buffers 10
#property indicator_plots   4

//--- plot Period - 10
#property indicator_label1  "10"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrPink
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Period - 14
#property indicator_label2  "14"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot Period - 21
#property indicator_label3  "21"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrDodgerBlue
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//--- plot Average
#property indicator_label4  "Average"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrGold
#property indicator_style4  STYLE_SOLID
#property indicator_width4  3
//--- input parameters

input int   inpPeriod1    = 10;             // RSI 1 Period
input int   inpPeriod2    = 14;             // RSI 2 Period
input int   inpPeriod3    = 21;             // RSI 3  Period

// Buffers for short term RSI
double    ShortRSIBuffer[];
double    ExtShortPosBuffer[];
double    ExtShortNegBuffer[];

// Buffers for medium term RSI
double    MediumRSIBuffer[];
double    ExtMediumPosBuffer[];
double    ExtMediumNegBuffer[];

// Buffers for long term RSI
double    LongRSIBuffer[];
double    ExtLongPosBuffer[];
double    ExtLongNegBuffer[];

//--- Average RSI Indicator Buffer
double    ExtRSIBuffer[];

// Price Buffers

double    Prices[];

int       ExtShortPeriodRSI;
int       ExtMediumPeriodRSI;
int       ExtLongPeriodRSI;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input
   if(inpPeriod1<1 || inpPeriod2<1 || inpPeriod3<1)
     {
      ExtShortPeriodRSI  = 10;
      ExtMediumPeriodRSI = 14;
      ExtLongPeriodRSI   = 21;
      PrintFormat("Incorrect value for input variables InpPeriodRSI = %d || %d || %d. Indicator will use value %d || %d || %d for calculations.",
                  inpPeriod1,inpPeriod2,inpPeriod3,ExtShortPeriodRSI,ExtMediumPeriodRSI,ExtLongPeriodRSI);
     }
   else
     {
      ExtShortPeriodRSI=inpPeriod1;
      ExtMediumPeriodRSI=inpPeriod2;
      ExtLongPeriodRSI=inpPeriod3;
     }

//--- indicator buffers mapping

   SetIndexBuffer(0,ShortRSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtShortPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,ExtShortNegBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,MediumRSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,ExtMediumPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,ExtMediumNegBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,LongRSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(7,ExtLongPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(8,ExtLongNegBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(9,ExtRSIBuffer,INDICATOR_DATA);

//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtShortPeriodRSI);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtMediumPeriodRSI);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtLongPeriodRSI);

//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtShortPeriodRSI)+")");
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtMediumPeriodRSI)+")");
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtLongPeriodRSI)+")");

  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   if(rates_total<=ExtShortPeriodRSI || rates_total<=ExtMediumPeriodRSI || rates_total<=ExtLongPeriodRSI)
      return(0);
//--- preliminary calculations

   int prices_total = ArraySize(price);
   for(int i = rates_total-1 ; i>=0 ; i--){
      Prices[i] = price[i];
   }

   CreateRsiBuffers(prev_calculated, rates_total,ShortRSIBuffer,ExtShortPosBuffer,ExtShortNegBuffer,ExtShortPeriodRSI);
   CreateRsiBuffers(prev_calculated, rates_total,MediumRSIBuffer,ExtMediumPosBuffer,ExtMediumNegBuffer,ExtMediumPeriodRSI);
   CreateRsiBuffers(prev_calculated, rates_total,LongRSIBuffer,ExtLongPosBuffer,ExtLongNegBuffer,ExtLongPeriodRSI);
   CreateAverageRsiBuffer(prev_calculated,ExtRSIBuffer);
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

void CreateRsiBuffers(int pre_calculated, int bars_total ,double &MainBuffer[],double &PosBuffer[],double &NegBuffer[],int RsiPeriod){
   int pos=pre_calculated-1;
   int rates_total = bars_total;
   if(!rates_total > 0) return;
   if(pos<=RsiPeriod)
     {
      double sum_pos=0.0;
      double sum_neg=0.0;
      //--- first RSIPeriod values of the indicator are not calculated
      MainBuffer[0]=0.0;
      PosBuffer[0]=0.0;
      NegBuffer[0]=0.0;
      for(int i=1; i<=RsiPeriod; i++)
        {
         MainBuffer[i]=0.0;
         PosBuffer[i]=0.0;
         NegBuffer[i]=0.0;
         double diff=Prices[i]-Prices[i-1];
         sum_pos+=(diff>0?diff:0);
         sum_neg+=(diff<0?-diff:0);
        }
      //--- calculate first visible value
      PosBuffer[RsiPeriod]=sum_pos/RsiPeriod;
      NegBuffer[RsiPeriod]=sum_neg/RsiPeriod;
      if(NegBuffer[RsiPeriod]!=0.0)
         MainBuffer[RsiPeriod]=100.0-(100.0/(1.0+PosBuffer[RsiPeriod]/NegBuffer[RsiPeriod]));
      else
        {
         if(PosBuffer[RsiPeriod]!=0.0)
            MainBuffer[RsiPeriod]=100.0;
         else
            MainBuffer[RsiPeriod]=50.0;
        }
      //--- prepare the position value for main calculation
      pos=RsiPeriod+1;
     }
//--- the main loop of calculations
   for(int i=pos; i<rates_total && !IsStopped(); i++)
     {
      double diff=Prices[i]-Prices[i-1];
      PosBuffer[i]=(PosBuffer[i-1]*(RsiPeriod-1)+(diff>0.0?diff:0.0))/RsiPeriod;
      NegBuffer[i]=(NegBuffer[i-1]*(RsiPeriod-1)+(diff<0.0?-diff:0.0))/RsiPeriod;
      if(NegBuffer[i]!=0.0)
         MainBuffer[i]=100.0-100.0/(1+PosBuffer[i]/NegBuffer[i]);
      else
        {
         if(NegBuffer[i]!=0.0)
            MainBuffer[i]=100.0;
         else
            MainBuffer[i]=50.0;
        }
     }
}

void CreateAverageRsiBuffer(int total_bars,double &MainBuffer[]){
      if(!total_bars > 0) return;
      int buffer_size = ArraySize(ShortRSIBuffer) + ArraySize(MediumRSIBuffer) + ArraySize(LongRSIBuffer);
      if(buffer_size % 3 == 0){
         double average;
         for(int i = buffer_size - 1;i >= 0;i--){
            average = (ShortRSIBuffer[i] + MediumRSIBuffer[i] + LongRSIBuffer[i]) / 3;
            ExtRSIBuffer[i] = average;
         }
      }
}
 
// Price Buffers
double    Prices[];
⋮
   int prices_total = ArraySize(price);
   for(int i = rates_total-1 ; i>=0 ; i--){
      Prices[i] = price[i];
  1. The array Prices has no size. First tick array exceeded, indicator crashes.
  2. Why the copy?
 
William Roeder #:
  1. The array Prices has no size. First tick array exceeded, indicator crashes.
  2. Why the copy?

If you are referring to the copy of the Prices array. When I would attempt to use it as a parameter for the CreateAverageRsiBuffer() function. It would not accept it as a reference. Hence I opted to use that instead.

  1. Chad - Thanks
  2. Not sure what you mean by the copy?


If you are referring to the "duplicate post". The original was deleted and updated to specifically cater to the revised version of the code whilst trying to avoid redundant comments about the old code. Additionally it had received no responses (More than likely due to the 4th of July holiday weekend) and I did not want it to be overlooked.

CURRENT ISSUE:

The RSI indicator value at position [0] sets to 0. I understand why but how would I go about fixing this? Essentially it basically falls of the screen if that makes sense?

How would I got about fixing this?

Thanks