[CODE Help] RSI + BB + MA Indicator

 

I am trying to make a Indicator based on the RSI + BollingerBands + MA

My Indicator doing great job by creating Arrows and Vertical line for Signal when matching the conditions but the problem is it not showing RSI, Bollinger Bands and MA in Chart.


Currently it showing like this :



I want like this :


My Code :


//+------------------------------------------------------------------+
//| Custom Indicator based on RSI, Moving Average, and Bollinger Bands |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime  // Green UP Arrow for Buy Signal
#property indicator_color2 Red   // Red DOWN Arrow for Sell Signal

// Indicator Buffers
double BuySignal[];
double SellSignal[];

// Input Parameters
extern string __RSI_Indicator__ = "***RSI Indicator Settings***";
extern ENUM_APPLIED_PRICE RSI_AppliedPrice = PRICE_CLOSE;
extern int RSI_Period = 14;
extern int RSI_UpLevel = 80;
extern int RSI_BelowLevel = 20;

extern string __BollingerBands_Indicator__ = "***Bollinger Bands Indicator Settings***";
extern ENUM_APPLIED_PRICE BollingerBands_AppliedPrice = PRICE_CLOSE;
extern int BollingerBands_Period = 20;
extern double BollingerBands_deviation = 2.0;
extern int BollingerBands_BandShift = 0;

extern string __MovingAverage_Indicator__ = "***Moving Average Indicator Settings***";
extern ENUM_MA_METHOD MovingAverage_Method = MODE_EMA;
extern ENUM_APPLIED_PRICE MovingAverage_AppliedPrice = PRICE_CLOSE;
extern int MovingAverage_Period = 200;
extern int MovingAverage_MAShift = 0;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, BuySignal);
   SetIndexBuffer(1, SellSignal);
   
   SetIndexStyle(0, DRAW_ARROW, 2, 2);
   SetIndexStyle(1, DRAW_ARROW, 2, 2);
   
   SetIndexArrow(0, 233); // Green Up Arrow
   SetIndexArrow(1, 234); // Red 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[])
{
   if (rates_total < BollingerBands_Period || rates_total < RSI_Period || rates_total < MovingAverage_Period) return 0;
   
   for (int i = prev_calculated; i < rates_total - 1; i++)
   {
      double rsi = iRSI(NULL, 0, RSI_Period, RSI_AppliedPrice, i);
      double ma = iMA(NULL, 0, MovingAverage_Period, MovingAverage_MAShift, MovingAverage_Method, MovingAverage_AppliedPrice, i);
      double bbUpper = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_UPPER, i);
      double bbLower = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_LOWER, i);
      
      double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
      double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
      
      // Sell Condition
      if (rsi > RSI_UpLevel && bid > bbUpper && ask < ma)
      {
         SellSignal[i] = high[i] + Point * 20;
         ObjectCreate(0, "SellLine" + IntegerToString(i), OBJ_VLINE, 0, time[i], 0);
         ObjectSetInteger(0, "SellLine" + IntegerToString(i), OBJPROP_COLOR, Red);
      }
      else
      {
         SellSignal[i] = EMPTY_VALUE;
      }
      
      // Buy Condition
      if (rsi < RSI_BelowLevel && ask < bbLower && bid > ma)
      {
         BuySignal[i] = low[i] - Point * 20; // Place Green Arrow below candle low
         ObjectCreate(0, "BuyLine" + IntegerToString(i), OBJ_VLINE, 0, time[i], 0);
         ObjectSetInteger(0, "BuyLine" + IntegerToString(i), OBJPROP_COLOR, Lime);
      }
      else
      {
         BuySignal[i] = EMPTY_VALUE;
      }
   }
   return rates_total;
}
 

I made some changes and now RSI and BB showing in Main chart but i tried my best to make RSI display in separate window but always failed. when i am using #property indicator_separate_window the whole chart getting messed up.

My New Code :

//+------------------------------------------------------------------+
//| Custom Indicator based on RSI, Moving Average, and Bollinger Bands |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 Lime  // Green UP Arrow for Buy Signal
#property indicator_color2 OrangeRed   // Red DOWN Arrow for Sell Signal
#property indicator_color3 White  // Moving Average Line
#property indicator_color4 Red  // Bollinger Bands Upper
#property indicator_color5 Green  // Bollinger Bands Lower

