//+------------------------------------------------------------------+
//|            ATR Stop with Fibo Curve.mq4                          |
//|  Adaptive ATR trailing stop incorporating a Fibonacci retracement|
//|  level, with additional dotted channel lines that move with the  |
//|  ATR stop (non-repainting).                                      |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 9
// Colors for the lines:
#property indicator_color1 clrWhite       // ATR Stop line color
#property indicator_color2 clrMaroon         // ATR High Channel 1 color
#property indicator_color3 clrDarkGreen        // ATR Low Channel 1 color
#property indicator_color4 clrDarkRed   // ATR High Channel 2 color
#property indicator_color5 clrForestGreen // ATR Low Channel 2 color
#property indicator_color6 clrOrangeRed     // ATR High Channel 3 color
#property indicator_color7 clrGreenYellow // ATR Low Channel 3 color
#property indicator_color8 clrRed      // ATR High Channel 4 color
#property indicator_color9 clrLime   // ATR Low Channel 4 color

// External parameters
extern int    ATRPeriod             = 14;      // Period for short-term ATR
extern double ATRMultiplier         = 1;       // Base multiplier for ATR stop
extern int    ATRLongPeriod         = 13;      // Longer ATR period for dynamic adjustment
extern int    FiboLookBack          = 50;      // Look-back bars for swing high/low calculation
extern double FiboRatio             = 0.618;   // Fibonacci ratio for retracement level
extern double ATRChannelMultiplier  = 1.236;     // Multiplier for channel lines offset from the ATR stop

// Indicator buffers
double ATRStopBuffer[];
double HighLineBuffer[];  // ATR High Channel 1
double LowLineBuffer[];   // ATR Low Channel 1

