RSI + BB + EMA

 

I took my own crack at coding today. This is supposed to be an indicator that connects BB and an EMA to the RSI indicator data that will be displayed in one indicator window.

However, after fixing all of the errors Meta Editor has given me, the indicator window shows up blank on my chart.

When I look at the data window, the value just shows 10.000000000.

What seems to be the problem? is it just crap code or what? 


//+------------------------------------------------------------------+
//|                                                     RSI_BB_MA.mq5 |
//|                                  Script to plot RSI, BB and an ema|
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrAqua             // RSI color
#property indicator_color2 clrMediumVioletRed  // Upper BB color
#property indicator_color3 clrMediumVioletRed  // Lower BB color
#property indicator_color4 clrBlack            // Moving Average color

// Input parameters for customization
input int   RSI_Period = 14;
input int   BB_Period = 20;
input double BB_Deviation = 2.0;
input int   BB_Shift = 2;
input int   MA_Period = 7;
input ENUM_MA_METHOD MA_Method = MODE_EMA; // Moving average method

// Buffers to store indicator values
double RSI_Buffer[];
double BB_Upper_Buffer[];
double BB_Lower_Buffer[];
double MA_Buffer[];

// Indicator handles for RSI and MA
int RSI_Handle, MA_Handle;

// Initialization function
int OnInit()
{
   // Set buffer properties
   SetIndexBuffer(0, RSI_Buffer);    // RSI line
   SetIndexBuffer(1, BB_Upper_Buffer);  // Upper BB line
   SetIndexBuffer(2, BB_Lower_Buffer);  // Lower BB line
   SetIndexBuffer(3, MA_Buffer);        // Moving average line
   
    // Set indicator labels
   string short_name = "RSI(" + IntegerToString(RSI_Period) + 
                       ") + BB(" + IntegerToString(BB_Period) + 
                       "," + DoubleToString(BB_Deviation, 1) + 
                       "," + IntegerToString(BB_Shift) + 
                       ") + MA(" + IntegerToString(MA_Period) + ")";
                 
   return INIT_SUCCEEDED;
}

// Calculation 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[])
{
   // Check if there are enough bars for calculation
   if (rates_total < MathMax(RSI_Period, MathMax(BB_Period, MA_Period)))
      return 0;

   // Calculate RSI
   for (int i = prev_calculated; i < rates_total; i++)
   {
      RSI_Buffer[i] = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
      Print("RSI_Buffer[", i, "] = ", RSI_Buffer[i]); // Debug output
   }

   // Calculate Bollinger Bands on RSI
   for (int i = MathMax(BB_Period, prev_calculated); i < rates_total; i++)
   {
   
      double sum = 0.0;
      for (int j = 0; j < BB_Period; j++)
      {
         sum += RSI_Buffer[i - j];
      }
      double average = sum / BB_Period;

      double stddev_sum = 0.0;
      for (int j = 0; j < BB_Period; j++)
      {
         stddev_sum += MathPow(RSI_Buffer[i - j] - average, 2);
      }
      double stddev = MathSqrt(stddev_sum / BB_Period);
      
      //Shift Logic
      int shifted_index = i + BB_Shift; // Apply the shift
      
      if (shifted_index < rates_total) // Ensure not out of bounds
      {
      BB_Upper_Buffer[shifted_index] = average + BB_Deviation * stddev;
      BB_Lower_Buffer[shifted_index] = average - BB_Deviation * stddev;
      
   
   // Debug output for Bollinger Bands
   Print("BB_Upper_Buffer[", shifted_index, "] = ", BB_Upper_Buffer[shifted_index]);
   Print("BB_Lower_Buffer[", shifted_index, "] = ", BB_Lower_Buffer[shifted_index]);
      }
 }

   // Calculate the Moving Average on the RSI manually
   if (MA_Method == MODE_SMA) // Simple Moving Average
   {
   for (int i = MA_Period - 1; i < rates_total; i++)
   {
   
      // (Calculation Logic...)
      Print("MA_Buffer[", i, "] = ", MA_Buffer[i]); // Debug output
      
      
      double sum = 0.0; //correct variable name
      for (int j = 0; j < MA_Period; j++) 
      {
         sum += RSI_Buffer[i-j];  //correct variable usage
      }
      MA_Buffer[i] = sum / MA_Period; // Assign to MA_Buffer
   }
 }

 else if (MA_Method == MODE_EMA) // Exponential Moving Average
 {
   double multiplier = 2.0 / (MA_Period + 1);
   
   MA_Buffer[MA_Period - 1] = RSI_Buffer[MA_Period - 1]; // Start EMA from SMA value
   
   for (int i = MA_Period; i < rates_total; i++)
   {
      MA_Buffer[i] = (RSI_Buffer[i] - MA_Buffer[i - 1]) * multiplier + MA_Buffer[i - 1];
   }
 }
 return rates_total;
 
 }
 

It seems you are relying on ChatGPT. Don't!

Instead, reference the documentation or the book.

Indicator functions return a handle, not the buffer data. You do in fact declare handles, but then don't assign me. A clear sign that you are using ChatGPT for the skeleton code.

// Indicator handles for RSI and MA
int RSI_Handle, MA_Handle;

Please read the documentation for iRSI() and the CopyBuffer() function to retrieve the buffer values.

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
Gets data of a specified buffer of a certain indicator in the necessary quantity. Counting of elements of copied data (indicator buffer with the...
 

Hi

In mql5 the functions for indicators like iRSI, iMA etc, return only handle for the indicator values. You should initialize those handles in the OnInit function and then use CopyBuffer  to get the data from chosen index. So move iRSI to the OnInit and in the OnCalculate use this instead:

RSI_Buffer[i]=getRSI(i);

double getRSI(int i){

   double res[];

   ResetLastError();

   if(CopyBuffer(RSI_Handle, 0, i,1,res)<0 ){

      Print("Error copying RSI data for buffer - error:"+IntegerToString(GetLastError())+"!!");

      return(0);

   }

   return(norm(res[0]));

}

Have a nice day👍📊