// Indicator Buffers
double BuySignal[];
double SellSignal[];
double MA_Buffer[];
double BB_Upper_Buffer[];
double BB_Lower_Buffer[];

// Input Parameters
extern string __RSI_Indicator__ = "***RSI Indicator Settings***";
extern ENUM_APPLIED_PRICE RSI_AppliedPrice = PRICE_CLOSE;
extern int RSI_Period = 14;
extern int RSI_UpLevel = 80;
extern int RSI_BelowLevel = 20;

extern string __BollingerBands_Indicator__ = "***Bollinger Bands Indicator Settings***";
extern ENUM_APPLIED_PRICE BollingerBands_AppliedPrice = PRICE_CLOSE;
extern int BollingerBands_Period = 20;
extern double BollingerBands_deviation = 2.0;
extern int BollingerBands_BandShift = 0;

extern string __MovingAverage_Indicator__ = "***Moving Average Indicator Settings***";
extern ENUM_MA_METHOD MovingAverage_Method = MODE_EMA;
extern ENUM_APPLIED_PRICE MovingAverage_AppliedPrice = PRICE_CLOSE;
extern int MovingAverage_Period = 200;
extern int MovingAverage_MAShift = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, BuySignal);
   SetIndexBuffer(1, SellSignal);
   SetIndexBuffer(2, MA_Buffer);
   SetIndexBuffer(3, BB_Upper_Buffer);
   SetIndexBuffer(4, BB_Lower_Buffer);

   SetIndexStyle(0, DRAW_ARROW, 2, 2);
   SetIndexStyle(1, DRAW_ARROW, 2, 2);
   SetIndexStyle(2, DRAW_LINE, 1, 4); // Moving Average
   SetIndexStyle(3, DRAW_LINE, 1, 3); // Upper Bollinger Band
   SetIndexStyle(4, DRAW_LINE, 1, 3); // Lower Bollinger Band

   SetIndexArrow(0, 233); // Green Up Arrow
   SetIndexArrow(1, 234); // Red 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[])
{
   if (rates_total < BollingerBands_Period || rates_total < RSI_Period || rates_total < MovingAverage_Period) return 0;
   
   for (int i = prev_calculated; i < rates_total - 1; i++)
   {
      double rsi = iRSI(NULL, 0, RSI_Period, RSI_AppliedPrice, i);
      double ma = iMA(NULL, 0, MovingAverage_Period, MovingAverage_MAShift, MovingAverage_Method, MovingAverage_AppliedPrice, i);
      double bbUpper = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_UPPER, i);
      double bbLower = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_LOWER, i);
      
      double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
      double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);

      // Store values for MA and Bollinger Bands
      MA_Buffer[i] = ma;
      BB_Upper_Buffer[i] = bbUpper;
      BB_Lower_Buffer[i] = bbLower;
      
      // Sell Condition
      if (rsi > RSI_UpLevel && bid > bbUpper && ask < ma)
      {
         SellSignal[i] = high[i] + Point * 20;
         ObjectCreate(0, "SellLine" + IntegerToString(i), OBJ_VLINE, 0, time[i], 0);
         ObjectSetInteger(0, "SellLine" + IntegerToString(i), OBJPROP_COLOR, Red);
      }
      else
      {
         SellSignal[i] = EMPTY_VALUE;
      }
      
      // Buy Condition
      if (rsi < RSI_BelowLevel && ask < bbLower && bid > ma)
      {
         BuySignal[i] = low[i] - Point * 20;
         ObjectCreate(0, "BuyLine" + IntegerToString(i), OBJ_VLINE, 0, time[i], 0);
         ObjectSetInteger(0, "BuyLine" + IntegerToString(i), OBJPROP_COLOR, Lime);
      }
      else
      {
         BuySignal[i] = EMPTY_VALUE;
      }
   }
   return rates_total;
}
 

I made some new modification like added Actionable Panel, Total Signal count, etc. But still unable to add RSI in separate window

Updated Code :


// Add these global variables at the top of your code
#define PANEL_WIDTH  200
#define PANEL_HEIGHT 150
#define BUTTON_HEIGHT 20
#define MAX_SIGNALS  50  // Maximum signals to display

