RSI MAKER

 

I want my indicator to mark all bearish candles that have RSI below 30 and all bullish candles that have RSI above 70. I'm not sure where the issue is.


//+------------------------------------------------------------------+
//|                                                     RSI_Marker.mq5 |
//|                        Custom indicator that marks candles based  |
//|                        on RSI levels with dots                    |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

//--- plot Bulls
#property indicator_label1  "Bulls"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrGreen
#property indicator_width1  1

//--- plot Bears
#property indicator_label2  "Bears"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  1

//--- indicator buffers
double BullsBuffer[];
double BearsBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Indicator buffers mapping
   SetIndexBuffer(0, BullsBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, BearsBuffer, INDICATOR_DATA);

   // Setting arrow codes
   PlotIndexSetInteger(0, PLOT_ARROW, 233); // Small up arrow
   PlotIndexSetInteger(1, PLOT_ARROW, 234); // Small down arrow

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
   // Variable to store RSI values
   double rsi[];
   ArraySetAsSeries(rsi, true);

   // Calculate RSI
   int rsiPeriod = 14; // RSI period
   if (CopyBuffer(iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE), 0, 0, rates_total, rsi) <= 0)
      return 0;

   // Marking conditions
   for (int i = prev_calculated; i < rates_total; i++)
   {
      BullsBuffer[i] = EMPTY_VALUE;
      BearsBuffer[i] = EMPTY_VALUE;

      // Bullish condition: RSI above 70 and close > open
      if (rsi[i] > 70 && close[i] > open[i])
      {
         BullsBuffer[i] = high[i] + 10 * _Point;
         BullsBuffer[i+1] = EMPTY_VALUE; // Clear previous arrow if any
      }

      // Bearish condition: RSI below 30 and close < open
      if (rsi[i] < 30 && close[i] < open[i])
      {
         BearsBuffer[i] = low[i] - 10 * _Point;
         BearsBuffer[i+1] = EMPTY_VALUE; // Clear previous arrow if any
      }
   }

   return(rates_total);
}
//+------------------------------------------------------------------+
 
   if (CopyBuffer(iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE), 0, 0, rates_total, rsi) <= 0)

Perhaps you should read the manual, especially the examples.
   How To Ask Questions The Smart Way. (2004)
      How To Interpret Answers.
         RTFM and STFW: How To Tell You've Seriously Screwed Up.

They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate/OnStart (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
          Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
          Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
          How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
          How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
          MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
          How to call indicators in MQL5 - MQL5 Articles (2010)

 

I think you have some logic back to front here. Bear condition is believed to be when you move below 70, and bull condition is believed to be when it is moving above 30.


//+------------------------------------------------------------------+
//|                                                     RSI_Marker.mq5 |
//|                        Custom indicator that marks candles based  |
//|                        on RSI levels with dots                    |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   2

//--- plot Bulls
#property indicator_label1  "Bulls"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrGreen
#property indicator_width1  1

//--- plot Bears
#property indicator_label2  "Bears"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  1

//--- indicator buffers
double BullsBuffer[];
double BearsBuffer[];


double rsi[]; // Variable to store RSI values

input int rsiPeriod = 14; // RSI period

int rsi_handle = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Indicator buffers mapping
   SetIndexBuffer(0, BullsBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, BearsBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, rsi, INDICATOR_CALCULATIONS);
   
   // Setting arrow codes
   PlotIndexSetInteger(0, PLOT_ARROW, 233); // Small up arrow
   PlotIndexSetInteger(1, PLOT_ARROW, 234); // Small down arrow
   
   rsi_handle = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE);
   
   ChartIndicatorAdd(ChartID(), 1, rsi_handle);
   
   return(INIT_SUCCEEDED);
}


   
//+------------------------------------------------------------------+
//| 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[])
{

   //ArraySetAsSeries(rsi, true); // don't set this to series, you set all buffers to series or none to series (else the data won't be synced)

   // Calculate RSI
   if (CopyBuffer(rsi_handle, 0, 0, rates_total, rsi) <= 0)
      return 0;

   // Marking conditions
   for (int i = prev_calculated; i < rates_total; i++)
   {
      BullsBuffer[i] = EMPTY_VALUE;
      BearsBuffer[i] = EMPTY_VALUE;

      // Bullish condition: RSI above 70 and close > open
      if (rsi[i] > 70 && close[i] > open[i])
      {
         BullsBuffer[i] = high[i] + 10 * _Point;
         BullsBuffer[i+1] = EMPTY_VALUE; // Clear previous arrow if any
      }

      // Bearish condition: RSI below 30 and close < open
      if (rsi[i] < 30 && close[i] < open[i])
      {
         BearsBuffer[i] = low[i] - 10 * _Point;
         BearsBuffer[i+1] = EMPTY_VALUE; // Clear previous arrow if any
      }

      // How I would make the logic:
      // Bear condition: RSI moving B-LOW 70 and close < open
//      if (i-1 > 0 && rsi[i] < 70 && rsi[i-1] > 70)
//      {
//         BearsBuffer[i] = low[i] - 10 * _Point;
//         BearsBuffer[i+1] = EMPTY_VALUE; // Clear previous arrow if any
//
//      }
//
//      // Bull condition: RSI moving ABOVE 30 and close > open
//      if (i-1 > 0 && rsi[i] > 30 && rsi[i-1] < 30)
//      {
//         BullsBuffer[i] = high[i] + 10 * _Point;
//         BullsBuffer[i+1] = EMPTY_VALUE; // Clear previous arrow if any
//      }      
      
   }

   return(rates_total);
}
//+------------------------------------------------------------------+
 
to state the main fault in one statement - you were setting the RSI buffer to series, and you should not