//+------------------------------------------------------------------+
//|                                             MultiLookbackLines.mq5|
//+------------------------------------------------------------------+
#property copyright "ChatGPT"
#property version   "1.45"
#property strict

//--- inputs
input ENUM_TIMEFRAMES InpTimeframe      = PERIOD_H1;   // Timeframe to look back on
input int            InpLookbackCandles = 10;          // Base number of candles (>=1)
input double         InpMultiplier      = 7.0;         // Max multiplier (integer part used, >=1)

// Optional color inputs
input color          ColorHighLines     = clrRed;
input color          ColorLowLines      = clrBlue;

#define PREFIX_HIGH "MultiHL_High_"
#define PREFIX_LOW  "MultiHL_Low_"

//--- globals
datetime lastBarTime = 0;
double   multiplier = 1.0; // working multiplier variable

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(InpLookbackCandles < 1)
     {
      Print("Error: InpLookbackCandles must be >= 1");
      return(INIT_FAILED);
     }

   multiplier = InpMultiplier;
   if(multiplier < 1.0)
     {
      Print("Warning: InpMultiplier < 1, setting to 1");
      multiplier = 1.0;
     }

   ClearLines();

   // Draw lines immediately once on init
   UpdateLines();

   Print("MultiLookbackLines EA initialized");
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ClearLines();
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   datetime currentBarTime = iTime(_Symbol, _Period, 0);
   if(currentBarTime == lastBarTime)
      return; // no new bar yet
   lastBarTime = currentBarTime;

   UpdateLines();
  }

//+------------------------------------------------------------------+
//| Core function to draw or update all lines                        |
//+------------------------------------------------------------------+
void UpdateLines()
  {
   int maxMult = (int)MathFloor(multiplier);
   if(maxMult < 1)
      maxMult = 1;

   for(int m=1; m<=maxMult; m++)
     {
      int barsToLookBack = InpLookbackCandles * m;

      MqlRates rates[];
      int copied = CopyRates(_Symbol, InpTimeframe, 1, barsToLookBack, rates);

      if(copied <= 0)
        {
         PrintFormat("CopyRates failed for %d bars on timeframe %s", barsToLookBack, EnumToString(InpTimeframe));
         continue;
        }

      double highest = -DBL_MAX;
      double lowest  =  DBL_MAX;

      for(int i=0; i<copied; i++)
        {
         if(rates[i].high > highest)
            highest = rates[i].high;
         if(rates[i].low < lowest)
            lowest = rates[i].low;
        }

      string highLineName = PREFIX_HIGH + IntegerToString(m);
      string lowLineName  = PREFIX_LOW  + IntegerToString(m);

      DrawOrUpdateLine(highLineName, highest, ColorHighLines);
      DrawOrUpdateLine(lowLineName, lowest,  ColorLowLines);

      PrintFormat("Multiplier %d (%d bars): Copied=%d High=%.5f Low=%.5f",
                  m, barsToLookBack, copied, highest, lowest);
     }
  }

//+------------------------------------------------------------------+
//| Draw or update horizontal line                                   |
//+------------------------------------------------------------------+
void DrawOrUpdateLine(string name, double price, color clr)
  {
   if(ObjectFind(0, name) == -1)
     {
      if(!ObjectCreate(0, name, OBJ_HLINE, 0, 0, price))
        {
         Print("Failed to create line: " + name);
         return;
        }
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
      ObjectSetInteger(0, name, OBJPROP_BACK, true);
      ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
     }
   else
     {
      ObjectSetDouble(0, name, OBJPROP_PRICE, price);
     }
  }

//+------------------------------------------------------------------+
//| Clear lines with defined prefixes                                |
//+------------------------------------------------------------------+
void ClearLines()
  {
   int total = ObjectsTotal(0);
   for(int i=total-1; i>=0; i--)
     {
      string name = ObjectName(0, i);
      if(StringFind(name, PREFIX_HIGH) == 0 || StringFind(name, PREFIX_LOW) == 0)
         ObjectDelete(0, name);
     }
  }
//+------------------------------------------------------------------+