//+------------------------------------------------------------------+
//|                           1. Smart WaveTrend Crossover PART1.mq5 |
//|                           Copyright 2026, Allan Munene Mutiiria. |
//|                                   https://t.me/Forex_Algo_Trader |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Allan Munene Mutiiria."
#property link "https://t.me/Forex_Algo_Trader"
#property version "1.00"

#property indicator_chart_window
#property indicator_buffers 23
#property indicator_plots 3
#property indicator_label1 "Colored Candles"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrTeal, clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Buy Signals"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrForestGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "Sell Signals"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrOrangeRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
input group "Colors"
input color col_up = clrTeal;                // Bull Color
input color col_dn = clrRed;                 // Bear Color

input group "WaveTrend Settings for Signals"
input int wt_channel_len = 5;                // Signal Channel Length
input int wt_average_len = 10;               // Signal Average Length
input int wt_ma_len = 4;                     // Signal MA Length

input group "WaveTrend Settings for Trend"
input int wt_trend_channel_len = 10;         // Trend Channel Length
input int wt_trend_average_len = 100;        // Trend Average Length
input int wt_trend_ma_len = 10;              // Trend MA Length

input group "Signal Settings"
input bool use_trend_filter = true;          // Use Trend Filter?
input color signal_buy_col = clrForestGreen; // Buy Signal Color
input color signal_sell_col = clrOrangeRed;  // Sell Signal Color
input int base_offset = 10;                  // Base Signal Offset from Candle

input group "Visual Settings"
input bool color_candles = true;             // Color Candles by Trend?

//+------------------------------------------------------------------+
//| Buffers                                                          |
//+------------------------------------------------------------------+
double esa_signal[];          //--- Signal ESA buffer
double d_signal[];            //--- Signal D buffer
double ci_signal[];           //--- Signal CI buffer
double wt1_signal[];          //--- Signal WT1 buffer
double wt2_signal[];          //--- Signal WT2 buffer
double signal_hist[];         //--- Signal histogram buffer
double signal_bull_cross[];   //--- Signal bull cross buffer
double signal_bear_cross[];   //--- Signal bear cross buffer

double esa_trend[];           //--- Trend ESA buffer
double d_trend[];             //--- Trend D buffer
double ci_trend[];            //--- Trend CI buffer
double wt1_trend[];           //--- Trend WT1 buffer
double wt2_trend[];           //--- Trend WT2 buffer
double trend_hist[];          //--- Trend histogram buffer
double trend_is_bull[];       //--- Trend bull indicator buffer
double trend_is_bear[];       //--- Trend bear indicator buffer

double openBuf[];             //--- Open price buffer
double highBuf[];             //--- High price buffer
double lowBuf[];              //--- Low price buffer
double closeBuf[];            //--- Close price buffer
double candleColorBuf[];      //--- Candle color buffer
double buyArrowBuf[];         //--- Buy arrow buffer
double sellArrowBuf[];        //--- Sell arrow buffer

//+------------------------------------------------------------------+
//| Calculate EMA manually                                           |
//+------------------------------------------------------------------+
double CalcEMA(double prev, double val, int period) {
   if (period < 1) return val;              //--- Handle invalid period
   double alpha = 2.0 / (period + 1);       //--- Compute alpha factor
   return alpha * val + (1 - alpha) * prev; //--- Return EMA value
}