struct SignalInfo
  {
   datetime          time;
   bool              isBuy;
   double            price;
  };

SignalInfo signalHistory[MAX_SIGNALS];
int signalCount = 0;

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Lime  // Green UP Arrow for Buy Signal
#property indicator_color2 OrangeRed   // Red DOWN Arrow for Sell Signal
#property indicator_color3 White  // Moving Average Line
#property indicator_color4 Red  // Bollinger Bands Upper
#property indicator_color5 Green  // Bollinger Bands Lower
#property indicator_color6 Gray  // Bollinger Bands Lower

// Indicator Buffers
double BuySignal[];
double SellSignal[];
double MA_Buffer[];
double BB_Upper_Buffer[];
double BB_Lower_Buffer[];
double BB_Middle_Buffer[];

// Counters for signals
int totalSignals = 0;
int buySignals = 0;
int sellSignals = 0;

// Input Parameters
extern string __RSI_Indicator__ = "***RSI Indicator Settings***";
extern ENUM_APPLIED_PRICE RSI_AppliedPrice = PRICE_CLOSE;
extern int RSI_Period = 14;
extern int RSI_UpLevel = 80;
extern int RSI_BelowLevel = 20;

extern string __BollingerBands_Indicator__ = "***Bollinger Bands Indicator Settings***";
extern ENUM_APPLIED_PRICE BollingerBands_AppliedPrice = PRICE_CLOSE;
extern int BollingerBands_Period = 20;
extern double BollingerBands_deviation = 2.0;
extern int BollingerBands_BandShift = 0;

extern string __MovingAverage_Indicator__ = "***Moving Average Indicator Settings***";
extern ENUM_MA_METHOD MovingAverage_Method = MODE_EMA;
extern ENUM_APPLIED_PRICE MovingAverage_AppliedPrice = PRICE_CLOSE;
extern int MovingAverage_Period = 200;
extern int MovingAverage_MAShift = 0;

// Modified OnInit function
int OnInit()
  {
// Existing buffer initialization
   SetIndexBuffer(0, BuySignal);
   SetIndexBuffer(1, SellSignal);
   SetIndexBuffer(2, MA_Buffer);
   SetIndexBuffer(3, BB_Upper_Buffer);
   SetIndexBuffer(4, BB_Lower_Buffer);
   SetIndexBuffer(5, BB_Middle_Buffer);

   SetIndexStyle(0, DRAW_ARROW, 2, 2);
   SetIndexStyle(1, DRAW_ARROW, 2, 2);
   SetIndexStyle(2, DRAW_LINE, 1, 4);
   SetIndexStyle(3, DRAW_LINE, 1, 3);
   SetIndexStyle(4, DRAW_LINE, 1, 3);
   SetIndexStyle(5, DRAW_LINE, 2);

   SetIndexArrow(0, 233);
   SetIndexArrow(1, 234);

   CreatePanel();  // Create the panel when indicator initializes

   return(INIT_SUCCEEDED);
  }

// Function to create the panel
void CreatePanel()
  {
// Create panel background
   ObjectCreate(0, "SignalPanel", OBJ_RECTANGLE_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_XDISTANCE, 10);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_YDISTANCE, 10);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_XSIZE, PANEL_WIDTH);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_YSIZE, PANEL_HEIGHT);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_BGCOLOR, clrDarkGray);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_BORDER_TYPE, BORDER_FLAT);
  }

// Function to update panel with signals
void UpdatePanel()
  {
// Remove old buttons
   for(int j = 0; j < MAX_SIGNALS; j++)
     {
      ObjectDelete(0, "SignalBtn" + IntegerToString(j));
     }

// Create new buttons for each signal
   int visibleSignals = MathMin(signalCount, (PANEL_HEIGHT-20)/BUTTON_HEIGHT);
   for(int i = 0; i < visibleSignals; i++)
     {
      string btnName = "SignalBtn" + IntegerToString(i);
      ObjectCreate(0, btnName, OBJ_BUTTON, 0, 0, 0);
      ObjectSetInteger(0, btnName, OBJPROP_XDISTANCE, 15);
      ObjectSetInteger(0, btnName, OBJPROP_YDISTANCE, 30 + (i * BUTTON_HEIGHT));
      ObjectSetInteger(0, btnName, OBJPROP_XSIZE, PANEL_WIDTH-10);
      ObjectSetInteger(0, btnName, OBJPROP_YSIZE, BUTTON_HEIGHT-2);

      string signalText = TimeToString(signalHistory[i].time, TIME_DATE|TIME_MINUTES) + " - " +
                          (signalHistory[i].isBuy ? "Buy" : "Sell") + " @ " +
                          DoubleToString(signalHistory[i].price, 4);
      ObjectSetString(0, btnName, OBJPROP_TEXT, signalText);
      ObjectSetInteger(0, btnName, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, btnName, OBJPROP_BGCOLOR, signalHistory[i].isBuy ? clrGreen : clrRed);
     }
  }

