[CODE Help] RSI + BB + MA

shanmugapradeep

Active Trader
Dec 18, 2020
141
8
34
39
I am trying to make a Indicator based on the strategy which i shared on this platform here : https://www.earnforex.com/forum/thr...-reversal-strategy-with-an-80-win-rate.51781/

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 :

1743946943252.png

I want like this :

1743947288842.png

My Code :

MQL4:
//+------------------------------------------------------------------+
//| 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 :

MQL4:
//+------------------------------------------------------------------+
//| 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 :

MQL4:
// 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;
  }
//+------------------------------------------------------------------+
 
Still waiting for Help! for RSI 🙁. I have added more. it will show many trades are win and how many lose

Updated Code :


MQL4:
// 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 __IndicatorSettings__ = "***Indicator Settings***";
extern int CheckCandlePL = 10;
 
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);
  }
 
// 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;
 
   if(prev_calculated == 0)   // Reset only on the first calculation
     {
      totalSignals = 0;
      buySignals = 0;
      sellSignals = 0;
      signalCount = 0;  // Reset signal history counter
     }
   int result = rates_total;
 
   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] = open[i];
         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] = open[i];
         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;
        }
     }
 
   int historyDays = Period() * Bars / 1440; // Calculate days based on available bars
   Comment("Total Signals: ", totalSignals,
           "\nBuy Signals: ", buySignals,
           "\nSell Signals: ", sellSignals,
           "\nDays of History: ", historyDays);
 
   UpdatePanel();  // Update the panel with new signals
   CheckSignalOutcome();
   return rates_total;
  }
 
// 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, 50);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_XSIZE, 400);
   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));
     }
 
// Calculate panel height dynamically based on signal count
   int panelHeight = 60 + (signalCount * BUTTON_HEIGHT);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_YSIZE, panelHeight);
 
// Create new buttons for each signal
   for(int i = 0; i < signalCount; 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, 60 + (i * BUTTON_HEIGHT));
      ObjectSetInteger(0, btnName, OBJPROP_XSIZE, 350-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);
     }
  }
 
// 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;
  }
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CheckSignalOutcome()
  {
   int CheckCandle = CheckCandlePL;
   for(int i = 0; i < signalCount; i++)
     {
      int shift = iBarShift(NULL, 0, signalHistory[i].time);
      if(shift < 0 || shift + CheckCandle >= Bars)
         continue;
 
      bool won = false;
      double maxMove = signalHistory[i].price;
      double minMove = signalHistory[i].price;
 
      if(signalHistory[i].isBuy)
        {
         for(int j = 1; j <= CheckCandle; j++)
           {
            if(Close[shift - j] > maxMove)
               maxMove = Close[shift - j];
            if(Close[shift - j] < minMove)
               minMove = Close[shift - j];
           }
         won = (maxMove > signalHistory[i].price);
        }
      else // Sell signal
        {
         for(int k = 1; k <= CheckCandle; k++)
           {
            if(Close[shift - k] < minMove)
               minMove = Close[shift - k];
            if(Close[shift - k] > maxMove)
               maxMove = Close[shift - k];
           }
         won = (minMove < signalHistory[i].price);
        }
 
      double pointsMoved = (won ? (maxMove - signalHistory[i].price) : (signalHistory[i].price - minMove)) / Point;
 
      string resultText = TimeToString(signalHistory[i].time, TIME_DATE|TIME_MINUTES) + " - " +
                          (signalHistory[i].isBuy ? "Buy" : "Sell") + " @ " +
                          DoubleToString(signalHistory[i].price, 4) + " - " +
                          (won ? "Win" : "Lose") + " (" + DoubleToString(pointsMoved, 1) + " points)";
 
      ObjectSetString(0, "SignalBtn" + IntegerToString(i), OBJPROP_TEXT, resultText);
      ObjectSetInteger(0, "SignalBtn" + IntegerToString(i), OBJPROP_BGCOLOR, won ? clrBlue : clrRed);
     }
  }
//+------------------------------------------------------------------+
 
Updated Code :

MQL4:
// 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 __IndicatorSettings__ = "***Indicator Settings***";
extern int CheckCandlePL = 10;
 
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);
  }
 