//+------------------------------------------------------------------+
//| Initialize indicator                                             |
//+------------------------------------------------------------------+
int OnInit() {
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits); //--- Set indicator digits
   IndicatorSetString(INDICATOR_SHORTNAME, "Smart WaveTrend Crossover PART1"); //--- Set short name

   SetIndexBuffer(0, openBuf, INDICATOR_DATA);       //--- Bind open buffer
   SetIndexBuffer(1, highBuf, INDICATOR_DATA);       //--- Bind high buffer
   SetIndexBuffer(2, lowBuf, INDICATOR_DATA);        //--- Bind low buffer
   SetIndexBuffer(3, closeBuf, INDICATOR_DATA);      //--- Bind close buffer
   SetIndexBuffer(4, candleColorBuf, INDICATOR_COLOR_INDEX); //--- Bind color buffer
   PlotIndexSetInteger(0, PLOT_SHOW_DATA, color_candles); //--- Set candle visibility

   SetIndexBuffer(5, buyArrowBuf, INDICATOR_DATA);   //--- Bind buy arrow buffer
   SetIndexBuffer(6, sellArrowBuf, INDICATOR_DATA);  //--- Bind sell arrow buffer
   PlotIndexSetInteger(1, PLOT_ARROW, 233);          //--- Set buy arrow symbol
   PlotIndexSetInteger(1, PLOT_SHOW_DATA, true);     //--- Enable buy arrow display
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 0);       //--- Set buy draw begin
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, 0, signal_buy_col); //--- Set buy color

   PlotIndexSetInteger(2, PLOT_ARROW, 234);          //--- Set sell arrow symbol
   PlotIndexSetInteger(2, PLOT_SHOW_DATA, true);     //--- Enable sell arrow display
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, 0);       //--- Set sell draw begin
   PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, signal_sell_col); //--- Set sell color

   SetIndexBuffer(7, esa_signal, INDICATOR_CALCULATIONS); //--- Bind signal ESA
   SetIndexBuffer(8, d_signal, INDICATOR_CALCULATIONS);   //--- Bind signal D
   SetIndexBuffer(9, ci_signal, INDICATOR_CALCULATIONS);  //--- Bind signal CI
   SetIndexBuffer(10, wt1_signal, INDICATOR_CALCULATIONS); //--- Bind signal WT1
   SetIndexBuffer(11, wt2_signal, INDICATOR_CALCULATIONS); //--- Bind signal WT2
   SetIndexBuffer(12, signal_hist, INDICATOR_CALCULATIONS); //--- Bind signal hist
   SetIndexBuffer(13, signal_bull_cross, INDICATOR_CALCULATIONS); //--- Bind bull cross
   SetIndexBuffer(14, signal_bear_cross, INDICATOR_CALCULATIONS); //--- Bind bear cross

   SetIndexBuffer(15, esa_trend, INDICATOR_CALCULATIONS); //--- Bind trend ESA
   SetIndexBuffer(16, d_trend, INDICATOR_CALCULATIONS);   //--- Bind trend D
   SetIndexBuffer(17, ci_trend, INDICATOR_CALCULATIONS);  //--- Bind trend CI
   SetIndexBuffer(18, wt1_trend, INDICATOR_CALCULATIONS); //--- Bind trend WT1
   SetIndexBuffer(19, wt2_trend, INDICATOR_CALCULATIONS); //--- Bind trend WT2
   SetIndexBuffer(20, trend_hist, INDICATOR_CALCULATIONS); //--- Bind trend hist
   SetIndexBuffer(21, trend_is_bull, INDICATOR_CALCULATIONS); //--- Bind trend bull
   SetIndexBuffer(22, trend_is_bear, INDICATOR_CALCULATIONS); //--- Bind trend bear

   return(INIT_SUCCEEDED);                        //--- Return success
}

//+------------------------------------------------------------------+
//| Deinitialize indicator                                           |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}

