MultiTimeframe MultiSymbol EA - How to handle the MQL5 Indicators?

shanmugapradeep

Master Trader
Dec 18, 2020
180
16
54
40
Hello,


I have built an multiTimeframe and MultiSymbol EA and it use 4 indicator to confirm signal across different symbol and timeframe in MQL4 and i am converting it to MQL5. I am new to MQL5 and i am facing difficult to understand how to handle the Indicators.


1. Sometime Due to Moving Average full EA get stuck


2. Sometime CopyBuffer get failed and return 0 (for all indicators)


3. When i deinit and init again by changing Timeframe my EA getting function getting broken (Until i close and reopen metatrader again).


My Code :

MQL5:
input string TradingSymbols = "EURUSD,GBPUSD,USDJPY,USDCHF,USDCAD,AUDUSD,NZDUSD,GBPCAD,EURGBP,AUDNZD,XAGUSD,XAUUSD,XAUGBP,XAUAUD,XAUEUR,XAUCAD,XAUJPY,XAUCHF,BTCUSD";
input string __TimeFrame__ = "***TimeFrame Settings***";
// ===== Minute Timeframes =====
input bool PeriodM1   = true;   // PERIOD_M1
input bool PeriodM2   = true;   // PERIOD_M2
input bool PeriodM3   = true;   // PERIOD_M3
input bool PeriodM4   = true;   // PERIOD_M4
input bool PeriodM5   = true;   // PERIOD_M5
input bool PeriodM6   = true;   // PERIOD_M6
input bool PeriodM10  = true;   // PERIOD_M10
input bool PeriodM12  = true;   // PERIOD_M12
input bool PeriodM15  = true;   // PERIOD_M15
input bool PeriodM20  = true;   // PERIOD_M20
input bool PeriodM30  = true;   // PERIOD_M30
 
// ===== Hour Timeframes =====
input bool PeriodH1   = true;   // PERIOD_H1
input bool PeriodH2   = true;   // PERIOD_H2
input bool PeriodH3   = true;   // PERIOD_H3
input bool PeriodH4   = true;   // PERIOD_H4
input bool PeriodH6   = true;   // PERIOD_H6
input bool PeriodH8   = true;   // PERIOD_H8
input bool PeriodH12  = true;   // PERIOD_H12
 
// ===== Higher Timeframes =====
input bool PeriodD1   = false;   // PERIOD_D1
input bool PeriodW1   = false;   // PERIOD_W1
input bool PeriodMN1  = false;   // PERIOD_MN1
 
input string __IndicatorStrategy__ = "***Indicator Strategy***";
input bool RelativeStrengthIndex = true;
input bool BollingerBands = true;
input bool MovingAverage = true;
input bool AverageDirectionalIndex =  true;
 
input string __RSI_Indicator__ = "***RSI Indicator Settings***";
input ENUM_APPLIED_PRICE RSI_AppliedPrice = PRICE_CLOSE;
input int RSI_Period = 14;
input int RSI_AboveLevel = 70;
input int RSI_BelowLevel = 30;
 
input string __BollingerBands_Indicator__ = "***Bollinger Bands Indicator Settings***";
input ENUM_APPLIED_PRICE BollingerBands_AppliedPrice = PRICE_CLOSE;
input int BollingerBands_Period = 20;
input double BollingerBands_deviation = 2.0;
input int BollingerBands_BandShift = 0;
 
input string __MovingAverage_Indicator__ = "***Moving Average Indicator Settings***";
input ENUM_APPLIED_PRICE MovingAverage_AppliedPrice = PRICE_CLOSE;
input ENUM_MA_METHOD MovingAverage_Method = MODE_EMA;
input int MovingAverage_Period = 200;
input int MovingAverage_MAShift = 0;
 
input string __ADX_Indicator__ = "***ADX Indicator Settings***";
input int ADX_Strength = 1;
input int ADX_Period = 150;
 
int gSymbolIndex = 0;
string validSymbols[];
ENUM_TIMEFRAMES TimeFrameArray[];
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   InitMultiSymbols();
   TimeFrameEnabled();
 
//Indicator Handle
   int MaxPeriod = MathMax(
                      MathMax(RSI_Period, BollingerBands_Period),
                      MathMax(ADX_Period, MovingAverage_Period)
                   ) * 3;
 
   for(int s=0; s<ArraySize(validSymbols); s++)
     {
      string sym = validSymbols[s];
      SymbolSelect(sym, true);
      for(int t=0; t<ArraySize(TimeFrameArray); t++)
        {
         ENUM_TIMEFRAMES tf = TimeFrameArray[t];
         MqlRates rates[];
         if(CopyRates(sym, tf, 0, MaxPeriod, rates) <= 0)
           {
            Print("Failed to load history for ", sym, " ", EnumToString(tf));
           }
 
         if(MovingAverage)
            GetMAHandle(sym, tf, MovingAverage_Period, MovingAverage_MAShift, MovingAverage_Method, MovingAverage_AppliedPrice);
 
         if(RelativeStrengthIndex)
            GetRSIHandle(sym, tf, RSI_Period, RSI_AppliedPrice);
 
         if(BollingerBands)
            GetBBHandle(sym, tf, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice);
 
         if(AverageDirectionalIndex)
            GetADXHandle(sym, tf, ADX_Period);
        }
     }
 
   TesterHideIndicators(true);
 
   return(INIT_SUCCEEDED);
  }
 