double HighLineBuffer2[]; // ATR High Channel 2 (additional)
double LowLineBuffer2[];  // ATR Low Channel 2 (additional)
double HighLineBuffer3[]; // ATR High Channel 3 (additional)
double LowLineBuffer3[];  // ATR Low Channel 3 (additional)
double HighLineBuffer4[]; // ATR High Channel 4 (additional)
double LowLineBuffer4[];  // ATR Low Channel 4 (additional)

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(9);
   // ATR Stop buffer
   SetIndexBuffer(0, ATRStopBuffer);
   SetIndexStyle(0, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(0, "ATR Stop with Fibo");
   
   // High Channel 1
   SetIndexBuffer(1, HighLineBuffer);
   SetIndexStyle(1, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(1, "ATR High Channel 1");
   
   // Low Channel 1
   SetIndexBuffer(2, LowLineBuffer);
   SetIndexStyle(2, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(2, "ATR Low Channel 1");
   
   // Additional High/Low Channel lines
   SetIndexBuffer(3, HighLineBuffer2);
   SetIndexStyle(3, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(3, "ATR High Channel 2");
   
   SetIndexBuffer(4, LowLineBuffer2);
   SetIndexStyle(4, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(4, "ATR Low Channel 2");
   
   SetIndexBuffer(5, HighLineBuffer3);
   SetIndexStyle(5, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(5, "ATR High Channel 3");
   
   SetIndexBuffer(6, LowLineBuffer3);
   SetIndexStyle(6, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(6, "ATR Low Channel 3");
   
   SetIndexBuffer(7, HighLineBuffer4);
   SetIndexStyle(7, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(7, "ATR High Channel 4");
   
   SetIndexBuffer(8, LowLineBuffer4);
   SetIndexStyle(8, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(8, "ATR Low Channel 4");

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars = IndicatorCounted();
   if(counted_bars < 0)
      return(-1);
   // Avoid recalculating the current forming bar:
   if(counted_bars > 0)
      counted_bars--;

   int limit = Bars - counted_bars;

   // Local arrays for the recursive ATR stop value and trend direction.
   double atrStopArray[];
   ArrayResize(atrStopArray, Bars);
   int trendArray[];
   ArrayResize(trendArray, Bars);

   //--- Initialize the oldest bar (index = Bars-1)
   int oldest = Bars - 1;
   double atrShort = iATR(NULL, 0, ATRPeriod, oldest);
   double atrLong  = iATR(NULL, 0, ATRLongPeriod, oldest);
   double dynamicMultiplier = ATRMultiplier;
   if(atrLong > 0)
      dynamicMultiplier *= (atrShort / atrLong);

   // Determine the swing high/low over the look-back period for Fibonacci.
   int countRange = FiboLookBack;
   if(oldest + countRange > Bars)
      countRange = Bars - oldest;
   int idxHighest = iHighest(NULL, 0, MODE_HIGH, countRange, oldest);
   int idxLowest  = iLowest(NULL, 0, MODE_LOW, countRange, oldest);
   double highestHigh = High[idxHighest];
   double lowestLow   = Low[idxLowest];

   // Assume an initial uptrend.
   trendArray[oldest] = 1;
   // ATR-based candidate for an uptrend:
   double candATR = Low[oldest] - dynamicMultiplier * atrShort;
   // Fibonacci candidate level (retracement above recent swing low):
   double fiboLevel = lowestLow + (highestHigh - lowestLow) * FiboRatio;
   // Weighted average (50/50) of the two candidates:
   double candidateStop = candATR + (fiboLevel - candATR) * 0.5;
   atrStopArray[oldest] = candidateStop;
   ATRStopBuffer[oldest] = atrStopArray[oldest];

   // Calculate the channel lines relative to the ATR stop line at the oldest bar.
   HighLineBuffer[oldest]  = atrStopArray[oldest] + 1 * ATRChannelMultiplier * atrShort;
   LowLineBuffer[oldest]   = atrStopArray[oldest] - 1 * ATRChannelMultiplier * atrShort;
   HighLineBuffer2[oldest] = atrStopArray[oldest] + 2 * ATRChannelMultiplier * atrShort;
   LowLineBuffer2[oldest]  = atrStopArray[oldest] - 2 * ATRChannelMultiplier * atrShort;
   HighLineBuffer3[oldest] = atrStopArray[oldest] + 3 * ATRChannelMultiplier * atrShort;
   LowLineBuffer3[oldest]  = atrStopArray[oldest] - 3 * ATRChannelMultiplier * atrShort;
   HighLineBuffer4[oldest] = atrStopArray[oldest] + 4 * ATRChannelMultiplier * atrShort;
   LowLineBuffer4[oldest]  = atrStopArray[oldest] - 4 * ATRChannelMultiplier * atrShort;

   //--- Loop from the next bar (Bars-2) up to the current bar (index 0)
   for(int i = oldest - 1; i >= 0; i--)
     {
      atrShort = iATR(NULL, 0, ATRPeriod, i);
      atrLong  = iATR(NULL, 0, ATRLongPeriod, i);
      dynamicMultiplier = ATRMultiplier;
      if(atrLong > 0)
         dynamicMultiplier *= (atrShort / atrLong);

      // Determine the trend based on the previous bar's close vs. its stop.
      if(Close[i+1] > atrStopArray[i+1])
         trendArray[i] = 1;
      else if(Close[i+1] < atrStopArray[i+1])
         trendArray[i] = -1;
      else
         trendArray[i] = trendArray[i+1];

      // Recalculate Fibonacci levels over the look-back period.
      countRange = FiboLookBack;
      if(i + countRange > Bars)
         countRange = Bars - i;
      idxHighest = iHighest(NULL, 0, MODE_HIGH, countRange, i);
      idxLowest  = iLowest(NULL, 0, MODE_LOW, countRange, i);
      highestHigh = High[idxHighest];
      lowestLow   = Low[idxLowest];

      if(trendArray[i] == 1)  // Uptrend
        {
         candATR = Low[i] - dynamicMultiplier * atrShort;
         fiboLevel = lowestLow + (highestHigh - lowestLow) * FiboRatio;
         candidateStop = candATR + (fiboLevel - candATR) * 0.5;
         // In an uptrend, ensure the stop never moves lower.
         atrStopArray[i] = MathMax(candidateStop, atrStopArray[i+1]);
        }
      else  // Downtrend
        {
         candATR = High[i] + dynamicMultiplier * atrShort;
         fiboLevel = highestHigh - (highestHigh - lowestLow) * FiboRatio;
         candidateStop = candATR + (fiboLevel - candATR) * 0.5;
         // In a downtrend, ensure the stop never moves higher.
         atrStopArray[i] = MathMin(candidateStop, atrStopArray[i+1]);
        }

      ATRStopBuffer[i] = atrStopArray[i];

      // Calculate the channel lines relative to the ATR stop line.
      HighLineBuffer[i]  = atrStopArray[i] + 1 * ATRChannelMultiplier * atrShort;
      LowLineBuffer[i]   = atrStopArray[i] - 1 * ATRChannelMultiplier * atrShort;
      HighLineBuffer2[i] = atrStopArray[i] + 2 * ATRChannelMultiplier * atrShort;
      LowLineBuffer2[i]  = atrStopArray[i] - 2 * ATRChannelMultiplier * atrShort;
      HighLineBuffer3[i] = atrStopArray[i] + 3 * ATRChannelMultiplier * atrShort;
      LowLineBuffer3[i]  = atrStopArray[i] - 3 * ATRChannelMultiplier * atrShort;
      HighLineBuffer4[i] = atrStopArray[i] + 4 * ATRChannelMultiplier * atrShort;
      LowLineBuffer4[i]  = atrStopArray[i] - 4 * ATRChannelMultiplier * atrShort;
     }

   return(0);
  }
//+------------------------------------------------------------------+