// Modified OnCalculate 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 < BollingerBands_Period || rates_total < RSI_Period || rates_total < MovingAverage_Period)
      return 0;

   totalSignals = 0;
   buySignals = 0;
   sellSignals = 0;
   signalCount = 0;  // Reset signal history counter

   for(int i = prev_calculated; i < rates_total - 1; i++)
     {
      double rsi = iRSI(NULL, 0, RSI_Period, RSI_AppliedPrice, i);
      double ma = iMA(NULL, 0, MovingAverage_Period, MovingAverage_MAShift, MovingAverage_Method, MovingAverage_AppliedPrice, i);
      double bbUpper = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_UPPER, i);
      double bbLower = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_LOWER, i);
      double bbMiddle = iBands(NULL, 0, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice, MODE_MAIN, i);

      MA_Buffer[i] = ma;
      BB_Upper_Buffer[i] = bbUpper;
      BB_Lower_Buffer[i] = bbLower;
      BB_Middle_Buffer[i] = bbMiddle;

      // Sell Signal
      if(rsi > RSI_UpLevel && open[i] > bbUpper && open[i] < ma)
        {
         SellSignal[i] = high[i] + Point * 20;
         ObjectCreate(0, "SellLine" + IntegerToString(i), OBJ_VLINE, 0, time[i], 0);
         ObjectSetInteger(0, "SellLine" + IntegerToString(i), OBJPROP_COLOR, Red);

         if(signalCount < MAX_SIGNALS)
           {
            signalHistory[signalCount].time = time[i];
            signalHistory[signalCount].isBuy = false;
            signalHistory[signalCount].price = open[i];
            signalCount++;
           }

         sellSignals++;
         totalSignals++;
        }
      else
        {
         SellSignal[i] = EMPTY_VALUE;
        }

      // Buy Signal
      if(rsi < RSI_BelowLevel && open[i] < bbLower && open[i] > ma)
        {
         BuySignal[i] = low[i] - Point * 20;
         ObjectCreate(0, "BuyLine" + IntegerToString(i), OBJ_VLINE, 0, time[i], 0);
         ObjectSetInteger(0, "BuyLine" + IntegerToString(i), OBJPROP_COLOR, Lime);

         if(signalCount < MAX_SIGNALS)
           {
            signalHistory[signalCount].time = time[i];
            signalHistory[signalCount].isBuy = true;
            signalHistory[signalCount].price = open[i];
            signalCount++;
           }

         buySignals++;
         totalSignals++;
        }
      else
        {
         BuySignal[i] = EMPTY_VALUE;
        }
     }

   Comment("Total Signals: ", totalSignals,
           "\nBuy Signals: ", buySignals,
           "\nSell Signals: ", sellSignals);

   UpdatePanel();  // Update the panel with new signals

   return rates_total;
  }

// Handle button clicks
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      if(StringFind(sparam, "SignalBtn") == 0)
        {
         int btnIndex = StringToInteger(StringSubstr(sparam, 9));
         if(btnIndex >= 0 && btnIndex < signalCount)
           {
            ChartNavigate(0, CHART_END, -iBarShift(NULL, 0, signalHistory[btnIndex].time));
           }
        }
     }
  }

// Modified deinit function
int deinit()
  {
   ObjectsDeleteAll(0, "SellLine");
   ObjectsDeleteAll(0, "BuyLine");
   ObjectsDeleteAll(0, "SignalPanel");
   ObjectsDeleteAll(0, "SignalBtn");
   return 0;
  }
//+------------------------------------------------------------------+