//+------------------------------------------------------------------+
//| On Deinit                                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   for(int i = 0; i < ArraySize(ADXHandles); i++)
     {
      if(ADXHandles[i].handle != INVALID_HANDLE)
         IndicatorRelease(ADXHandles[i].handle);
     }
 
   for(int i=0; i<ArraySize(RSIHandles); i++)
     {
      if(RSIHandles[i].handle != INVALID_HANDLE)
         IndicatorRelease(RSIHandles[i].handle);
     }
 
   for(int i=0; i<ArraySize(BBHandles); i++)
     {
      if(BBHandles[i].handle != INVALID_HANDLE)
         IndicatorRelease(BBHandles[i].handle);
     }
 
   for(int i=0;i<ArraySize(MAHandles);i++)
     {
      if(MAHandles[i].handle != INVALID_HANDLE)
         IndicatorRelease(MAHandles[i].handle);
     }
  }
 
//+------------------------------------------------------------------+
//|    OnTick                                                        |
//+------------------------------------------------------------------+
void OnTick()
  {
   for(int s=0; s<ArraySize(validSymbols); s++)
     {
      string sym = validSymbols[s];
      for(int t=0; t<ArraySize(TimeFrameArray); t++)
        {
         ENUM_TIMEFRAMES tf = TimeFrameArray[t];
         double RSIValue = 0;
         if(RelativeStrengthIndex)
            RSIValue  = fRSI(sym, tf, RSI_Period, RSI_AppliedPrice, 1);
 
         double BB_UpperBand = 0, BB_LowerBand = 0;
         if(BollingerBands)
           {
            BB_UpperBand  = fBands(sym, tf, BollingerBands_Period, BollingerBands_deviation, 0, BollingerBands_AppliedPrice, UPPER_BAND, 1);
 
            BB_LowerBand  = fBands(sym, tf, BollingerBands_Period, BollingerBands_deviation, 0, BollingerBands_AppliedPrice, LOWER_BAND, 1);
           }
 
         double MovingAverageValue = 0;
         if(MovingAverage)
            MovingAverageValue = fMA(sym, tf, MovingAverage_Period, 0, MovingAverage_Method, MovingAverage_AppliedPrice, 1);
 
         double ADXStrength = 0, ADX_PlusDI = 0, ADX_MinusDI = 0;
         if(AverageDirectionalIndex)
           {
            ADXStrength = fADX(sym, tf, ADX_Period, MAIN_LINE, 1);
 
            ADX_PlusDI = fADX(sym, tf, ADX_Period, PLUSDI_LINE, 1);
 
            ADX_MinusDI = fADX(sym, tf, ADX_Period, MINUSDI_LINE, 1);
           }
        }
     }
 
  }
 
//+------------------------------------------------------------------+
//|     Symbol Array                                                 |
//+------------------------------------------------------------------+
void InitMultiSymbols()
  {
   ArrayResize(validSymbols, 0);
   gSymbolIndex = 0;
 
   string inputPairs[];
   int pairCount = StringSplit(TradingSymbols, ',', inputPairs);
   if(pairCount <= 0)
     {
      Print("InitMultiSymbols: No TradingSymbols");
      return;
     }
 
   bool isTester = MQLInfoInteger(MQL_TESTER);
   int totalMW   = SymbolsTotal(true);
 
   for(int i = 0; i < pairCount; i++)
     {
      if(isTester)
        {
         // Tester: accept input directly
         ArrayResize(validSymbols, ArraySize(validSymbols) + 1);
         validSymbols[ArraySize(validSymbols) - 1] = inputPairs[i];
        }
      else
        {
         // Live/Demo: only if in Market Watch
         for(int m = 0; m < totalMW; m++)
           {
            if(SymbolName(m, true) == inputPairs[i])
              {
               ArrayResize(validSymbols, ArraySize(validSymbols) + 1);
               validSymbols[ArraySize(validSymbols) - 1] = inputPairs[i];
               break;
              }
           }
        }
     }
  }
 
//+------------------------------------------------------------------+
//|   Timeframe                                                      |
//+------------------------------------------------------------------+
void TimeFrameEnabled()
  {
   int tfCount = 0;
   ArrayResize(TimeFrameArray, 21);   // max possible TFs
 
   if(PeriodM1)
      TimeFrameArray[tfCount++] = PERIOD_M1;
   if(PeriodM2)
      TimeFrameArray[tfCount++] = PERIOD_M2;
   if(PeriodM3)
      TimeFrameArray[tfCount++] = PERIOD_M3;
   if(PeriodM4)
      TimeFrameArray[tfCount++] = PERIOD_M4;
   if(PeriodM5)
      TimeFrameArray[tfCount++] = PERIOD_M5;
   if(PeriodM6)
      TimeFrameArray[tfCount++] = PERIOD_M6;
   if(PeriodM10)
      TimeFrameArray[tfCount++] = PERIOD_M10;
   if(PeriodM12)
      TimeFrameArray[tfCount++] = PERIOD_M12;
   if(PeriodM15)
      TimeFrameArray[tfCount++] = PERIOD_M15;
   if(PeriodM20)
      TimeFrameArray[tfCount++] = PERIOD_M20;
   if(PeriodM30)
      TimeFrameArray[tfCount++] = PERIOD_M30;
 
   if(PeriodH1)
      TimeFrameArray[tfCount++] = PERIOD_H1;
   if(PeriodH2)
      TimeFrameArray[tfCount++] = PERIOD_H2;
   if(PeriodH3)
      TimeFrameArray[tfCount++] = PERIOD_H3;
   if(PeriodH4)
      TimeFrameArray[tfCount++] = PERIOD_H4;
   if(PeriodH6)
      TimeFrameArray[tfCount++] = PERIOD_H6;
   if(PeriodH8)
      TimeFrameArray[tfCount++] = PERIOD_H8;
   if(PeriodH12)
      TimeFrameArray[tfCount++] = PERIOD_H12;
 
   if(PeriodD1)
      TimeFrameArray[tfCount++] = PERIOD_D1;
   if(PeriodW1)
      TimeFrameArray[tfCount++] = PERIOD_W1;
   if(PeriodMN1)
      TimeFrameArray[tfCount++] = PERIOD_MN1;
 
   ArrayResize(TimeFrameArray, tfCount);   // shrink to real size
  }
 
 
//+------------------------------------------------------------------+
//|   Series Checl                                                   |
//+------------------------------------------------------------------+
bool IsSeriesReady(string sy, ENUM_TIMEFRAMES tf)
  {
   long sync = 0;
   if(!SeriesInfoInteger(sy, tf, SERIES_SYNCHRONIZED, sync))
      return false;
 
   return (sync == 1);
  }
 
//+------------------------------------------------------------------+
//|  Force Rates                                                     |
//+------------------------------------------------------------------+
bool ForceRates(string sy, ENUM_TIMEFRAMES tf, int CountPeriod)
  {
   MqlRates rates[];
   ArraySetAsSeries(rates, true);
 
   int copied = CopyRates(sy, tf, 0, CountPeriod, rates);
   return (copied > 0);
  }
 
//+------------------------------------------------------------------+
//|      Moving Average                                              |
//+------------------------------------------------------------------+
struct MA_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   int               shift;
   ENUM_MA_METHOD    method;
   ENUM_APPLIED_PRICE price;
   int               handle;
  };
 
