/* ATR Based Zigzag w EMA */

#property copyright "Converted from Pine Script"
#property link      "forex-station.com"
#property version   "1.00"

#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "Trend Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLime
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3

//--- Inputs
input int ATRLength = 14;                // ATR Length
input double ATRMult = 5.0;              // ATR Multiplier
input int LineSmoothLength = 50;         // Line Smoothness (EMA Length)
input color UpTrendColor = clrLime;      // Uptrend Line Color
input color DownTrendColor = clrRed;     // Downtrend Line Color

//--- Buffers
double TrendLineBuffer[];

//--- Global Variables
double LL = 0.0;                        // Lowest Low
double HH = 0.0;                        // Highest High
int trend = 1;                          // Trend direction: 1 = up, -1 = down
double medianPrice[];
double smoothLine[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                          |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set indicator buffer
   SetIndexBuffer(0, TrendLineBuffer);
   SetIndexLabel(0, "Trend Line");
   
   // Initialize arrays
   ArraySetAsSeries(medianPrice, true);
   ArraySetAsSeries(smoothLine, true);
   ArraySetAsSeries(TrendLineBuffer, true);
   
   // Set indicator properties
   IndicatorShortName("ATR Based Zigzag w EMA");
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                               |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   // Ensure arrays are resized
   ArrayResize(medianPrice, rates_total);
   ArrayResize(smoothLine, rates_total);
   
   // Set array as timeseries
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);
   
   // Calculate starting point
   int start = prev_calculated == 0 ? rates_total - 1 : prev_calculated - 1;
   if(start >= rates_total - 1) start = rates_total - 1;
   
   // Initialize variables on first run
   if(prev_calculated == 0)
   {
      LL = low[rates_total-1];
      HH = high[rates_total-1];
      trend = 1;
   }
   
   // Main loop
   for(int i = start; i >= 0; i--)
   {
      // Calculate ATR
      double atr_val = iATR(NULL, 0, ATRLength, i);
      
      // Calculate median price
      medianPrice[i] = (high[i] + low[i]) / 2;
      
      // Calculate EMA of median price
      if(i == rates_total - 1)
         smoothLine[i] = medianPrice[i];
      else
         smoothLine[i] = (medianPrice[i] * (2.0 / (LineSmoothLength + 1))) + (smoothLine[i+1] * (1 - (2.0 / (LineSmoothLength + 1))));
      
      // Core Zigzag logic
      if(trend > 0) // Uptrend: looking for new swing low
      {
         if(high[i] >= HH)
         {
            HH = high[i];
         }
         else if(low[i] < HH - atr_val * ATRMult)
         {
            trend = -1;
            LL = low[i];
         }
      }
      else // Downtrend: looking for new swing high
      {
         if(low[i] <= LL)
         {
            LL = low[i];
         }
         else if(high[i] > LL + atr_val * ATRMult)
         {
            trend = 1;
            HH = high[i];
         }
      }
      
      // Assign smoothed line to buffer with color based on trend
      TrendLineBuffer[i] = smoothLine[i];
      
   }
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up if necessary
}