//+------------------------------------------------------------------+
//|                                             DailyHighLowGrid.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

//--- Inputs
input int             NumberOfDays = 40;             // How many days back, including today
input color           HighLineColor = clrGreen;       // Color for High lines
input color           LowLineColor  = clrRed;         // Color for Low lines
input int             LineWidth     = 1;               // Line width
input ENUM_LINE_STYLE LineStyleInp  = STYLE_SOLID;     // Line style

//--- Object name prefixes (used for identification & cleanup)
#define PREFIX      "DHLGrid_"
#define PREFIX_HIGH PREFIX + "High_"
#define PREFIX_LOW  PREFIX + "Low_"

//+------------------------------------------------------------------+
//| Custom indicator initialization function                        |
//+------------------------------------------------------------------+
int OnInit()
  {
   DrawDailyLines();
   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[])
  {
   //--- Redraw / refresh lines each time new data arrives
   DrawDailyLines();
   return(rates_total);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectsDeleteAll(0, PREFIX);
   ChartRedraw(0);
  }

//+------------------------------------------------------------------+
//| Builds/updates the High & Low lines for each of the last N days |
//+------------------------------------------------------------------+
void DrawDailyLines()
  {
   for(int i = 0; i < NumberOfDays; i++)
     {
      datetime dayTime = iTime(_Symbol, PERIOD_D1, i);
      if(dayTime == 0)
         continue; // not enough history for this day

      double dayHigh = iHigh(_Symbol, PERIOD_D1, i);
      double dayLow  = iLow(_Symbol, PERIOD_D1, i);

      string stamp     = TimeToString(dayTime, TIME_DATE);
      string highName  = PREFIX_HIGH + stamp;
      string lowName   = PREFIX_LOW  + stamp;

      // Second time-point only matters to satisfy ObjectCreate(); RAY_RIGHT
      // set afterwards is what actually extends the line to time current.
      datetime dayEnd = TimeCurrent();

      //--- Create High line only if it doesn't already exist
      if(ObjectFind(0, highName) < 0)
         ObjectCreate(0, highName, OBJ_TREND, 0, dayTime, dayHigh, dayEnd, dayHigh);

      //--- Create Low line only if it doesn't already exist
      if(ObjectFind(0, lowName) < 0)
         ObjectCreate(0, lowName, OBJ_TREND, 0, dayTime, dayLow, dayEnd, dayLow);

      //--- Set/refresh all other properties independently of creation
      SetLineProperties(highName, HighLineColor, dayTime, dayHigh, dayEnd);
      SetLineProperties(lowName,  LowLineColor,  dayTime, dayLow,  dayEnd);
     }

   ChartRedraw(0);
  }

//+------------------------------------------------------------------+
//| Applies visual/positional properties to a trend line object      |
//+------------------------------------------------------------------+
void SetLineProperties(const string name,
                        const color  lineColor,
                        const datetime dayTime,
                        const double  priceLevel,
                        const datetime dayEnd)
  {
   ObjectSetInteger(0, name, OBJPROP_TIME,   0, dayTime);
   ObjectSetDouble (0, name, OBJPROP_PRICE,  0, priceLevel);
   ObjectSetInteger(0, name, OBJPROP_TIME,   1, dayEnd);
   ObjectSetDouble (0, name, OBJPROP_PRICE,  1, priceLevel);

   ObjectSetInteger(0, name, OBJPROP_COLOR,     lineColor);
   ObjectSetInteger(0, name, OBJPROP_WIDTH,     LineWidth);
   ObjectSetInteger(0, name, OBJPROP_STYLE,     LineStyleInp);
   ObjectSetInteger(0, name, OBJPROP_RAY_LEFT,  false);
   ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, false);   // extend to time current
   ObjectSetInteger(0, name, OBJPROP_BACK,      true);
   ObjectSetInteger(0, name, OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0, name, OBJPROP_SELECTED,  false);
   ObjectSetInteger(0, name, OBJPROP_HIDDEN,    true);
   ObjectSetString (0, name, OBJPROP_TOOLTIP,   TimeToString(dayTime, TIME_DATE));
  }
//+------------------------------------------------------------------+