//+------------------------------------------------------------------+
//| RSI + Support Resistance Reversal Indicator (MT5)               |
//| BUY: RSI<=30 + Support                                          |
//| SELL: RSI>=70 + Resistance                                      |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLime
#property indicator_width1  2
#property indicator_label1  "BUY"

#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  2
#property indicator_label2  "SELL"

//---- Inputs
input int    RSI_Period     = 14;
input double RSI_Oversold   = 30.0;
input double RSI_Overbought = 70.0;
input int    SR_Lookback    = 50;
input int    Arrow_Points   = 40;

//---- Buffers
double BuyBuffer[];
double SellBuffer[];

int rsiHandle;

//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, SellBuffer, INDICATOR_DATA);

   PlotIndexSetInteger(0, PLOT_ARROW, 233);
   PlotIndexSetInteger(1, PLOT_ARROW, 234);

   ArrayInitialize(BuyBuffer, EMPTY_VALUE);
   ArrayInitialize(SellBuffer, EMPTY_VALUE);

   rsiHandle = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE);
   if(rsiHandle == INVALID_HANDLE)
      return INIT_FAILED;

   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
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 < SR_Lookback + 5)
      return 0;

   double rsi[];
   ArraySetAsSeries(rsi, true);
   CopyBuffer(rsiHandle, 0, 0, rates_total, rsi);

   for(int i = rates_total - SR_Lookback - 1; i >= 1; i--)
   {
      BuyBuffer[i]  = EMPTY_VALUE;
      SellBuffer[i] = EMPTY_VALUE;

      //---- Calculate Support & Resistance from PREVIOUS candles
      double support    = low[i+1];
      double resistance = high[i+1];

      for(int j = i+1; j <= i + SR_Lookback; j++)
      {
         if(low[j] < support) support = low[j];
         if(high[j] > resistance) resistance = high[j];
      }

      //---- BUY: RSI oversold + Support
      if(rsi[i] <= RSI_Oversold &&
         low[i] <= support)
      {
         BuyBuffer[i] = low[i] - Arrow_Points * _Point;
      }

      //---- SELL: RSI overbought + Resistance
      if(rsi[i] >= RSI_Overbought &&
         high[i] >= resistance)
      {
         SellBuffer[i] = high[i] + Arrow_Points * _Point;
      }
   }

   DrawZones(time, high, low);
   return rates_total;
}

//+------------------------------------------------------------------+
void DrawZones(const datetime &time[],
               const double &high[],
               const double &low[])
{
   ObjectDelete(0, "SR_SUPPORT_ZONE");
   ObjectDelete(0, "SR_RESIST_ZONE");

   double support    = low[1];
   double resistance = high[1];

   for(int i = 1; i <= SR_Lookback; i++)
   {
      if(low[i] < support) support = low[i];
      if(high[i] > resistance) resistance = high[i];
   }

   datetime t1 = time[SR_Lookback];
   datetime t2 = time[0];

   ObjectCreate(0, "SR_SUPPORT_ZONE", OBJ_RECTANGLE, 0,
                t1, support,
                t2, support + 20 * _Point);
   ObjectSetInteger(0, "SR_SUPPORT_ZONE", OBJPROP_COLOR, clrGreen);
   ObjectSetInteger(0, "SR_SUPPORT_ZONE", OBJPROP_BACK, true);

   ObjectCreate(0, "SR_RESIST_ZONE", OBJ_RECTANGLE, 0,
                t1, resistance,
                t2, resistance - 20 * _Point);
   ObjectSetInteger(0, "SR_RESIST_ZONE", OBJPROP_COLOR, clrRed);
   ObjectSetInteger(0, "SR_RESIST_ZONE", OBJPROP_BACK, true);
}
