//+------------------------------------------------------------------+
//|                                          KK_DualMA_Envelope.mq5  |
//|                                                                  |
//|  ATR-based dynamic channel – upper & lower always visible        |
//|  Center Guide EMA drawn continuously                             |
//+------------------------------------------------------------------+
#property copyright "KK"
#property link      ""
#property version   "3.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

#property indicator_label1  "Channel Lower"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

#property indicator_label2  "Channel Upper"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#property indicator_label3  "Guide EMA"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrWhite
#property indicator_style3  STYLE_DOT
#property indicator_width3  1

//--- Input parameters
input string            Settings        = "=== MA Settings ===";
input ENUM_MA_METHOD    MAType          = MODE_EMA;           // MA Type
input int               FastMA_Period   = 10;                 // Fast MA Period
input int               SlowMA_Period   = 21;                 // Slow MA Period
input string            ATRSettings     = "=== ATR Settings ===";
input int               ATR_Period      = 14;                 // ATR Period
input double            ATR_Multiplier  = 1.0;                // ATR Multiplier
input string            Visual          = "=== Visualization ===";
input color             GuideColor      = clrWhite;           // Guide EMA Color
input int               BarsToScan      = 1000;               // Bars To Scan

//--- Indicator buffers
double ChannelLowerBuffer[];
double ChannelUpperBuffer[];
double GuideEMABuffer[];

//--- Indicator handles
int handleFastMA;
int handleSlowMA;
int handleATR;

//--- For detecting timeframe/symbol change
string lastSymbol = "";
ENUM_TIMEFRAMES lastTimeframe = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                          |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, ChannelLowerBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, ChannelUpperBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, GuideEMABuffer, INDICATOR_DATA);
   
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
   
   PlotIndexSetInteger(2, PLOT_LINE_COLOR, GuideColor);
   
   ArraySetAsSeries(ChannelLowerBuffer, true);
   ArraySetAsSeries(ChannelUpperBuffer, true);
   ArraySetAsSeries(GuideEMABuffer, true);
   
   handleFastMA = iMA(_Symbol, PERIOD_CURRENT, FastMA_Period, 0, MAType, PRICE_CLOSE);
   handleSlowMA = iMA(_Symbol, PERIOD_CURRENT, SlowMA_Period, 0, MAType, PRICE_CLOSE);
   handleATR    = iATR(_Symbol, PERIOD_CURRENT, ATR_Period);
   
   if(handleFastMA == INVALID_HANDLE || handleSlowMA == INVALID_HANDLE || handleATR == INVALID_HANDLE)
   {
      Print("KK_DualMA_Envelope: Error creating indicator handles!");
      return(INIT_FAILED);
   }
   
   lastSymbol    = _Symbol;
   lastTimeframe = Period();
   
   IndicatorSetString(INDICATOR_SHORTNAME,
      "KK_DualMA_Envelope (" + IntegerToString(FastMA_Period) + "/" + IntegerToString(SlowMA_Period) + ")");
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Release indicator handles                                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(handleFastMA != INVALID_HANDLE) IndicatorRelease(handleFastMA);
   if(handleSlowMA != INVALID_HANDLE) IndicatorRelease(handleSlowMA);
   if(handleATR    != INVALID_HANDLE) IndicatorRelease(handleATR);
   
   if(reason == REASON_CHARTCHANGE)
   {
      ArrayInitialize(ChannelLowerBuffer, 0);
      ArrayInitialize(ChannelUpperBuffer, 0);
      ArrayInitialize(GuideEMABuffer, 0);
   }
}

//+------------------------------------------------------------------+
//| Recreate handles for new symbol/timeframe                         |
//+------------------------------------------------------------------+
void RecreateHandles()
{
   if(handleFastMA != INVALID_HANDLE) IndicatorRelease(handleFastMA);
   if(handleSlowMA != INVALID_HANDLE) IndicatorRelease(handleSlowMA);
   if(handleATR    != INVALID_HANDLE) IndicatorRelease(handleATR);
   
   handleFastMA = iMA(_Symbol, PERIOD_CURRENT, FastMA_Period, 0, MAType, PRICE_CLOSE);
   handleSlowMA = iMA(_Symbol, PERIOD_CURRENT, SlowMA_Period, 0, MAType, PRICE_CLOSE);
   handleATR    = iATR(_Symbol, PERIOD_CURRENT, ATR_Period);
}

//+------------------------------------------------------------------+
//| 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[])
{
   //--- Check for symbol or timeframe change
   if(lastSymbol != _Symbol || lastTimeframe != Period())
   {
      lastSymbol    = _Symbol;
      lastTimeframe = Period();
      RecreateHandles();
      ArrayInitialize(ChannelLowerBuffer, 0);
      ArrayInitialize(ChannelUpperBuffer, 0);
      ArrayInitialize(GuideEMABuffer, 0);
   }
   
   ArraySetAsSeries(ChannelLowerBuffer, true);
   ArraySetAsSeries(ChannelUpperBuffer, true);
   ArraySetAsSeries(GuideEMABuffer, true);
   ArraySetAsSeries(time, true);
   ArraySetAsSeries(close, true);
   
   int limit;
   
   if(prev_calculated == 0)
   {
      limit = MathMin(rates_total - 1, BarsToScan);
      ArrayInitialize(ChannelLowerBuffer, 0);
      ArrayInitialize(ChannelUpperBuffer, 0);
      ArrayInitialize(GuideEMABuffer, 0);
   }
   else
   {
      limit = rates_total - prev_calculated + 1;
   }
   
   //--- Temp arrays
   double fastMA[], slowMA[], atr[];
   ArraySetAsSeries(fastMA, true);
   ArraySetAsSeries(slowMA, true);
   ArraySetAsSeries(atr, true);
   
   if(CopyBuffer(handleFastMA, 0, 0, limit + 1, fastMA) <= 0) return(0);
   if(CopyBuffer(handleSlowMA, 0, 0, limit + 1, slowMA) <= 0) return(0);
   if(CopyBuffer(handleATR,    0, 0, limit + 1, atr)    <= 0) return(0);
   
   //--- Main calculation loop
   for(int i = limit; i >= 0; i--)
   {
      double fastMAVal = fastMA[i];
      double slowMAVal = slowMA[i];
      double atrVal    = atr[i];
      
      //--- Trend direction
      int trend = 0;
      if(fastMAVal > slowMAVal)      trend =  1;
      else if(fastMAVal < slowMAVal) trend = -1;
      
      //--- Channel: always draw both lines around slowMA
      ChannelLowerBuffer[i] = slowMAVal - atrVal * ATR_Multiplier;
      ChannelUpperBuffer[i] = slowMAVal + atrVal * ATR_Multiplier;
      
      //--- Guide EMA: always drawn
      if(trend == 1)
         GuideEMABuffer[i] = MathMin(fastMAVal, slowMAVal);
      else if(trend == -1)
         GuideEMABuffer[i] = MathMax(fastMAVal, slowMAVal);
      else
         GuideEMABuffer[i] = slowMAVal;
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+