// 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;
 
   if(prev_calculated == 0)   // Reset only on the first calculation
     {
      totalSignals = 0;
      buySignals = 0;
      sellSignals = 0;
      signalCount = 0;  // Reset signal history counter
     }
   int result = rates_total;
 
   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] = open[i];
         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] = open[i];
         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;
        }
     }
 
   int historyDays = Period() * Bars / 1440; // Calculate days based on available bars
   Comment("Total Signals: ", totalSignals,
           "\nBuy Signals: ", buySignals,
           "\nSell Signals: ", sellSignals,
           "\nDays of History: ", historyDays);
 
   UpdatePanel();  // Update the panel with new signals
   CheckSignalOutcome();
   return rates_total;
  }
 
// 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, 50);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_XSIZE, 400);
   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));
     }
 
// Calculate panel height dynamically based on signal count
   int panelHeight = 60 + (signalCount * BUTTON_HEIGHT);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_YSIZE, panelHeight);
 
// Create new buttons for each signal
   for(int i = 0; i < signalCount; 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, 60 + (i * BUTTON_HEIGHT));
      ObjectSetInteger(0, btnName, OBJPROP_XSIZE, 350-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, Digits);
      ObjectSetString(0, btnName, OBJPROP_TEXT, signalText);
      ObjectSetInteger(0, btnName, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, btnName, OBJPROP_BGCOLOR, signalHistory[i].isBuy ? clrGreen : clrRed);
     }
  }
 
// 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;
  }
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CheckSignalOutcome()
  {
   int CheckCandle = CheckCandlePL;
   for(int i = 0; i < signalCount; i++)
     {
      int shift = iBarShift(NULL, 0, signalHistory[i].time);
      if(shift < 0 || shift + CheckCandle >= Bars)
         continue;
 
      bool won = false;
      double maxMove = signalHistory[i].price;
      double minMove = signalHistory[i].price;
 
      if(signalHistory[i].isBuy)
        {
         for(int j = 1; j <= CheckCandle; j++)
           {
            if(Close[shift - j] > maxMove)
               maxMove = Close[shift - j];
            if(Close[shift - j] < minMove)
               minMove = Close[shift - j];
           }
         won = (maxMove > signalHistory[i].price);
        }
      else // Sell signal
        {
         for(int k = 1; k <= CheckCandle; k++)
           {
            if(Close[shift - k] < minMove)
               minMove = Close[shift - k];
            if(Close[shift - k] > maxMove)
               maxMove = Close[shift - k];
           }
         won = (minMove < signalHistory[i].price);
        }
 
      double pointsMoved = (won ? (maxMove - signalHistory[i].price) : (signalHistory[i].price - minMove)) / Point;
 
      string resultText = TimeToString(signalHistory[i].time, TIME_DATE|TIME_MINUTES) + " - " +
                          (signalHistory[i].isBuy ? "Buy" : "Sell") + " @ " +
                          DoubleToString(signalHistory[i].price, Digits) + " - " +
                          (won ? "Win" : "Lose") + " (" + DoubleToString(pointsMoved,0) + " points)";
 
      ObjectSetString(0, "SignalBtn" + IntegerToString(i), OBJPROP_TEXT, resultText);
      ObjectSetInteger(0, "SignalBtn" + IntegerToString(i), OBJPROP_BGCOLOR, won && signalHistory[i].isBuy ? clrGreen : !won && signalHistory[i].isBuy ? clrLightGreen : won && !signalHistory[i].isBuy ? clrRed : clrOrangeRed);
     }
  }
//+------------------------------------------------------------------+
 
You cannot have one indicator showing calculations in both the main chart window and the separate chart window. Use separate indicators for that. In fact, those three (RSI, Bollinger bands, and MA) are all standard indicators. You don't need to make your custom indicator display them - just add the standard ones to the chart for display and focus your custom one on producing the combined signals.
 
You cannot have one indicator showing calculations in both the main chart window and the separate chart window. Use separate indicators for that. In fact, those three (RSI, Bollinger bands, and MA) are all standard indicators. You don't need to make your custom indicator display them - just add the standard ones to the chart for display and focus your custom one on producing the combined signals.
So, you mean to say. i just need to add Signal and Panel in my indicator and use remaining from other indicator?.

As per your recommendation, i have cleaned the indicator :

MQL4:
//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2018, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime  // Green UP Arrow for Buy Signal
#property indicator_color2 OrangeRed   // Red DOWN Arrow for Sell Signal
// 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;
 
// Indicator Buffers
double BuySignal[];
double SellSignal[];
 
// Counters for signals
int totalSignals = 0;
int buySignals = 0;
int sellSignals = 0;
 