//+------------------------------------------------------------------+
//| Calculate indicator values                                       |
//+------------------------------------------------------------------+
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[]) {
   int start = prev_calculated - 1;               //--- Set start index
   if (start < 0) start = 0;                      //--- Adjust invalid start

   if (prev_calculated == 0) {                    //--- Handle initial calculation
      ArrayInitialize(esa_signal, EMPTY_VALUE);   //--- Init signal ESA
      ArrayInitialize(d_signal, EMPTY_VALUE);     //--- Init signal D
      ArrayInitialize(ci_signal, EMPTY_VALUE);    //--- Init signal CI
      ArrayInitialize(wt1_signal, EMPTY_VALUE);  //--- Init signal WT1
      ArrayInitialize(wt2_signal, EMPTY_VALUE);  //--- Init signal WT2
      ArrayInitialize(signal_hist, EMPTY_VALUE); //--- Init signal hist
      ArrayInitialize(signal_bull_cross, 0);     //--- Init bull cross
      ArrayInitialize(signal_bear_cross, 0);     //--- Init bear cross

      ArrayInitialize(esa_trend, EMPTY_VALUE);   //--- Init trend ESA
      ArrayInitialize(d_trend, EMPTY_VALUE);     //--- Init trend D
      ArrayInitialize(ci_trend, EMPTY_VALUE);    //--- Init trend CI
      ArrayInitialize(wt1_trend, EMPTY_VALUE);  //--- Init trend WT1
      ArrayInitialize(wt2_trend, EMPTY_VALUE);  //--- Init trend WT2
      ArrayInitialize(trend_hist, EMPTY_VALUE); //--- Init trend hist
      ArrayInitialize(trend_is_bull, 0);         //--- Init trend bull
      ArrayInitialize(trend_is_bear, 0);         //--- Init trend bear

      ArrayInitialize(buyArrowBuf, EMPTY_VALUE); //--- Init buy arrows
      ArrayInitialize(sellArrowBuf, EMPTY_VALUE);//--- Init sell arrows
   }

   for (int i = start; i < rates_total; i++) {   //--- Loop through bars
      double src_wt = (high[i] + low[i] + close[i]) / 3.0; //--- Compute source

      if (i == 0) {                               //--- Handle first bar signal
         esa_signal[i] = src_wt;                  //--- Set initial ESA
         d_signal[i] = MathAbs(src_wt - esa_signal[i]); //--- Set initial D
         double denom_signal = 0.015 * d_signal[i]; //--- Compute denominator
         ci_signal[i] = (denom_signal != 0.0) ? (src_wt - esa_signal[i]) / denom_signal : 0.0; //--- Set CI
         wt1_signal[i] = ci_signal[i];            //--- Set initial WT1
         wt2_signal[i] = wt1_signal[i];           //--- Set initial WT2
      } else {                                    //--- Handle subsequent bars
         esa_signal[i] = CalcEMA(esa_signal[i-1], src_wt, wt_channel_len); //--- Update ESA
         d_signal[i] = CalcEMA(d_signal[i-1], MathAbs(src_wt - esa_signal[i]), wt_channel_len); //--- Update D
         double denom_signal = 0.015 * d_signal[i]; //--- Compute denominator
         ci_signal[i] = (denom_signal != 0.0) ? (src_wt - esa_signal[i]) / denom_signal : 0.0; //--- Update CI
         wt1_signal[i] = CalcEMA(wt1_signal[i-1], ci_signal[i], wt_average_len); //--- Update WT1
         wt2_signal[i] = 0;                       //--- Reset WT2
         int cnt_ma = 0;                          //--- Init MA count
         for (int k = 0; k < wt_ma_len; k++) {    //--- Loop for MA
            if (i - k < 0) break;                 //--- Skip invalid index
            wt2_signal[i] += wt1_signal[i - k];   //--- Accumulate WT1
            cnt_ma++;                             //--- Increment count
         }
         if (cnt_ma > 0) wt2_signal[i] /= cnt_ma; //--- Average WT2
      }

      signal_hist[i] = wt1_signal[i] - wt2_signal[i]; //--- Compute signal hist
      signal_bull_cross[i] = (wt1_signal[i] > wt2_signal[i] && (i == 0 || wt1_signal[i-1] <= wt2_signal[i-1])) ? 1 : 0; //--- Detect bull cross
      signal_bear_cross[i] = (wt1_signal[i] < wt2_signal[i] && (i == 0 || wt1_signal[i-1] >= wt2_signal[i-1])) ? 1 : 0; //--- Detect bear cross

      double src_wt_trend = src_wt;              //--- Set trend source
      if (i == 0) {                              //--- Handle first bar trend
         esa_trend[i] = src_wt_trend;            //--- Set initial ESA
         d_trend[i] = MathAbs(src_wt_trend - esa_trend[i]); //--- Set initial D
         double denom_trend = 0.015 * d_trend[i]; //--- Compute denominator
         ci_trend[i] = (denom_trend != 0.0) ? (src_wt_trend - esa_trend[i]) / denom_trend : 0.0; //--- Set CI
         wt1_trend[i] = ci_trend[i];             //--- Set initial WT1
         wt2_trend[i] = wt1_trend[i];            //--- Set initial WT2
      } else {                                   //--- Handle subsequent bars
         esa_trend[i] = CalcEMA(esa_trend[i-1], src_wt_trend, wt_trend_channel_len); //--- Update ESA
         d_trend[i] = CalcEMA(d_trend[i-1], MathAbs(src_wt_trend - esa_trend[i]), wt_trend_channel_len); //--- Update D
         double denom_trend = 0.015 * d_trend[i]; //--- Compute denominator
         ci_trend[i] = (denom_trend != 0.0) ? (src_wt_trend - esa_trend[i]) / denom_trend : 0.0; //--- Update CI
         wt1_trend[i] = CalcEMA(wt1_trend[i-1], ci_trend[i], wt_trend_average_len); //--- Update WT1
         wt2_trend[i] = 0;                       //--- Reset WT2
         int cnt_ma_trend = 0;                   //--- Init MA count
         for (int k = 0; k < wt_trend_ma_len; k++) { //--- Loop for MA
            if (i - k < 0) break;                //--- Skip invalid index
            wt2_trend[i] += wt1_trend[i - k];    //--- Accumulate WT1
            cnt_ma_trend++;                      //--- Increment count
         }
         if (cnt_ma_trend > 0) wt2_trend[i] /= cnt_ma_trend; //--- Average WT2
      }

      trend_hist[i] = wt1_trend[i] - wt2_trend[i]; //--- Compute trend hist
      trend_is_bull[i] = (wt1_trend[i] > wt2_trend[i]) ? 1 : 0; //--- Set bull trend
      trend_is_bear[i] = (wt1_trend[i] < wt2_trend[i]) ? 1 : 0; //--- Set bear trend

      if (color_candles) {                       //--- Check candle coloring
         openBuf[i] = open[i];                   //--- Set open
         highBuf[i] = high[i];                   //--- Set high
         lowBuf[i] = low[i];                     //--- Set low
         closeBuf[i] = close[i];                 //--- Set close
         candleColorBuf[i] = trend_is_bull[i] == 1 ? 0 : 1; //--- Set color index
      }

      buyArrowBuf[i] = EMPTY_VALUE;              //--- Reset buy arrow
      sellArrowBuf[i] = EMPTY_VALUE;             //--- Reset sell arrow
      if (signal_bull_cross[i] == 1 && (!use_trend_filter || trend_is_bull[i] == 1)) { //--- Check buy condition
         buyArrowBuf[i] = low[i] - _Point * base_offset; //--- Place buy arrow
      }
      if (signal_bear_cross[i] == 1 && (!use_trend_filter || trend_is_bear[i] == 1)) { //--- Check sell condition
         sellArrowBuf[i] = high[i] + _Point * base_offset; //--- Place sell arrow
      }
   }

   return(rates_total);                          //--- Return total rates
}
//+------------------------------------------------------------------+