//+------------------------------------------------------------------+
//|                                                    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 ENUM_TIMEFRAMES CandleColorTF              = PERIOD_CURRENT;
input color           CandleUp                   = C'96,170,204';
input color           CandleWt                   = C'34,34,34';
input color           CandleDn                   = C'255,140,255';
input bool            showBGchange               = true;
input ENUM_TIMEFRAMES BGchangeTF                 = PERIOD_CURRENT;
input color           BGchangeUpClr              = C'18,45,58';
input color           BGchangeWtClr              = C'24,24,24';
input color           BGchangeDnClr              = C'58,28,58';

//--- [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[];
double candleXtrend[];
double bgXtrend[];

//--- 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;
int h_BG_TREND_high = INVALID_HANDLE;
int h_BG_TREND_low  = INVALID_HANDLE;
int h_BG_SIGNAL_high = INVALID_HANDLE;
int h_BG_SIGNAL_low  = INVALID_HANDLE;
int h_CANDLE_TREND_high = INVALID_HANDLE;
int h_CANDLE_TREND_low  = INVALID_HANDLE;
int h_CANDLE_SIGNAL_high = INVALID_HANDLE;
int h_CANDLE_SIGNAL_low  = 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);
   ArraySetAsSeries(candleXtrend, true);
   ArraySetAsSeries(bgXtrend, 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);

   h_BG_TREND_high = iMA(_Symbol, BGchangeTF, TRENDper, TRENDshft, TRENDmode, PRICE_HIGH);
   h_BG_TREND_low  = iMA(_Symbol, BGchangeTF, TRENDper, TRENDshft, TRENDmode, PRICE_LOW);
   h_BG_SIGNAL_high = iMA(_Symbol, BGchangeTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_HIGH);
   h_BG_SIGNAL_low  = iMA(_Symbol, BGchangeTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_LOW);

   h_CANDLE_TREND_high = iMA(_Symbol, CandleColorTF, TRENDper, TRENDshft, TRENDmode, PRICE_HIGH);
   h_CANDLE_TREND_low  = iMA(_Symbol, CandleColorTF, TRENDper, TRENDshft, TRENDmode, PRICE_LOW);
   h_CANDLE_SIGNAL_high = iMA(_Symbol, CandleColorTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_HIGH);
   h_CANDLE_SIGNAL_low  = iMA(_Symbol, CandleColorTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_LOW);

   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 ||
      h_BG_TREND_high == INVALID_HANDLE || h_BG_TREND_low == INVALID_HANDLE ||
      h_BG_SIGNAL_high == INVALID_HANDLE || h_BG_SIGNAL_low == INVALID_HANDLE ||
      h_CANDLE_TREND_high == INVALID_HANDLE || h_CANDLE_TREND_low == INVALID_HANDLE ||
      h_CANDLE_SIGNAL_high == INVALID_HANDLE || h_CANDLE_SIGNAL_low == 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);
   IndicatorRelease(h_BG_TREND_high);
   IndicatorRelease(h_BG_TREND_low);
   IndicatorRelease(h_BG_SIGNAL_high);
   IndicatorRelease(h_BG_SIGNAL_low);
   IndicatorRelease(h_CANDLE_TREND_high);
   IndicatorRelease(h_CANDLE_TREND_low);
   IndicatorRelease(h_CANDLE_SIGNAL_high);
   IndicatorRelease(h_CANDLE_SIGNAL_low);
}

//+------------------------------------------------------------------+
//| 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();
bool BuildSelectedTimeframeTrend(const datetime &time[], int rates_total, ENUM_TIMEFRAMES selectedTF,
                                 int trendHighHandle, int trendLowHandle,
                                 int signalHighHandle, int signalLowHandle,
                                 double &stateBuffer[]);
bool BuildCandleTrend(const datetime &time[], int rates_total);
bool BuildBackgroundTrend(const datetime &time[], int rates_total);
void DrawBackgroundZones(const datetime &time[], int rates_total);
void CreateBGRect(string name, datetime t1, datetime t2, color clr);
double GetHTFPrice(string symbol, ENUM_TIMEFRAMES tf, int price_type, int shift);
double GetNrpHTFMAVal(string symbol, ENUM_TIMEFRAMES tf, int period, int shift_ma, int ma_method, int price_type, int 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;
         }
      }
   }

    ENUM_TIMEFRAMES trendTF  = IntegerToTFEnum(TRENDtf);
    ENUM_TIMEFRAMES signalTF = IntegerToTFEnum(SIGNALtf);
    bool trendDiffTF  = (trendTF  != PERIOD_CURRENT && trendTF  != (ENUM_TIMEFRAMES)_Period);
    bool signalDiffTF = (signalTF != PERIOD_CURRENT && signalTF != (ENUM_TIMEFRAMES)_Period);

    //--- TREND Calculation
    if(showTREND)
    {
       for(int i = limit; i >= 0; i--)
       {
          double ma_high, ma_low, ma_med;
          if(trendDiffTF)
          {
             ma_high = GetNrpHTFMAVal(_Symbol, trendTF, TRENDper, TRENDshft, TRENDmode, PRICE_HIGH, i, time, open, high, low, close, trend_high_arr);
             ma_low  = GetNrpHTFMAVal(_Symbol, trendTF, TRENDper, TRENDshft, TRENDmode, PRICE_LOW,  i, time, open, high, low, close, trend_low_arr);
             ma_med  = GetNrpHTFMAVal(_Symbol, trendTF, TRENDper, TRENDshft, TRENDmode, TRENDtype, i, time, open, high, low, close, trend_med_arr);
          }
          else
          {
             ma_high = trend_high_arr[i];
             ma_low  = trend_low_arr[i];
             ma_med  = trend_med_arr[i];
          }
          
          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, ma_low, ma_med;
          if(signalDiffTF)
          {
             ma_high = GetNrpHTFMAVal(_Symbol, signalTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_HIGH, i, time, open, high, low, close, sig_high_arr);
             ma_low  = GetNrpHTFMAVal(_Symbol, signalTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_LOW,  i, time, open, high, low, close, sig_low_arr);
             ma_med  = GetNrpHTFMAVal(_Symbol, signalTF, SIGNALper, SIGNALshft, SIGNALmode, SIGNALtype, i, time, open, high, low, close, sig_med_arr);
          }
          else
          {
             ma_high = sig_high_arr[i];
             ma_low  = sig_low_arr[i];
             ma_med  = sig_med_arr[i];
          }
          
          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
   for(int i = limit; i >= 0; i--)
   {
      xtrend[i] = 0;
      candle6[i] = 0.0;
      candle7[i] = 0.0;
      
      if(trend[i] == 1 && signal_buf[i] == 1)
      {
         xtrend[i] = 1;
      }
      else if(trend[i] == -1 && signal_buf[i] == -1)
      {
         xtrend[i] = -1;
      }
   }

   //--- Candles colored from selected candle timeframe
   if(!BuildCandleTrend(time, rates_total))
   {
      for(int i = limit; i >= 0; i--)
         candleXtrend[i] = xtrend[i];
   }

   for(int i = limit; i >= 0; i--)
   {
      if(candleXtrend[i] == 1.0)
         candle(1, i, open, close, high, low);
      else if(candleXtrend[i] == -1.0)
         candle(3, i, open, close, high, low);
      else
         candle(2, i, open, close, high, low);
   }

   //--- Draw background coloring on xtrend change
   DrawBackgroundZones(time, rates_total);

   //--- 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                                                |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Build trend from selected timeframe and map it to chart bars     |
//+------------------------------------------------------------------+
bool BuildSelectedTimeframeTrend(const datetime &time[], int rates_total, ENUM_TIMEFRAMES selectedTF,
                                 int trendHighHandle, int trendLowHandle,
                                 int signalHighHandle, int signalLowHandle,
                                 double &stateBuffer[])
{
   ArrayResize(stateBuffer, rates_total);
   ArraySetAsSeries(stateBuffer, true);

   if(selectedTF == PERIOD_CURRENT)
   {
      for(int i = 0; i < rates_total; i++)
         stateBuffer[i] = xtrend[i];
      return(true);
   }

   int bgBars = Bars(_Symbol, selectedTF);
   if(bgBars <= 0)
      return(false);

   int oldestShift = iBarShift(_Symbol, selectedTF, time[rates_total - 1], false);
   int newestShift = iBarShift(_Symbol, selectedTF, time[0], false);
   if(oldestShift < 0 || newestShift < 0)
      return(false);

   int copyCount = oldestShift + 1;
   if(copyCount > bgBars)
      copyCount = bgBars;

   double bgClose[], bgTrendHigh[], bgTrendLow[], bgSignalHigh[], bgSignalLow[];
   double bgTrend[], bgSignal[];

   ArraySetAsSeries(bgClose, true);
   ArraySetAsSeries(bgTrendHigh, true);
   ArraySetAsSeries(bgTrendLow, true);
   ArraySetAsSeries(bgSignalHigh, true);
   ArraySetAsSeries(bgSignalLow, true);
   ArraySetAsSeries(bgTrend, true);
   ArraySetAsSeries(bgSignal, true);

   int copiedClose = CopyClose(_Symbol, selectedTF, 0, copyCount, bgClose);
   int copiedTH = CopyBuffer(trendHighHandle, 0, 0, copyCount, bgTrendHigh);
   int copiedTL = CopyBuffer(trendLowHandle,  0, 0, copyCount, bgTrendLow);
   int copiedSH = CopyBuffer(signalHighHandle, 0, 0, copyCount, bgSignalHigh);
   int copiedSL = CopyBuffer(signalLowHandle,  0, 0, copyCount, bgSignalLow);

   int copied = copiedClose;
   if(copiedTH < copied) copied = copiedTH;
   if(copiedTL < copied) copied = copiedTL;
   if(copiedSH < copied) copied = copiedSH;
   if(copiedSL < copied) copied = copiedSL;
   if(copied <= 0)
      return(false);

   ArrayResize(bgTrend, copied);
   ArrayResize(bgSignal, copied);
   ArraySetAsSeries(bgTrend, true);
   ArraySetAsSeries(bgSignal, true);

   for(int j = copied - 1; j >= 0; j--)
   {
      if(bgClose[j] > bgTrendHigh[j])
         bgTrend[j] = 1.0;
      else if(bgClose[j] < bgTrendLow[j])
         bgTrend[j] = -1.0;
      else
         bgTrend[j] = (j < copied - 1) ? bgTrend[j + 1] : 0.0;

      if(bgClose[j] > bgSignalHigh[j])
         bgSignal[j] = 1.0;
      else if(bgClose[j] < bgSignalLow[j])
         bgSignal[j] = -1.0;
      else
         bgSignal[j] = (j < copied - 1) ? bgSignal[j + 1] : 0.0;
   }

   // Copy current timeframe prices for non-repainting calculations
   double open[], high[], low[], close[];
   ArraySetAsSeries(open, true);
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);

   if(CopyOpen(_Symbol, _Period, 0, rates_total, open) <= 0) return(false);
   if(CopyHigh(_Symbol, _Period, 0, rates_total, high) <= 0) return(false);
   if(CopyLow(_Symbol, _Period, 0, rates_total, low) <= 0) return(false);
   if(CopyClose(_Symbol, _Period, 0, rates_total, close) <= 0) return(false);

   for(int i = rates_total - 1; i >= 0; i--)
   {
      int shift = iBarShift(_Symbol, selectedTF, time[i], false);
      if(shift >= 0 && shift < copied)
      {
         double temp_trend_high = GetNrpHTFMAVal(_Symbol, selectedTF, TRENDper,  TRENDshft,  TRENDmode,  PRICE_HIGH, i, time, open, high, low, close, bgTrendHigh);
         double temp_trend_low  = GetNrpHTFMAVal(_Symbol, selectedTF, TRENDper,  TRENDshft,  TRENDmode,  PRICE_LOW,  i, time, open, high, low, close, bgTrendLow);
         double temp_sig_high   = GetNrpHTFMAVal(_Symbol, selectedTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_HIGH, i, time, open, high, low, close, bgSignalHigh);
         double temp_sig_low    = GetNrpHTFMAVal(_Symbol, selectedTF, SIGNALper, SIGNALshft, SIGNALmode, PRICE_LOW,  i, time, open, high, low, close, bgSignalLow);

         double temp_close = close[i];

         double temp_trend;
         if(temp_close > temp_trend_high)
            temp_trend = 1.0;
         else if(temp_close < temp_trend_low)
            temp_trend = -1.0;
         else
            temp_trend = (shift + 1 < copied) ? bgTrend[shift + 1] : 0.0;

         double temp_signal;
         if(temp_close > temp_sig_high)
            temp_signal = 1.0;
         else if(temp_close < temp_sig_low)
            temp_signal = -1.0;
         else
            temp_signal = (shift + 1 < copied) ? bgSignal[shift + 1] : 0.0;

         if(temp_trend == 1.0 && temp_signal == 1.0)
            stateBuffer[i] = 1.0;
         else if(temp_trend == -1.0 && temp_signal == -1.0)
            stateBuffer[i] = -1.0;
         else
            stateBuffer[i] = 0.0;
      }
      else
      {
         stateBuffer[i] = (i < rates_total - 1) ? stateBuffer[i + 1] : 0.0;
      }
   }

   return(true);
}

//+------------------------------------------------------------------+
//| Build candle trend from selected candle timeframe                |
//+------------------------------------------------------------------+
bool BuildCandleTrend(const datetime &time[], int rates_total)
{
   return(BuildSelectedTimeframeTrend(time, rates_total, CandleColorTF,
                                      h_CANDLE_TREND_high, h_CANDLE_TREND_low,
                                      h_CANDLE_SIGNAL_high, h_CANDLE_SIGNAL_low,
                                      candleXtrend));
}

//+------------------------------------------------------------------+
//| Build background trend from selected background timeframe        |
//+------------------------------------------------------------------+
bool BuildBackgroundTrend(const datetime &time[], int rates_total)
{
   return(BuildSelectedTimeframeTrend(time, rates_total, BGchangeTF,
                                      h_BG_TREND_high, h_BG_TREND_low,
                                      h_BG_SIGNAL_high, h_BG_SIGNAL_low,
                                      bgXtrend));
}

//+------------------------------------------------------------------+
//| Draw background colour zones between xtrend transitions         |
//+------------------------------------------------------------------+
void DrawBackgroundZones(const datetime &time[], int rates_total)
{
   string prefix = ID + "_bg_";

   // Delete all existing BG zone objects
   for(int j = ObjectsTotal(0, -1, -1) - 1; j >= 0; j--)
   {
      string nm = ObjectName(0, j, -1, -1);
      if(StringFind(nm, prefix) == 0)
         ObjectDelete(0, nm);
   }

   if(!showBGchange || rates_total < 2) return;
   if(!BuildBackgroundTrend(time, rates_total)) return;

   // Walk from oldest bar (high series index) to newest (index 0)
   // Collect groups of consecutive bars with the same xtrend value
   int cnt          = 0;
   int groupStart   = rates_total - 1;   // index of oldest bar in current group

   for(int i = rates_total - 2; i >= -1; i--)
   {
      // Use a sentinel value to flush the last group when we reach the end
      double currTrend = (i >= 0) ? bgXtrend[i] : (bgXtrend[0] + 999.0);

      if(currTrend != bgXtrend[groupStart])
      {
         double gt = bgXtrend[groupStart];
         string   nm  = prefix + IntegerToString(cnt++);
         color    clr = (gt == 1.0) ? BGchangeUpClr : (gt == -1.0 ? BGchangeDnClr : BGchangeWtClr);
         datetime t1  = time[groupStart];                                          // left edge (older)
         datetime t2  = (i >= 0) ? time[i] : (time[0] + (datetime)PeriodSeconds()); // right edge (newer)
         CreateBGRect(nm, t1, t2, clr);
         if(i >= 0) groupStart = i;
      }
   }
}

//+------------------------------------------------------------------+
//| Create or update a filled background rectangle                   |
//+------------------------------------------------------------------+
void CreateBGRect(string name, datetime t1, datetime t2, color clr)
{
   if(ObjectFind(0, name) < 0)
      ObjectCreate(0, name, OBJ_RECTANGLE, 0, t1, 1e10, t2, -1e10);

   ObjectSetInteger(0, name, OBJPROP_TIME,  0, t1);
   ObjectSetDouble (0, name, OBJPROP_PRICE, 0,  1e10);
   ObjectSetInteger(0, name, OBJPROP_TIME,  1, t2);
   ObjectSetDouble (0, name, OBJPROP_PRICE, 1, -1e10);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
   ObjectSetInteger(0, name, OBJPROP_BACK,  true);
   ObjectSetInteger(0, name, OBJPROP_FILL,  true);
   ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
   ObjectSetInteger(0, name, OBJPROP_HIDDEN,  true);
}
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                            |
//+------------------------------------------------------------------+
double GetNrpHTFMAVal(string symbol, ENUM_TIMEFRAMES tf, int period, int shift_ma, int ma_method, int price_type, int 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)
   {
      if(i >= 0 && i < ArraySize(htf_ma_buffer))
         return htf_ma_buffer[i];
      return 0;
   }
   
   int htf_shift = iBarShift(symbol, tf, time[i], false);
   if(htf_shift < 0) return 0;
   htf_shift += shift_ma;
   
   if(ArraySize(htf_ma_buffer) <= 0) return 0;
   if(htf_shift >= ArraySize(htf_ma_buffer))
      return htf_ma_buffer[ArraySize(htf_ma_buffer) - 1];
   
   // Calculate forming HTF bar prices at LTF bar i (series indexing: index-0 is newest)
   datetime htf_start_time = iTime(symbol, tf, htf_shift);
   int first_ltf_i = iBarShift(symbol, (ENUM_TIMEFRAMES)_Period, htf_start_time, false);
   if(first_ltf_i < 0) first_ltf_i = i;
   if(first_ltf_i < i) first_ltf_i = i;
   
   double temp_high = high[i];
   double temp_low = low[i];
   for(int k = i; k <= first_ltf_i; k++)
   {
      if(k >= ArraySize(high)) break;
      if(high[k] > temp_high) temp_high = high[k];
      if(low[k] < temp_low) temp_low = low[k];
   }
   double temp_open = open[first_ltf_i];
   double temp_close = close[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;
   }
   
   int prev_htf_shift = htf_shift + 1;
   if(prev_htf_shift >= ArraySize(htf_ma_buffer))
      prev_htf_shift = ArraySize(htf_ma_buffer) - 1;
   if(prev_htf_shift < 0) return 0;
   double prev_ma = htf_ma_buffer[prev_htf_shift];
   
   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;
   }
}
//+------------------------------------------------------------------+