// Input Parameters
extern string __IndicatorSettings__ = "***Indicator Settings***";
extern int CheckCandlePL = 10;
 
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);
 
   SetIndexStyle(0, DRAW_ARROW, 2, 2);
   SetIndexStyle(1, DRAW_ARROW, 2, 2);
 
   SetIndexArrow(0, 233);
   SetIndexArrow(1, 234);
 
   CreatePanel();  // Create the panel when indicator initializes
 
   return(INIT_SUCCEEDED);
  }
 
// 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;
 
   if(prev_calculated == 0)   // Reset only on the first calculation
     {
      totalSignals = 0;
      buySignals = 0;
      sellSignals = 0;
      signalCount = 0;  // Reset signal history counter
     }
   int result = rates_total;
 
   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);
 
      // Sell Signal
      if(rsi > RSI_UpLevel && open[i] > bbUpper && open[i] < ma)
        {
         SellSignal[i] = open[i];
         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] = open[i];
         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;
        }
     }
 
   int historyDays = Period() * Bars / 1440; // Calculate days based on available bars
   Comment("Total Signals: ", totalSignals,
           "\nBuy Signals: ", buySignals,
           "\nSell Signals: ", sellSignals,
           "\nDays of History: ", historyDays);
 
   UpdatePanel();  // Update the panel with new signals
   CheckSignalOutcome();
   return rates_total;
  }
 
// 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, 50);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_XSIZE, 400);
   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));
     }
 
// Calculate panel height dynamically based on signal count
   int panelHeight = 60 + (signalCount * BUTTON_HEIGHT);
   ObjectSetInteger(0, "SignalPanel", OBJPROP_YSIZE, panelHeight);
 
// Create new buttons for each signal
   for(int i = 0; i < signalCount; 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, 60 + (i * BUTTON_HEIGHT));
      ObjectSetInteger(0, btnName, OBJPROP_XSIZE, 350-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, Digits);
      ObjectSetString(0, btnName, OBJPROP_TEXT, signalText);
      ObjectSetInteger(0, btnName, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, btnName, OBJPROP_BGCOLOR, signalHistory[i].isBuy ? clrGreen : clrRed);
     }
  }
 
// 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;
  }
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CheckSignalOutcome()
  {
   int CheckCandle = CheckCandlePL;
   for(int i = 0; i < signalCount; i++)
     {
      int shift = iBarShift(NULL, 0, signalHistory[i].time);
      if(shift < 0 || shift + CheckCandle >= Bars)
         continue;
 
      bool won = false;
      double maxMove = signalHistory[i].price;
      double minMove = signalHistory[i].price;
 
      if(signalHistory[i].isBuy)
        {
         for(int j = 1; j <= CheckCandle; j++)
           {
            if(Close[shift - j] > maxMove)
               maxMove = Close[shift - j];
            if(Close[shift - j] < minMove)
               minMove = Close[shift - j];
           }
         won = (maxMove > signalHistory[i].price);
        }
      else // Sell signal
        {
         for(int k = 1; k <= CheckCandle; k++)
           {
            if(Close[shift - k] < minMove)
               minMove = Close[shift - k];
            if(Close[shift - k] > maxMove)
               maxMove = Close[shift - k];
           }
         won = (minMove < signalHistory[i].price);
        }
 
      double pointsMoved = (won ? (maxMove - signalHistory[i].price) : (signalHistory[i].price - minMove)) / Point;
 
      string resultText = TimeToString(signalHistory[i].time, TIME_DATE|TIME_MINUTES) + " - " +
                          (signalHistory[i].isBuy ? "Buy" : "Sell") + " @ " +
                          DoubleToString(signalHistory[i].price, Digits) + " - " +
                          (won ? "Win" : "Lose") + " (" + DoubleToString(pointsMoved,0) + " points)";
 
      ObjectSetString(0, "SignalBtn" + IntegerToString(i), OBJPROP_TEXT, resultText);
      ObjectSetInteger(0, "SignalBtn" + IntegerToString(i), OBJPROP_BGCOLOR, won && signalHistory[i].isBuy ? clrGreen : !won && signalHistory[i].isBuy ? clrLightGreen : won && !signalHistory[i].isBuy ? clrRed : clrOrangeRed);
     }
  }
//+------------------------------------------------------------------+
 
//+------------------------------------------------------------------+

Problem :

If there is several signals, many signals not displaying in panel because it getting out of the screen. Can we add any scroll option in object panel? or any alternative solution?

1744024401729.png
 
Last edited: