//+------------------------------------------------------------------+
//|                                                    XU-MA v3.mq5 |
//|                                      Converted from MQL4 to MQL5 |
//+------------------------------------------------------------------+
#property copyright "XARD UNIVERSE"
#property link      "https://forex-station.com"
#property version   "3.00"
#property description "[XU-MA v3]"
#property description "THIS IS A FREE INDICATOR"
#property description "Welcome to XARD UNIVERSE"

#property indicator_chart_window
#property indicator_buffers 21
#property indicator_plots   11

//--- Inputs
input string          Indicator                  = "[XU-MA v3]";

//--- [01] Candle Settings
input string          STR01                      = "<<<==== [01] Candle Settings ====>>>";
input bool            showCANDLES                = true;
input int             cWick                      = 1;
input color           CandleUp                   = C'96,170,204';
input color           CandleWt                   = C'34,34,34';
input color           CandleDn                   = C'255,140,255';

//--- [02] Openline Settings
input string          STR02                      = "<<<==== [02] Openline Settings ====>>>";
input bool            showDOP                    = true;
input int             DOPwidth                   = 5;
input int             DOPtf                      = 1440;
input color           DOPclr                     = C'60,60,60';

//--- [03] TREND Settings
input string          STR03                      = "<<<==== [03] TREND Settings ====>>>";
input bool            showTREND                  = true;
input color           TRENDupclr                 = clrBlue;
input color           TRENDdnclr                 = clrCrimson;
input color           Tbgdclr                    = C'100,130,160';
input int             TRENDper                   = 36;
input int             TRENDtf                    = 0;
input int             TRENDshft                  = 0;
input ENUM_MA_METHOD  TRENDmode                  = MODE_EMA;
input ENUM_APPLIED_PRICE TRENDtype               = PRICE_MEDIAN;
input int             TRENDwidth                 = 7;

//--- [04] SIGNAL Settings
input string          STR04                      = "<<<==== [04] SIGNAL Settings ====>>>";
input bool            showSIGNAL                 = true;
input color           SIGNALupclr                = clrBlue;
input color           SIGNALdnclr                = clrCrimson;
input color           Sbgdclr                    = C'100,130,160';
input int             SIGNALper                  = 9;
input int             SIGNALtf                   = 0;
input int             SIGNALshft                 = 0;
input ENUM_MA_METHOD  SIGNALmode                 = MODE_EMA;
input ENUM_APPLIED_PRICE SIGNALtype              = PRICE_MEDIAN;
input int             SIGNALwidth                = 4;

//--- [05] BGDzones Settings
input string          STR05                      = "<<<==== [05] BGDzones Settings ====>>>";
input bool            showBGDzones               = true;
input ENUM_APPLIED_PRICE CCIPrice                = PRICE_TYPICAL;
input color           ColorUp                    = C'53,72,110';
input color           ColorDown                  = C'120,63,82';
input color           ColorWait                  = C'91,103,112';

//--- [06] BOXtxt Settings
input string          STR06                      = "<<<==== [06] BOXtxt Settings ====>>>";
input bool            showBOXtxt                 = true;
input bool            showSig                    = true;
input int             moveTxtLR                  = 0;
input int             moveTxtUD                  = 0;
input int             FontSize                   = 15;

//--- [07] Alert Settings
input string          STR07                      = "<<<==== [07] Alert Settings ====>>>";
input bool            AlertsOn                   = true;
input bool            AlertsOnCurrent            = true;
input bool            AlertsMessage              = true;
input bool            AlertsSound                = false;
input bool            alertsNotify               = true;
input bool            AlertsEmail                = false;
input string          soundfile                  = "alert1.wav";

//--- Buffers
double candle0[], candle1[], candle2[], candle3[], candle4[], candle5[], candle6[], candle7[];
double DOP[];
double Tbgd[], TREND[], TRENDdna[], TRENDdnb[], trend[];
double Sbgd[], SIGNAL[], SIGNALdna[], SIGNALdnb[], signal_buf[];
double colors[], xtrend[];

//--- Global variables
ENUM_TIMEFRAMES timeFrame;
string ID = "b";
datetime lastDummyTime = 0;

//--- Indicator handles
int h_TREND_high = INVALID_HANDLE;
int h_TREND_low  = INVALID_HANDLE;
int h_TREND_med  = INVALID_HANDLE;
int h_SIGNAL_high = INVALID_HANDLE;
int h_SIGNAL_low  = INVALID_HANDLE;
int h_SIGNAL_med  = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Helper to map integer timeframe to ENUM_TIMEFRAMES               |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES IntegerToTFEnum(int minutes)
{
   if(minutes <= 0) return PERIOD_CURRENT;
   switch(minutes)
   {
      case 1:    return PERIOD_M1;
      case 2:    return PERIOD_M2;
      case 3:    return PERIOD_M3;
      case 4:    return PERIOD_M4;
      case 5:    return PERIOD_M5;
      case 6:    return PERIOD_M6;
      case 10:   return PERIOD_M10;
      case 12:   return PERIOD_M12;
      case 15:   return PERIOD_M15;
      case 20:   return PERIOD_M20;
      case 30:   return PERIOD_M30;
      case 60:   return PERIOD_H1;
      case 120:  return PERIOD_H2;
      case 180:  return PERIOD_H3;
      case 240:  return PERIOD_H4;
      case 360:  return PERIOD_H6;
      case 480:  return PERIOD_H8;
      case 720:  return PERIOD_H12;
      case 1440: return PERIOD_D1;
      case 10080:return PERIOD_W1;
      case 43200:return PERIOD_MN1;
      default:   return PERIOD_CURRENT;
   }
}

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
   IndicatorSetString(INDICATOR_SHORTNAME, ID);
   
   //--- Candle Buffers (Plots 0 and 1)
   SetIndexBuffer(0, candle0, INDICATOR_DATA);
   SetIndexBuffer(1, candle1, INDICATOR_DATA);
   SetIndexBuffer(2, candle2, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(3, candle3, INDICATOR_DATA);
   SetIndexBuffer(4, candle4, INDICATOR_DATA);
   SetIndexBuffer(5, candle5, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(6, candle6, INDICATOR_CALCULATIONS);
   SetIndexBuffer(7, candle7, INDICATOR_CALCULATIONS);
   
   // Plot 0: Wicks
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, showCANDLES ? DRAW_COLOR_HISTOGRAM2 : DRAW_NONE);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, cWick);
   PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 3);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, CandleUp);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, CandleWt);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 2, CandleDn);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetString(0, PLOT_LABEL, "Wicks");

   // Plot 1: Bodies
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, showCANDLES ? DRAW_COLOR_HISTOGRAM2 : DRAW_NONE);
   PlotIndexSetInteger(1, PLOT_LINE_WIDTH, cWick + 4);
   PlotIndexSetInteger(1, PLOT_COLOR_INDEXES, 3);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, 0, CandleUp);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, 1, CandleWt);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, 2, CandleDn);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetString(1, PLOT_LABEL, "Bodies");

   //--- DOP Buffer (Plot 2)
   SetIndexBuffer(8, DOP, INDICATOR_DATA);
   PlotIndexSetDouble(8, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   if(showDOP && PeriodSeconds() <= PeriodSeconds(PERIOD_H1))
   {
      PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(2, PLOT_LINE_WIDTH, DOPwidth);
      PlotIndexSetInteger(2, PLOT_LINE_COLOR, DOPclr);
      PlotIndexSetString(2, PLOT_LABEL, "DOP");
   }
   else
   {
      PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_NONE);
   }

   //--- TREND Buffers (Plot 3, 4, 5, 6)
   SetIndexBuffer(9,  Tbgd,    INDICATOR_DATA);
   SetIndexBuffer(10, TREND,   INDICATOR_DATA);
   SetIndexBuffer(11, TRENDdna,INDICATOR_DATA);
   SetIndexBuffer(12, TRENDdnb,INDICATOR_DATA);
   SetIndexBuffer(13, trend,   INDICATOR_CALCULATIONS);
   
   if(showTREND)
   {
      PlotIndexSetInteger(3, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(3, PLOT_LINE_WIDTH, TRENDwidth + 4);
      PlotIndexSetInteger(3, PLOT_LINE_COLOR, Tbgdclr);
      PlotIndexSetString(3, PLOT_LABEL, "Tbgd");

      PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(4, PLOT_LINE_WIDTH, TRENDwidth);
      PlotIndexSetInteger(4, PLOT_LINE_COLOR, TRENDupclr);
      PlotIndexSetString(4, PLOT_LABEL, "TREND");

      PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(5, PLOT_LINE_WIDTH, TRENDwidth);
      PlotIndexSetInteger(5, PLOT_LINE_COLOR, TRENDdnclr);
      PlotIndexSetString(5, PLOT_LABEL, "TRENDdna");

      PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(6, PLOT_LINE_WIDTH, TRENDwidth);
      PlotIndexSetInteger(6, PLOT_LINE_COLOR, TRENDdnclr);
      PlotIndexSetString(6, PLOT_LABEL, "TRENDdnb");
   }
   else
   {
      for(int i = 3; i <= 6; i++) PlotIndexSetInteger(i, PLOT_DRAW_TYPE, DRAW_NONE);
   }

   //--- SIGNAL Buffers (Plot 7, 8, 9, 10)
   SetIndexBuffer(14, Sbgd,     INDICATOR_DATA);
   SetIndexBuffer(15, SIGNAL,   INDICATOR_DATA);
   SetIndexBuffer(16, SIGNALdna,INDICATOR_DATA);
   SetIndexBuffer(17, SIGNALdnb,INDICATOR_DATA);
   SetIndexBuffer(18, signal_buf, INDICATOR_CALCULATIONS);
   
   if(showSIGNAL)
   {
      PlotIndexSetInteger(7, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(7, PLOT_LINE_WIDTH, SIGNALwidth + 4);
      PlotIndexSetInteger(7, PLOT_LINE_COLOR, Sbgdclr);
      PlotIndexSetString(7, PLOT_LABEL, "Sbgd");

      PlotIndexSetInteger(8, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(8, PLOT_LINE_WIDTH, SIGNALwidth);
      PlotIndexSetInteger(8, PLOT_LINE_COLOR, SIGNALupclr);
      PlotIndexSetString(8, PLOT_LABEL, "SIGNAL");

      PlotIndexSetInteger(9, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(9, PLOT_LINE_WIDTH, SIGNALwidth);
      PlotIndexSetInteger(9, PLOT_LINE_COLOR, SIGNALdnclr);
      PlotIndexSetString(9, PLOT_LABEL, "SIGNALdna");

      PlotIndexSetInteger(10, PLOT_DRAW_TYPE, DRAW_LINE);
      PlotIndexSetInteger(10, PLOT_LINE_WIDTH, SIGNALwidth);
      PlotIndexSetInteger(10, PLOT_LINE_COLOR, SIGNALdnclr);
      PlotIndexSetString(10, PLOT_LABEL, "SIGNALdnb");
   }
   else
   {
      for(int i = 7; i <= 10; i++) PlotIndexSetInteger(i, PLOT_DRAW_TYPE, DRAW_NONE);
   }

   SetIndexBuffer(19, colors,  INDICATOR_CALCULATIONS);
   SetIndexBuffer(20, xtrend,  INDICATOR_CALCULATIONS);

   // Set Array Series mapping
   ArraySetAsSeries(candle0, true);
   ArraySetAsSeries(candle1, true);
   ArraySetAsSeries(candle2, true);
   ArraySetAsSeries(candle3, true);
   ArraySetAsSeries(candle4, true);
   ArraySetAsSeries(candle5, true);
   ArraySetAsSeries(candle6, true);
   ArraySetAsSeries(candle7, true);
   ArraySetAsSeries(DOP, true);
   ArraySetAsSeries(Tbgd, true);
   ArraySetAsSeries(TREND, true);
   ArraySetAsSeries(TRENDdna, true);
   ArraySetAsSeries(TRENDdnb, true);
   ArraySetAsSeries(trend, true);
   ArraySetAsSeries(Sbgd, true);
   ArraySetAsSeries(SIGNAL, true);
   ArraySetAsSeries(SIGNALdna, true);
   ArraySetAsSeries(SIGNALdnb, true);
   ArraySetAsSeries(signal_buf, true);
   ArraySetAsSeries(colors, true);
   ArraySetAsSeries(xtrend, true);

   timeFrame = (DOPtf > 0) ? IntegerToTFEnum(DOPtf) : Period();

   // Create MA handles
   ENUM_TIMEFRAMES trendTF = IntegerToTFEnum(TRENDtf);
   h_TREND_high = iMA(_Symbol, trendTF, TRENDper, TRENDshft, TRENDmode, PRICE_HIGH);
   h_TREND_low  = iMA(_Symbol, trendTF, TRENDper, TRENDshft, TRENDmode, PRICE_LOW);
   h_TREND_med  = iMA(_Symbol, trendTF, TRENDper, TRENDshft, TRENDmode, TRENDtype);

   ENUM_TIMEFRAMES signalTF = IntegerToTFEnum(SIGNALtf);
   h_SIGNAL_high = iMA(_Symbol, signalTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_HIGH);
   h_SIGNAL_low  = iMA(_Symbol, signalTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_LOW);
   h_SIGNAL_med  = iMA(_Symbol, signalTF, SIGNALper, SIGNALshft, SIGNALmode, SIGNALtype);

   if(h_TREND_high == INVALID_HANDLE || h_TREND_low == INVALID_HANDLE || h_TREND_med == INVALID_HANDLE ||
      h_SIGNAL_high == INVALID_HANDLE || h_SIGNAL_low == INVALID_HANDLE || h_SIGNAL_med == INVALID_HANDLE)
   {
      Print("Error creating indicator handles");
      return(INIT_FAILED);
   }

   EventSetTimer(60);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   CleanUpOnIsle1();
   EventKillTimer();

   // Release handles
   IndicatorRelease(h_TREND_high);
   IndicatorRelease(h_TREND_low);
   IndicatorRelease(h_TREND_med);
   IndicatorRelease(h_SIGNAL_high);
   IndicatorRelease(h_SIGNAL_low);
   IndicatorRelease(h_SIGNAL_med);
}

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| Helper forward declarations                                       |
//+------------------------------------------------------------------+
void candle(int direction, int i, const double &open[], const double &close[], const double &high[], const double &low[]);
void UpdatePanelAndLabels();
void manageAlerts(const datetime &time[]);
void doAlert(string direction);
void CleanUpOnIsle1();
double GetHTFPrice(string symbol, ENUM_TIMEFRAMES tf, int price_type, int shift);
double GetHTFMAValMQ5(string symbol, ENUM_TIMEFRAMES tf, int period, int shift_ma, int ma_method, int price_type, int ltf_bar_i,
                      const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[],
                      const double &htf_ma_buffer[]);

//+------------------------------------------------------------------+
//| Main calculation 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 < 100) return(0);
   
   // Set array indexing style to series (index 0 is newest bar)
   ArraySetAsSeries(time, true);
   ArraySetAsSeries(open, true);
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);

   // Set up local arrays to copy MA values
   double trend_high_arr[], trend_low_arr[], trend_med_arr[];
   double sig_high_arr[], sig_low_arr[], sig_med_arr[];

   ArraySetAsSeries(trend_high_arr, true);
   ArraySetAsSeries(trend_low_arr, true);
   ArraySetAsSeries(trend_med_arr, true);
   ArraySetAsSeries(sig_high_arr, true);
   ArraySetAsSeries(sig_low_arr, true);
   ArraySetAsSeries(sig_med_arr, true);

   // Copy buffer data to local arrays
   if(CopyBuffer(h_TREND_high, 0, 0, rates_total, trend_high_arr) < 0) return(0);
   if(CopyBuffer(h_TREND_low,  0, 0, rates_total, trend_low_arr)  < 0) return(0);
   if(CopyBuffer(h_TREND_med,  0, 0, rates_total, trend_med_arr)  < 0) return(0);

   if(CopyBuffer(h_SIGNAL_high, 0, 0, rates_total, sig_high_arr) < 0) return(0);
   if(CopyBuffer(h_SIGNAL_low,  0, 0, rates_total, sig_low_arr)  < 0) return(0);
   if(CopyBuffer(h_SIGNAL_med,  0, 0, rates_total, sig_med_arr)  < 0) return(0);

   int limit = rates_total - prev_calculated;
   if(prev_calculated == 0) limit = rates_total - 1;
   
   //--- DOP Line
   if(showDOP)
   {
      for(int i = limit; i >= 0; i--)
      {
         double open_val[1];
         ENUM_TIMEFRAMES dopTF = IntegerToTFEnum(DOPtf);
         if(CopyOpen(_Symbol, dopTF, time[i], 1, open_val) > 0)
         {
            DOP[i] = open_val[0];
         }
         else
         {
            DOP[i] = (i < rates_total - 1) ? DOP[i+1] : EMPTY_VALUE;
         }
      }
   }

   //--- TREND Calculation
   if(showTREND)
   {
      for(int i = limit; i >= 0; i--)
      {
          double ma_high = GetHTFMAValMQ5(_Symbol, IntegerToTFEnum(TRENDtf), TRENDper, TRENDshft, TRENDmode, PRICE_HIGH, i, time, open, high, low, close, trend_high_arr);
          double ma_low  = GetHTFMAValMQ5(_Symbol, IntegerToTFEnum(TRENDtf), TRENDper, TRENDshft, TRENDmode, PRICE_LOW,  i, time, open, high, low, close, trend_low_arr);
          double ma_med  = GetHTFMAValMQ5(_Symbol, IntegerToTFEnum(TRENDtf), TRENDper, TRENDshft, TRENDmode, TRENDtype, i, time, open, high, low, close, trend_med_arr);
         
         if(close[i] > ma_high) trend[i] = 1;
         else if(close[i] < ma_low) trend[i] = -1;
         else trend[i] = (i < rates_total-1) ? trend[i+1] : 0;
         
         TREND[i] = ma_med;
         Tbgd[i] = ma_med;
         
         TRENDdna[i] = (trend[i] == -1) ? ma_med : EMPTY_VALUE;
         TRENDdnb[i] = (trend[i] == -1) ? ma_med : EMPTY_VALUE;
      }
   }

   //--- SIGNAL Calculation
   if(showSIGNAL)
   {
      for(int i = limit; i >= 0; i--)
      {
          double ma_high = GetHTFMAValMQ5(_Symbol, IntegerToTFEnum(SIGNALtf), SIGNALper, SIGNALshft, SIGNALmode, PRICE_HIGH, i, time, open, high, low, close, sig_high_arr);
          double ma_low  = GetHTFMAValMQ5(_Symbol, IntegerToTFEnum(SIGNALtf), SIGNALper, SIGNALshft, SIGNALmode, PRICE_LOW,  i, time, open, high, low, close, sig_low_arr);
          double ma_med  = GetHTFMAValMQ5(_Symbol, IntegerToTFEnum(SIGNALtf), SIGNALper, SIGNALshft, SIGNALmode, SIGNALtype, i, time, open, high, low, close, sig_med_arr);
         
         if(close[i] > ma_high) signal_buf[i] = 1;
         else if(close[i] < ma_low) signal_buf[i] = -1;
         else signal_buf[i] = (i < rates_total-1) ? signal_buf[i+1] : 0;
         
         SIGNAL[i] = ma_med;
         Sbgd[i] = ma_med;
         
         SIGNALdna[i] = (signal_buf[i] == -1) ? ma_med : EMPTY_VALUE;
         SIGNALdnb[i] = (signal_buf[i] == -1) ? ma_med : EMPTY_VALUE;
      }
   }

   //--- Direction & Candles
   for(int i = limit; i >= 0; i--)
   {
      xtrend[i] = 0;
      candle(2, i, open, close, high, low); // default waiting
      candle6[i] = 0.0;
      candle7[i] = 0.0;
      
      if(trend[i] == 1 && signal_buf[i] == 1)
      {
         xtrend[i] = 1;
         candle(1, i, open, close, high, low);
      }
      else if(trend[i] == -1 && signal_buf[i] == -1)
      {
         xtrend[i] = -1;
         candle(3, i, open, close, high, low);
      }
   }

   //--- Background Zones
   if(showBGDzones)
   {
      for(int i = limit; i >= 0; i--)
      {
         colors[i] = (trend[i] == 1) ? 1 : (trend[i] == -1 ? -1 : 0);
      }
   }

   //--- Draw Objects (Panel & Labels)
   UpdatePanelAndLabels();

   manageAlerts(time);

   return(rates_total);
}

//+------------------------------------------------------------------+
//| Candle Drawing Function                                          |
//+------------------------------------------------------------------+
void candle(int direction, int i, const double &open[], const double &close[], const double &high[], const double &low[])
{
   double bodyHigh = MathMax(open[i], close[i]);
   double bodyLow  = MathMin(open[i], close[i]);
   
   if(!showCANDLES)
   {
      candle0[i] = EMPTY_VALUE;
      candle1[i] = EMPTY_VALUE;
      candle2[i] = EMPTY_VALUE;
      candle3[i] = EMPTY_VALUE;
      candle4[i] = EMPTY_VALUE;
      candle5[i] = EMPTY_VALUE;
      return;
   }

   // Default to wick/body coordinates
   candle0[i] = low[i];
   candle1[i] = high[i];
   candle3[i] = bodyLow;
   candle4[i] = bodyHigh;
   
   switch(direction)
   {
      case 1: // Up
         candle2[i] = 0.0; // Color index 0 (CandleUp)
         candle5[i] = 0.0; // Color index 0 (CandleUp)
         break;
      case 2: // Neutral
         candle2[i] = 1.0; // Color index 1 (CandleWt)
         candle5[i] = 1.0; // Color index 1 (CandleWt)
         break;
      case 3: // Down
         candle2[i] = 2.0; // Color index 2 (CandleDn)
         candle5[i] = 2.0; // Color index 2 (CandleDn)
         break;
      default:
         candle0[i] = EMPTY_VALUE;
         candle1[i] = EMPTY_VALUE;
         candle2[i] = EMPTY_VALUE;
         candle3[i] = EMPTY_VALUE;
         candle4[i] = EMPTY_VALUE;
         candle5[i] = EMPTY_VALUE;
         break;
   }
}

//+------------------------------------------------------------------+
//| Update Panel and Labels                                          |
//+------------------------------------------------------------------+
void UpdatePanelAndLabels()
{
   if(!showBOXtxt) return;

   string stateText  = "WAIT";
   color  stateColor = ColorWait;

   if(xtrend[0] == 1.0)       { stateText = "BUY";  stateColor = TRENDupclr; }
   else if(xtrend[0] == -1.0) { stateText = "SELL"; stateColor = TRENDdnclr; }

   string panelName = ID + "_panel";
   if(ObjectFind(0, panelName) < 0)
   {
      ObjectCreate(0, panelName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
      ObjectSetInteger(0, panelName, OBJPROP_CORNER,    CORNER_LEFT_UPPER);
      ObjectSetInteger(0, panelName, OBJPROP_XDISTANCE, 10 + moveTxtLR);
      ObjectSetInteger(0, panelName, OBJPROP_YDISTANCE, 20 + moveTxtUD);
      ObjectSetInteger(0, panelName, OBJPROP_XSIZE,     120);
      ObjectSetInteger(0, panelName, OBJPROP_YSIZE,     40);
      ObjectSetInteger(0, panelName, OBJPROP_BGCOLOR,   C'20,20,20');
      ObjectSetInteger(0, panelName, OBJPROP_BORDER_TYPE, BORDER_FLAT);
      ObjectSetInteger(0, panelName, OBJPROP_COLOR,     C'60,60,60');
      ObjectSetInteger(0, panelName, OBJPROP_BACK,      true);
      ObjectSetInteger(0, panelName, OBJPROP_SELECTABLE, false);
   }
   else
   {
      ObjectSetInteger(0, panelName, OBJPROP_XDISTANCE, 10 + moveTxtLR);
      ObjectSetInteger(0, panelName, OBJPROP_YDISTANCE, 20 + moveTxtUD);
   }

   if(showSig)
   {
      string lblName = ID + "_label";
      if(ObjectFind(0, lblName) < 0)
      {
         ObjectCreate(0, lblName, OBJ_LABEL, 0, 0, 0);
         ObjectSetInteger(0, lblName, OBJPROP_CORNER,    CORNER_LEFT_UPPER);
         ObjectSetInteger(0, lblName, OBJPROP_SELECTABLE, false);
      }
      ObjectSetInteger(0, lblName, OBJPROP_XDISTANCE, 18 + moveTxtLR);
      ObjectSetInteger(0, lblName, OBJPROP_YDISTANCE, 25 + moveTxtUD);
      ObjectSetString (0, lblName, OBJPROP_TEXT,      stateText);
      ObjectSetInteger(0, lblName, OBJPROP_COLOR,     stateColor);
      ObjectSetInteger(0, lblName, OBJPROP_FONTSIZE,  FontSize);
      ObjectSetString (0, lblName, OBJPROP_FONT,      "Arial Bold");
   }

   ChartRedraw(0);
}

//+------------------------------------------------------------------+
//| Alert Management                                                 |
//+------------------------------------------------------------------+
void manageAlerts(const datetime &time[])
{
   if(!AlertsOn) return;
   
   static datetime lastAlertTime = 0;
   int shift = AlertsOnCurrent ? 0 : 1;
   
   if(xtrend[shift] != xtrend[shift+1] && time[shift] != lastAlertTime)
   {
      lastAlertTime = time[shift];
      string dir = (xtrend[shift] == 1.0) ? "UP" : "DOWN";
      doAlert(dir);
   }
}

void doAlert(string direction)
{
   string msg = _Symbol + " " + EnumToString(timeFrame) + " : Direction changed to " + direction;
   
   if(AlertsMessage) Alert(msg);
   if(AlertsSound) PlaySound(soundfile);
   if(alertsNotify) SendNotification(msg);
   if(AlertsEmail) SendMail("XU-MA Alert", msg);
}

//+------------------------------------------------------------------+
//| Clean all objects                                                |
//+------------------------------------------------------------------+
void CleanUpOnIsle1()
{
   for(int i = ObjectsTotal(0, -1, -1)-1; i >= 0; i--)
   {
      string name = ObjectName(0, i, -1, -1);
      if(StringFind(name, ID) == 0)
         ObjectDelete(0, name);
   }
}

//+------------------------------------------------------------------+
//| Get price of HTF bar at shift                                    |
//+------------------------------------------------------------------+
double GetHTFPrice(string symbol, ENUM_TIMEFRAMES tf, int price_type, int shift)
{
   double res[1];
   switch(price_type)
   {
      case PRICE_CLOSE:
         if(CopyClose(symbol, tf, shift, 1, res) > 0) return res[0];
         break;
      case PRICE_OPEN:
         if(CopyOpen(symbol, tf, shift, 1, res) > 0) return res[0];
         break;
      case PRICE_HIGH:
         if(CopyHigh(symbol, tf, shift, 1, res) > 0) return res[0];
         break;
      case PRICE_LOW:
         if(CopyLow(symbol, tf, shift, 1, res) > 0) return res[0];
         break;
      case PRICE_MEDIAN:
         {
            double h[1], l[1];
            if(CopyHigh(symbol, tf, shift, 1, h) > 0 && CopyLow(symbol, tf, shift, 1, l) > 0)
               return (h[0] + l[0]) / 2.0;
         }
         break;
      case PRICE_TYPICAL:
         {
            double h[1], l[1], c[1];
            if(CopyHigh(symbol, tf, shift, 1, h) > 0 && CopyLow(symbol, tf, shift, 1, l) > 0 && CopyClose(symbol, tf, shift, 1, c) > 0)
               return (h[0] + l[0] + c[0]) / 3.0;
         }
         break;
      case PRICE_WEIGHTED:
         {
            double h[1], l[1], c[1];
            if(CopyHigh(symbol, tf, shift, 1, h) > 0 && CopyLow(symbol, tf, shift, 1, l) > 0 && CopyClose(symbol, tf, shift, 1, c) > 0)
               return (h[0] + l[0] + 2.0 * c[0]) / 4.0;
         }
         break;
   }
   return 0;
}

//+------------------------------------------------------------------+
//| Calculate non-repainting HTF MA value for MQ5                    |
//+------------------------------------------------------------------+
double GetHTFMAValMQ5(string symbol, ENUM_TIMEFRAMES tf, int period, int shift_ma, int ma_method, int price_type, int ltf_bar_i,
                      const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[],
                      const double &htf_ma_buffer[])
{
   if(tf == PERIOD_CURRENT || tf == (ENUM_TIMEFRAMES)_Period)
   {
      return htf_ma_buffer[ltf_bar_i];
   }
   
   int htf_shift = iBarShift(symbol, tf, time[ltf_bar_i], false);
   htf_shift += shift_ma;
   
   // Calculate forming HTF bar prices at ltf_bar_i
   datetime htf_start_time = iTime(symbol, tf, htf_shift);
   int first_ltf_shift = iBarShift(symbol, (ENUM_TIMEFRAMES)_Period, htf_start_time, false);
   if(first_ltf_shift < ltf_bar_i) first_ltf_shift = ltf_bar_i;
   
   double temp_high = high[ltf_bar_i];
   double temp_low = low[ltf_bar_i];
   for(int k = ltf_bar_i + 1; k <= first_ltf_shift; k++)
   {
      if(high[k] > temp_high) temp_high = high[k];
      if(low[k] < temp_low) temp_low = low[k];
   }
   double temp_open = open[first_ltf_shift];
   double temp_close = close[ltf_bar_i];
   
   double temp_price = 0;
   switch(price_type)
   {
      case PRICE_CLOSE:     temp_price = temp_close; break;
      case PRICE_OPEN:      temp_price = temp_open; break;
      case PRICE_HIGH:      temp_price = temp_high; break;
      case PRICE_LOW:       temp_price = temp_low; break;
      case PRICE_MEDIAN:    temp_price = (temp_high + temp_low) / 2.0; break;
      case PRICE_TYPICAL:   temp_price = (temp_high + temp_low + temp_close) / 3.0; break;
      case PRICE_WEIGHTED:  temp_price = (temp_high + temp_low + 2.0 * temp_close) / 4.0; break;
      default:              temp_price = temp_close; break;
   }
   
   double prev_ma = htf_ma_buffer[htf_shift + 1];
   
   if(ma_method == MODE_EMA)
   {
      double alpha = 2.0 / (period + 1.0);
      return temp_price * alpha + prev_ma * (1.0 - alpha);
   }
   else if(ma_method == MODE_SMMA)
   {
      return (temp_price + prev_ma * (period - 1.0)) / period;
   }
   else if(ma_method == MODE_LWMA)
   {
      double sum = temp_price * period;
      double weight_sum = period;
      for(int k = 1; k < period; k++)
      {
         double p = GetHTFPrice(symbol, tf, price_type, htf_shift + k);
         sum += p * (period - k);
         weight_sum += (period - k);
      }
      return sum / weight_sum;
   }
   else // MODE_SMA
   {
      double sum = temp_price;
      for(int k = 1; k < period; k++)
      {
         sum += GetHTFPrice(symbol, tf, price_type, htf_shift + k);
      }
      return sum / period;
   }
}
//+------------------------------------------------------------------+
