#property copyright "FX Omoshiro Lab"
#property version   "1.00"
#property description "Shows the previous completed D1 high, low and midpoint"
#property indicator_chart_window
#property indicator_plots 0

input color InpHighColor=clrDodgerBlue;
input color InpLowColor=clrHotPink;
input color InpCenterColor=clrGold;
input int   InpLineWidth=2;

#define PREFIX "MQL104_PREV_DAY_"
datetime g_previous_day_open=0;

bool UpdateLevels()
  {
   MqlRates day[];
   ArraySetAsSeries(day,true);
   ResetLastError();
   const int copied=CopyRates(_Symbol,PERIOD_D1,1,1,day);
   if(copied!=1 || day[0].time<=0 || day[0].high<=0 || day[0].low<=0 || day[0].high<day[0].low)
     {
      Comment("Previous D1 data unavailable");
      PrintFormat("MQL104_WAIT copied=%d error=%d",copied,GetLastError());
      return false;
     }
   if(day[0].time==g_previous_day_open) return true;
   const double center=(day[0].high+day[0].low)/2.0;
   const string names[3]={PREFIX+"HIGH",PREFIX+"LOW",PREFIX+"CENTER"};
   const double values[3]={day[0].high,day[0].low,center};
   const color colors[3]={InpHighColor,InpLowColor,InpCenterColor};
   const string captions[3]={"Previous D1 High","Previous D1 Low","Previous D1 Midpoint"};
   for(int i=0;i<3;i++)
     {
      if(ObjectFind(0,names[i])<0 && !ObjectCreate(0,names[i],OBJ_HLINE,0,0,values[i]))
        {
         PrintFormat("MQL104_FAIL create=%s error=%d",names[i],GetLastError());
         return false;
        }
      ObjectSetDouble(0,names[i],OBJPROP_PRICE,values[i]);
      ObjectSetInteger(0,names[i],OBJPROP_COLOR,colors[i]);
      ObjectSetInteger(0,names[i],OBJPROP_STYLE,i==2 ? STYLE_DASH : STYLE_SOLID);
      ObjectSetInteger(0,names[i],OBJPROP_WIDTH,InpLineWidth);
      ObjectSetInteger(0,names[i],OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,names[i],OBJPROP_HIDDEN,true);
      ObjectSetString(0,names[i],OBJPROP_TEXT,captions[i]);
     }
   Comment("Previous D1 levels  |  ",TimeToString(day[0].time,TIME_DATE),
           "\nHigh ",DoubleToString(day[0].high,_Digits),
           "   Mid ",DoubleToString(center,_Digits),
           "   Low ",DoubleToString(day[0].low,_Digits));
   ChartRedraw(0);
   g_previous_day_open=day[0].time;
   PrintFormat("MQL104_LEVELS date=%s high=%.*f low=%.*f midpoint=%.*f copied=%d",
               TimeToString(day[0].time,TIME_DATE),_Digits,day[0].high,_Digits,day[0].low,_Digits,center,copied);
   return true;
  }

int OnInit()
  {
   IndicatorSetString(INDICATOR_SHORTNAME,"Previous D1 High / Low / Midpoint");
   UpdateLevels();
   EventSetTimer(60);
   return INIT_SUCCEEDED;
  }

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[])
  {
   if(prev_calculated==0) UpdateLevels();
   return rates_total;
  }

void OnTimer() { UpdateLevels(); }

void OnDeinit(const int reason)
  {
   EventKillTimer();
   Comment("");
   ObjectDelete(0,PREFIX+"HIGH");
   ObjectDelete(0,PREFIX+"LOW");
   ObjectDelete(0,PREFIX+"CENTER");
  }