MA_HANDLE MAHandles[];
//MA Handle
int GetMAHandle(string sy, ENUM_TIMEFRAMES tf, int period, int ma_shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE price)
  {
   for(int i=0;i<ArraySize(MAHandles);i++)
     {
      if(MAHandles[i].symbol==sy &&
         MAHandles[i].tf==tf &&
         MAHandles[i].period==period &&
         MAHandles[i].shift==ma_shift &&
         MAHandles[i].method==method &&
         MAHandles[i].price==price)
        {
         return MAHandles[i].handle;
        }
     }
 
   int h = iMA(sy, tf, period, ma_shift, method, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create MA for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(MAHandles);
   ArrayResize(MAHandles, n+1);
 
   MAHandles[n].symbol = sy;
   MAHandles[n].tf     = tf;
   MAHandles[n].period = period;
   MAHandles[n].shift  = ma_shift;
   MAHandles[n].method = method;
   MAHandles[n].price  = price;
   MAHandles[n].handle = h;
 
   return h;
  }
 
//MA Value
double fMA(string sy, ENUM_TIMEFRAMES tf, int period, int ma_shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE price, int shift)
  {
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//force price data
   if(!ForceRates(sy, tf, period))
     {
      Print(__FUNCTION__, "Rate Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   int h = GetMAHandle(sy, tf, period, ma_shift, method, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, "Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= period)
     {
      Print(__FUNCTION__, "BarsCalculated (Period) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   ArraySetAsSeries(buf, true);
 
// Copy safely
   if(CopyBuffer(h, 0, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, " CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
 
//+------------------------------------------------------------------+
//|      BollingerBands                                              |
//+------------------------------------------------------------------+
struct BB_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   double            deviation;
   int               shift;
   ENUM_APPLIED_PRICE price;
   int               handle;
  };
 
BB_HANDLE BBHandles[];
//BB Handle
int GetBBHandle(string sy, ENUM_TIMEFRAMES tf, int period, double deviation, int bands_shift, ENUM_APPLIED_PRICE price)
  {
   for(int i=0; i<ArraySize(BBHandles); i++)
     {
      if(BBHandles[i].symbol == sy &&
         BBHandles[i].tf == tf &&
         BBHandles[i].period == period &&
         BBHandles[i].deviation == deviation &&
         BBHandles[i].shift == bands_shift &&
         BBHandles[i].price == price)
        {
         return BBHandles[i].handle; //  reuse
        }
     }
 
// ❗ create only once
   int h = iBands(sy, tf, period, bands_shift, deviation, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(BBHandles);
   ArrayResize(BBHandles, n + 1);
 
   BBHandles[n].symbol    = sy;
   BBHandles[n].tf        = tf;
   BBHandles[n].period    = period;
   BBHandles[n].deviation = deviation;
   BBHandles[n].shift     = bands_shift;
   BBHandles[n].price     = price;
   BBHandles[n].handle    = h;
 
   return h;
  }
//BB Value
double fBands(string sy, ENUM_TIMEFRAMES tf, int period, double deviation, int bands_shift, ENUM_APPLIED_PRICE price, int mode, int shift)
  {
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//force price data
   if(!ForceRates(sy, tf, period))
     {
      Print(__FUNCTION__, "Rate Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   int h = GetBBHandle(sy, tf, period, deviation, bands_shift, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= period)
     {
      Print(__FUNCTION__, "BarsCalculated (Period) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   if(CopyBuffer(h, mode, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, " CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
 
//+------------------------------------------------------------------+
//|      RSI                                                         |
//+------------------------------------------------------------------+
struct RSI_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   ENUM_APPLIED_PRICE price;
   int               handle;
  };
 
RSI_HANDLE RSIHandles[];
//RSI Handle
int GetRSIHandle(string sy, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE price)
  {
   for(int i=0; i<ArraySize(RSIHandles); i++)
     {
      if(RSIHandles[i].symbol == sy &&
         RSIHandles[i].tf == tf &&
         RSIHandles[i].period == period &&
         RSIHandles[i].price == price)
        {
         return RSIHandles[i].handle; //  reuse
        }
     }
 
// ❗ create once
   int h = iRSI(sy, tf, period, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(RSIHandles);
   ArrayResize(RSIHandles, n + 1);
 
   RSIHandles[n].symbol = sy;
   RSIHandles[n].tf     = tf;
   RSIHandles[n].period = period;
   RSIHandles[n].price  = price;
   RSIHandles[n].handle = h;
 
   return h;
  }
//Get RSI Value
double fRSI(string sy, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE price, int shift)
  {
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//force price data
   if(!ForceRates(sy, tf, period))
     {
      Print(__FUNCTION__, "Rate Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   int h = GetRSIHandle(sy, tf, period, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, "Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= period)
     {
      Print(__FUNCTION__, "BarsCalculated (Period) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   if(CopyBuffer(h, 0, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, " CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
 
//+------------------------------------------------------------------+
//|      ADX                                                         |
//+------------------------------------------------------------------+
struct ADX_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   int               handle;
  };
 
ADX_HANDLE ADXHandles[];
 
//Get ADX Handle
int GetADXHandle(string sy, ENUM_TIMEFRAMES tf, int period)
  {
   for(int i = 0; i < ArraySize(ADXHandles); i++)
     {
      if(ADXHandles[i].symbol == sy &&
         ADXHandles[i].tf == tf &&
         ADXHandles[i].period == period)
        {
         return ADXHandles[i].handle; //  reuse
        }
     }
 
// ❗ create once
   int h = iADX(sy, tf, period);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(ADXHandles);
   ArrayResize(ADXHandles, n + 1);
 
   ADXHandles[n].symbol = sy;
   ADXHandles[n].tf     = tf;
   ADXHandles[n].period = period;
   ADXHandles[n].handle = h;
 
   return h;
  }
 
//ADX Value
double fADX(string sy, ENUM_TIMEFRAMES tf, int period, int mode, int shift)
  {
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
//force price data
   if(!ForceRates(sy, tf, period))
     {
      Print(__FUNCTION__, "Rate Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   int h = GetADXHandle(sy, tf, period);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, "Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= period)
     {
      Print(__FUNCTION__, "BarsCalculated (Period) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   if(CopyBuffer(h, mode, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, "CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
//+------------------------------------------------------------------+

Kindly help me fix this.
 
1. Sometime Due to Moving Average full EA get stuck
Stuck how?
2. Sometime CopyBuffer get failed and return 0 (for all indicators)
CopyBuffer can sometimes return 0. You code needs to check for that and retry on next tick or after some delay.
3. When i deinit and init again by changing Timeframe my EA getting function getting broken (Until i close and reopen metatrader again).
Broken how? Do you take into account that on re-initialization (e.g., timeframe change) all global variables retain their values (i.e., gSymbolIndex, validSymbols[], TimeFrameArray[])? Also, since you are getting handles for all timeframes irrespective of the current timeframe, perhaps there is no need to release handles on deinit?
 
Stuck how?
EA stuck. maybe because i use 200 EMA and that might be the reason. MT5 Terminal running fine even chart price changing but EA does nothing it stay as it is. Now it fixed after using MqlRates rates[];

CopyBuffer can sometimes return 0. You code needs to check for that and retry on next tick or after some delay.
I already using BarsCalculated(h) <= shift. should i compare BarsCalculated(h) with shift or period or both?

I also feel it super-slow or laggy because it checking lot of things every tick like SymbolSelect, SymbolIsSynchronized, Bars, etc. so i moved all to other place where it only called when handle getting created.

Updated code :

MQL5:
//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
input string TradingSymbols = "EURUSD,GBPUSD,USDJPY,USDCHF,USDCAD,AUDUSD,NZDUSD,GBPCAD,EURGBP,AUDNZD,XAGUSD,XAUUSD,XAUGBP,XAUAUD,XAUEUR,XAUCAD,XAUJPY,XAUCHF,BTCUSD";
input string __TimeFrame__ = "***TimeFrame Settings***";
// ===== Minute Timeframes =====
input bool PeriodM1   = true;   // PERIOD_M1
input bool PeriodM2   = true;   // PERIOD_M2
input bool PeriodM3   = true;   // PERIOD_M3
input bool PeriodM4   = true;   // PERIOD_M4
input bool PeriodM5   = true;   // PERIOD_M5
input bool PeriodM6   = true;   // PERIOD_M6
input bool PeriodM10  = true;   // PERIOD_M10
input bool PeriodM12  = true;   // PERIOD_M12
input bool PeriodM15  = true;   // PERIOD_M15
input bool PeriodM20  = true;   // PERIOD_M20
input bool PeriodM30  = true;   // PERIOD_M30
 
// ===== Hour Timeframes =====
input bool PeriodH1   = true;   // PERIOD_H1
input bool PeriodH2   = true;   // PERIOD_H2
input bool PeriodH3   = true;   // PERIOD_H3
input bool PeriodH4   = true;   // PERIOD_H4
input bool PeriodH6   = true;   // PERIOD_H6
input bool PeriodH8   = true;   // PERIOD_H8
input bool PeriodH12  = true;   // PERIOD_H12
 
// ===== Higher Timeframes =====
input bool PeriodD1   = false;   // PERIOD_D1
input bool PeriodW1   = false;   // PERIOD_W1
input bool PeriodMN1  = false;   // PERIOD_MN1
 
input string __IndicatorStrategy__ = "***Indicator Strategy***";
input bool RelativeStrengthIndex = true;
input bool BollingerBands = true;
input bool MovingAverage = true;
input bool AverageDirectionalIndex =  true;
 
input string __RSI_Indicator__ = "***RSI Indicator Settings***";
input ENUM_APPLIED_PRICE RSI_AppliedPrice = PRICE_CLOSE;
input int RSI_Period = 14;
input int RSI_AboveLevel = 70;
input int RSI_BelowLevel = 30;
 
input string __BollingerBands_Indicator__ = "***Bollinger Bands Indicator Settings***";
input ENUM_APPLIED_PRICE BollingerBands_AppliedPrice = PRICE_CLOSE;
input int BollingerBands_Period = 20;
input double BollingerBands_deviation = 2.0;
input int BollingerBands_BandShift = 0;
 
input string __MovingAverage_Indicator__ = "***Moving Average Indicator Settings***";
input ENUM_APPLIED_PRICE MovingAverage_AppliedPrice = PRICE_CLOSE;
input ENUM_MA_METHOD MovingAverage_Method = MODE_EMA;
input int MovingAverage_Period = 200;
input int MovingAverage_MAShift = 0;
 
input string __ADX_Indicator__ = "***ADX Indicator Settings***";
input int ADX_Strength = 1;
input int ADX_Period = 150;
 
int gSymbolIndex = 0;
string validSymbols[];
ENUM_TIMEFRAMES TimeFrameArray[];
 
//+------------------------------------------------------------------+
//|   OnInit                                                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   InitMultiSymbols();
   TimeFrameEnabled();
 
//Indicator Handle
   int MaxPeriod = MathMax(
                      MathMax(RSI_Period, BollingerBands_Period),
                      MathMax(ADX_Period, MovingAverage_Period)
                   ) * 3;
 
   for(int s=0; s<ArraySize(validSymbols); s++)
     {
      string sym = validSymbols[s];
      SymbolSelect(sym, true);
      for(int t=0; t<ArraySize(TimeFrameArray); t++)
        {
         ENUM_TIMEFRAMES tf = TimeFrameArray[t];
         MqlRates rates[];
         if(CopyRates(sym, tf, 0, MaxPeriod, rates) <= 0)
           {
            Print("Failed to load history for ", sym, " ", EnumToString(tf));
           }
 
         if(MovingAverage)
            GetMAHandle(sym, tf, MovingAverage_Period, MovingAverage_MAShift, MovingAverage_Method, MovingAverage_AppliedPrice);
 
         if(RelativeStrengthIndex)
            GetRSIHandle(sym, tf, RSI_Period, RSI_AppliedPrice);
 
         if(BollingerBands)
            GetBBHandle(sym, tf, BollingerBands_Period, BollingerBands_deviation, BollingerBands_BandShift, BollingerBands_AppliedPrice);
 
         if(AverageDirectionalIndex)
            GetADXHandle(sym, tf, ADX_Period);
        }
     }
 
   TesterHideIndicators(true);
 
   return(INIT_SUCCEEDED);
  }
 
//+------------------------------------------------------------------+
//| On Deinit                                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   for(int i = 0; i < ArraySize(ADXHandles); i++)
     {
      if(ADXHandles[i].handle != INVALID_HANDLE)
         if(!IndicatorRelease(ADXHandles[i].handle))
            Print("Failed to release MA handle: ", ADXHandles[i].handle);
     }
 
   for(int i=0; i<ArraySize(RSIHandles); i++)
     {
      if(RSIHandles[i].handle != INVALID_HANDLE)
         if(!IndicatorRelease(RSIHandles[i].handle))
            Print("Failed to release MA handle: ", RSIHandles[i].handle);
 
     }
 
   for(int i=0; i<ArraySize(BBHandles); i++)
     {
      if(BBHandles[i].handle != INVALID_HANDLE)
         if(!IndicatorRelease(BBHandles[i].handle))
            Print("Failed to release MA handle: ", BBHandles[i].handle);
     }
 
   for(int i=0;i<ArraySize(MAHandles);i++)
     {
      if(MAHandles[i].handle != INVALID_HANDLE)
        {
         if(!IndicatorRelease(MAHandles[i].handle))
            Print("Failed to release MA handle: ", MAHandles[i].handle);
         MAHandles[i].handle = INVALID_HANDLE;
        }
     }
   ArrayResize(MAHandles,0);
  }
 
//+------------------------------------------------------------------+
//|    OnTick                                                        |
//+------------------------------------------------------------------+
void OnTick()
  {
   for(int s=0; s<ArraySize(validSymbols); s++)
     {
      string sym = validSymbols[s];
      for(int t=0; t<ArraySize(TimeFrameArray); t++)
        {
         ENUM_TIMEFRAMES tf = TimeFrameArray[t];
         double RSIValue = 0;
         if(RelativeStrengthIndex)
            RSIValue  = fRSI(sym, tf, RSI_Period, RSI_AppliedPrice, 1);
 
         double BB_UpperBand = 0, BB_LowerBand = 0;
         if(BollingerBands)
           {
            BB_UpperBand  = fBands(sym, tf, BollingerBands_Period, BollingerBands_deviation, 0, BollingerBands_AppliedPrice, UPPER_BAND, 1);
 
            BB_LowerBand  = fBands(sym, tf, BollingerBands_Period, BollingerBands_deviation, 0, BollingerBands_AppliedPrice, LOWER_BAND, 1);
           }
 
         double MovingAverageValue = 0;
         if(MovingAverage)
            MovingAverageValue = fMA(sym, tf, MovingAverage_Period, 0, MovingAverage_Method, MovingAverage_AppliedPrice, 1);
 
         double ADXStrength = 0, ADX_PlusDI = 0, ADX_MinusDI = 0;
         if(AverageDirectionalIndex)
           {
            ADXStrength = fADX(sym, tf, ADX_Period, MAIN_LINE, 1);
 
            ADX_PlusDI = fADX(sym, tf, ADX_Period, PLUSDI_LINE, 1);
 
            ADX_MinusDI = fADX(sym, tf, ADX_Period, MINUSDI_LINE, 1);
           }
        }
     }
 
  }
 
//+------------------------------------------------------------------+
//|     Symbol Array                                                 |
//+------------------------------------------------------------------+
void InitMultiSymbols()
  {
   ArrayResize(validSymbols, 0);
   gSymbolIndex = 0;
 
   string inputPairs[];
   int pairCount = StringSplit(TradingSymbols, ',', inputPairs);
   if(pairCount <= 0)
     {
      Print("InitMultiSymbols: No TradingSymbols");
      return;
     }
 
   bool isTester = MQLInfoInteger(MQL_TESTER);
   int totalMW   = SymbolsTotal(true);
 
   for(int i = 0; i < pairCount; i++)
     {
      if(isTester)
        {
         // Tester: accept input directly
         ArrayResize(validSymbols, ArraySize(validSymbols) + 1);
         validSymbols[ArraySize(validSymbols) - 1] = inputPairs[i];
        }
      else
        {
         // Live/Demo: only if in Market Watch
         for(int m = 0; m < totalMW; m++)
           {
            if(SymbolName(m, true) == inputPairs[i])
              {
               ArrayResize(validSymbols, ArraySize(validSymbols) + 1);
               validSymbols[ArraySize(validSymbols) - 1] = inputPairs[i];
               break;
              }
           }
        }
     }
  }
 
//+------------------------------------------------------------------+
//|   Timeframe                                                      |
//+------------------------------------------------------------------+
void TimeFrameEnabled()
  {
   int tfCount = 0;
   ArrayResize(TimeFrameArray, 21);   // max possible TFs
 
   if(PeriodM1)
      TimeFrameArray[tfCount++] = PERIOD_M1;
   if(PeriodM2)
      TimeFrameArray[tfCount++] = PERIOD_M2;
   if(PeriodM3)
      TimeFrameArray[tfCount++] = PERIOD_M3;
   if(PeriodM4)
      TimeFrameArray[tfCount++] = PERIOD_M4;
   if(PeriodM5)
      TimeFrameArray[tfCount++] = PERIOD_M5;
   if(PeriodM6)
      TimeFrameArray[tfCount++] = PERIOD_M6;
   if(PeriodM10)
      TimeFrameArray[tfCount++] = PERIOD_M10;
   if(PeriodM12)
      TimeFrameArray[tfCount++] = PERIOD_M12;
   if(PeriodM15)
      TimeFrameArray[tfCount++] = PERIOD_M15;
   if(PeriodM20)
      TimeFrameArray[tfCount++] = PERIOD_M20;
   if(PeriodM30)
      TimeFrameArray[tfCount++] = PERIOD_M30;
 
   if(PeriodH1)
      TimeFrameArray[tfCount++] = PERIOD_H1;
   if(PeriodH2)
      TimeFrameArray[tfCount++] = PERIOD_H2;
   if(PeriodH3)
      TimeFrameArray[tfCount++] = PERIOD_H3;
   if(PeriodH4)
      TimeFrameArray[tfCount++] = PERIOD_H4;
   if(PeriodH6)
      TimeFrameArray[tfCount++] = PERIOD_H6;
   if(PeriodH8)
      TimeFrameArray[tfCount++] = PERIOD_H8;
   if(PeriodH12)
      TimeFrameArray[tfCount++] = PERIOD_H12;
 
   if(PeriodD1)
      TimeFrameArray[tfCount++] = PERIOD_D1;
   if(PeriodW1)
      TimeFrameArray[tfCount++] = PERIOD_W1;
   if(PeriodMN1)
      TimeFrameArray[tfCount++] = PERIOD_MN1;
 
   ArrayResize(TimeFrameArray, tfCount);   // shrink to real size
  }
 
 
//+------------------------------------------------------------------+
//|   Series Checl                                                   |
//+------------------------------------------------------------------+
bool IsSeriesReady(string sy, ENUM_TIMEFRAMES tf)
  {
   long sync = 0;
   if(!SeriesInfoInteger(sy, tf, SERIES_SYNCHRONIZED, sync))
      return false;
 
   return (sync == 1);
  }
 
//+------------------------------------------------------------------+
//|  Force Rates                                                     |
//+------------------------------------------------------------------+
bool ForceRates(string sy, ENUM_TIMEFRAMES tf)
  {
   int MaxPeriod = MathMax(
                      MathMax(RSI_Period, BollingerBands_Period),
                      MathMax(ADX_Period, MovingAverage_Period)
                   ) * 3;
   MqlRates rates[];
   ArraySetAsSeries(rates, true);
 
   int copied = CopyRates(sy, tf, 0, MaxPeriod, rates);
   return (copied > 0);
  }
 
//+------------------------------------------------------------------+
//|      Moving Average                                              |
//+------------------------------------------------------------------+
struct MA_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   int               shift;
   ENUM_MA_METHOD    method;
   ENUM_APPLIED_PRICE price;
   int               handle;
  };
 
MA_HANDLE MAHandles[];
//MA Handle
int GetMAHandle(string sy, ENUM_TIMEFRAMES tf, int period, int ma_shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE price)
  {
   for(int i=0;i<ArraySize(MAHandles);i++)
     {
      if(MAHandles[i].symbol==sy &&
         MAHandles[i].tf==tf &&
         MAHandles[i].period==period &&
         MAHandles[i].shift==ma_shift &&
         MAHandles[i].method==method &&
         MAHandles[i].price==price)
        {
         return MAHandles[i].handle;
        }
     }
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//force price data
   if(!ForceRates(sy, tf))
     {
      Print(__FUNCTION__, "Rate Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
   int h = iMA(sy, tf, period, ma_shift, method, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create MA for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(MAHandles);
   ArrayResize(MAHandles, n+1);
 
   MAHandles[n].symbol = sy;
   MAHandles[n].tf     = tf;
   MAHandles[n].period = period;
   MAHandles[n].shift  = ma_shift;
   MAHandles[n].method = method;
   MAHandles[n].price  = price;
   MAHandles[n].handle = h;
 
   return h;
  }
 
//MA Value
double fMA(string sy, ENUM_TIMEFRAMES tf, int period, int ma_shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE price, int shift)
  {
 
   int h = GetMAHandle(sy, tf, period, ma_shift, method, price);
   if(h == INVALID_HANDLE || h == -919)
     {
      Print(__FUNCTION__, "Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   ArraySetAsSeries(buf, true);
   if(CopyBuffer(h, 0, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, " CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
 
//+------------------------------------------------------------------+
//|      BollingerBands                                              |
//+------------------------------------------------------------------+
struct BB_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   double            deviation;
   int               shift;
   ENUM_APPLIED_PRICE price;
   int               handle;
  };
 
BB_HANDLE BBHandles[];
//BB Handle
int GetBBHandle(string sy, ENUM_TIMEFRAMES tf, int period, double deviation, int bands_shift, ENUM_APPLIED_PRICE price)
  {
   for(int i=0; i<ArraySize(BBHandles); i++)
     {
      if(BBHandles[i].symbol == sy &&
         BBHandles[i].tf == tf &&
         BBHandles[i].period == period &&
         BBHandles[i].deviation == deviation &&
         BBHandles[i].shift == bands_shift &&
         BBHandles[i].price == price)
        {
         return BBHandles[i].handle; //  reuse
        }
     }
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//force price data
   if(!ForceRates(sy, tf))
     {
      Print(__FUNCTION__, "Rate Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// ❗ create only once
   int h = iBands(sy, tf, period, bands_shift, deviation, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(BBHandles);
   ArrayResize(BBHandles, n + 1);
 
   BBHandles[n].symbol    = sy;
   BBHandles[n].tf        = tf;
   BBHandles[n].period    = period;
   BBHandles[n].deviation = deviation;
   BBHandles[n].shift     = bands_shift;
   BBHandles[n].price     = price;
   BBHandles[n].handle    = h;
 
   return h;
  }
//BB Value
double fBands(string sy, ENUM_TIMEFRAMES tf, int period, double deviation, int bands_shift, ENUM_APPLIED_PRICE price, int mode, int shift)
  {
   int h = GetBBHandle(sy, tf, period, deviation, bands_shift, price);
   if(h == INVALID_HANDLE || h == -919)
     {
      Print(__FUNCTION__, " Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   if(CopyBuffer(h, mode, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, " CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
 
//+------------------------------------------------------------------+
//|      RSI                                                         |
//+------------------------------------------------------------------+
struct RSI_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   ENUM_APPLIED_PRICE price;
   int               handle;
  };
 
RSI_HANDLE RSIHandles[];
//RSI Handle
int GetRSIHandle(string sy, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE price)
  {
   for(int i=0; i<ArraySize(RSIHandles); i++)
     {
      if(RSIHandles[i].symbol == sy &&
         RSIHandles[i].tf == tf &&
         RSIHandles[i].period == period &&
         RSIHandles[i].price == price)
        {
         return RSIHandles[i].handle; //  reuse
        }
     }
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//force price data
   if(!ForceRates(sy, tf))
     {
      Print(__FUNCTION__, "Rate Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// ❗ create once
   int h = iRSI(sy, tf, period, price);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(RSIHandles);
   ArrayResize(RSIHandles, n + 1);
 
   RSIHandles[n].symbol = sy;
   RSIHandles[n].tf     = tf;
   RSIHandles[n].period = period;
   RSIHandles[n].price  = price;
   RSIHandles[n].handle = h;
 
   return h;
  }
//Get RSI Value
double fRSI(string sy, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE price, int shift)
  {
   int h = GetRSIHandle(sy, tf, period, price);
   if(h == INVALID_HANDLE || h == -919)
     {
      Print(__FUNCTION__, "Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   if(CopyBuffer(h, 0, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, " CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
 
//+------------------------------------------------------------------+
//|      ADX                                                         |
//+------------------------------------------------------------------+
struct ADX_HANDLE
  {
   string            symbol;
   ENUM_TIMEFRAMES   tf;
   int               period;
   int               handle;
  };
 
ADX_HANDLE ADXHandles[];
 
//Get ADX Handle
int GetADXHandle(string sy, ENUM_TIMEFRAMES tf, int period)
  {
   for(int i = 0; i < ArraySize(ADXHandles); i++)
     {
      if(ADXHandles[i].symbol == sy &&
         ADXHandles[i].tf == tf &&
         ADXHandles[i].period == period)
        {
         return ADXHandles[i].handle; //  reuse
        }
     }
 
//Symbol Safety
   if(!SymbolSelect(sy, true))
     {
      Print(__FUNCTION__, "SymbolSelect Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Symbol Sync Check
   if(!SymbolIsSynchronized(sy))
     {
      Print(__FUNCTION__, "Symbol Synchreonized Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//Check Bars
   if(Bars(sy, tf) < period)
     {
      Print(__FUNCTION__, "Bars (No Enough Bars) Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
//force price data
   if(!ForceRates(sy, tf))
     {
      Print(__FUNCTION__, "Rate Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// Ensure series is synchronized
   if(!IsSeriesReady(sy, tf))
     {
      Print(__FUNCTION__, " Series Returned Error for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return -919;
     }
 
// ❗ create once
   int h = iADX(sy, tf, period);
   if(h == INVALID_HANDLE)
     {
      Print(__FUNCTION__, " Failed to create for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return INVALID_HANDLE;
     }
 
   int n = ArraySize(ADXHandles);
   ArrayResize(ADXHandles, n + 1);
 
   ADXHandles[n].symbol = sy;
   ADXHandles[n].tf     = tf;
   ADXHandles[n].period = period;
   ADXHandles[n].handle = h;
 
   return h;
  }
 
//ADX Value
double fADX(string sy, ENUM_TIMEFRAMES tf, int period, int mode, int shift)
  {
   int h = GetADXHandle(sy, tf, period);
   if(h == INVALID_HANDLE || h == -919)
     {
      Print(__FUNCTION__, "Invalid Handle Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
// Ensure indicator is calculated
   if(BarsCalculated(h) <= shift)
     {
      Print(__FUNCTION__, "BarsCalculated (Shift) Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   double buf[];
   if(CopyBuffer(h, mode, shift, 1, buf) <= 0)
     {
      Print(__FUNCTION__, "CopyBuffer Returned 0 for symbol: ", sy, " timeframe: ", EnumToString(tf));
      return 0;
     }
 
   return buf[0];
  }
//+------------------------------------------------------------------+

Is my new code is fine?