//+------------------------------------------------------------------+
//|                                             Daily LinesBoxes.mq4 |
//+------------------------------------------------------------------+

#property indicator_chart_window

#include <hanover --- function header.mqh>

extern int      LookbackDays        = 20;
extern double   StartHours          = 0;
extern double   EndHours            = 23;
extern double   ExtendHours         = 23;
extern string   UniqueID            = "DLB#1";
extern color    BoxColor            = C'0,64,0';
extern color    LineColor           = Green;
extern string   Properties          = "FTH2";
extern string   HorizLineLevels     = "0";
extern string   TextProperties      = "Verdana,9,Silver,4,HL,w: ,T3.5'; '";
extern string   SymbolProperties    = "2,White,108,10";
extern string   DaysOfWeek          = "Mon,Tue,Wed,Thu,Fri";
extern string   DaysOfMonth         = "01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31";
extern string   Visibility          = "M1,M5,M15,M30,H1,H4";
extern string   TimeFrame           = "";
extern bool     CandlesMustExist    = false;
extern double   ClearancePips       = 0;
extern int      RefreshEveryXMins   = 1;
extern bool     SecondaryPipCount   = false;

int tscale;

datetime prev_time;
string   sym, arr[7], HLL[100];
double   pnt;
int      dig;

//+------------------------------------------------------------------+
int init()  {
//+------------------------------------------------------------------+

  if (RefreshEveryXMins > 240)                             RefreshEveryXMins = 240;
  if (RefreshEveryXMins > 60 && RefreshEveryXMins < 240)   RefreshEveryXMins = 60;
  if (RefreshEveryXMins > 30 && RefreshEveryXMins < 60)    RefreshEveryXMins = 30;
  if (RefreshEveryXMins > 15 && RefreshEveryXMins < 30)    RefreshEveryXMins = 15;
  if (RefreshEveryXMins > 5  && RefreshEveryXMins < 15)    RefreshEveryXMins = 5;
  if (RefreshEveryXMins > 1  && RefreshEveryXMins < 5)     RefreshEveryXMins = 1;

  prev_time = -9999;
  del_obj();
  plot_obj();
  return(0);
}

//+------------------------------------------------------------------+
int deinit()  {
//+------------------------------------------------------------------+
  del_obj();
  return(0);
}


//+------------------------------------------------------------------+
int start()  {
//+------------------------------------------------------------------+
  sym = Symbol();
  if (RefreshEveryXMins < 0)
    return(0);
  if (RefreshEveryXMins == 0) {
    del_obj();
    plot_obj();    
  }
  else {
    if(prev_time != iTime(sym,RefreshEveryXMins,0))  {
      del_obj();
      plot_obj();
      prev_time = iTime(sym,RefreshEveryXMins,0);
  } }      
  return(0);
}

//+------------------------------------------------------------------+
void del_obj()  {
//+------------------------------------------------------------------+
  int k=0;
  while (k<ObjectsTotal())   {
    string objname = ObjectName(k);
    if (StringSubstr(objname,0,StringLen(UniqueID)) == UniqueID)  
      ObjectDelete(objname);
    else
      k++;
  }    
  return(0);
}

//+------------------------------------------------------------------+
void plot_obj()  {
//+------------------------------------------------------------------+
  if (TimeFrame == "")
    tscale = Period();
  else  
    tscale = StrToTF(TimeFrame);
  sym = Symbol();
  pnt = MarketInfo(sym,MODE_POINT);
  dig = MarketInfo(sym,MODE_DIGITS);
  if (dig == 3 || dig == 5) {
    pnt *= 10;
  }  

  DaysOfWeek = StringUpper(DaysOfWeek) + ",";
  DaysOfMonth = DaysOfMonth + ",";
  Visibility = StringUpper(Visibility) + ",";
  string test_vis[9] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
  int vis = 0, inc = 1;
  for (int i=0; i<9; i++)  {
    if (StringFind(Visibility,test_vis[i]+",") >= 0)    vis+=inc;
    inc*=2;
  }  

  int levels = StrToStringArray(HorizLineLevels,HLL);

  string prop = StringUpper(Properties); 
  int width = StrToNumber(Properties);  
  int style = STYLE_SOLID;             
  if (StringFind(prop,"-..",0) >= 0)   style = STYLE_DASHDOTDOT;   else
  if (StringFind(prop,"-.",0) >= 0)    style = STYLE_DASHDOT;      else
  if (StringFind(prop,".",0) >= 0)     style = STYLE_DOT;          else
  if (StringFind(prop,"--",0) >= 0)    style = STYLE_DASH;

  datetime tc  = TimeCurrent();
  for (i=0; i<LookbackDays; i++)   {
    int shifted = tc-i*86400;      
    if (shifted < Time[Bars-1])    break;
    if (StringFind(DaysOfWeek,StringUpper(DateToStr(shifted,"w"))+",") < 0)  continue;
    if (StringFind(DaysOfMonth,DateToStr(shifted,"D")+",")             < 0)  continue;
    datetime dt1  = StrToTime(DateToStr(shifted,"Y.M.D")) + 3600 * StartHours;
    datetime dt2  = StrToTime(DateToStr(shifted,"Y.M.D")) + 3600 * EndHours;
    datetime dt3  = StrToTime(DateToStr(shifted,"Y.M.D")) + 3600 * ExtendHours;

    int exist1 = iBarShift(NULL,tscale,dt1,true);
//    if (exist1 >= 0 && Time[exist1] != dt1)   exist1 = -1;
    int exist2 = iBarShift(NULL,tscale,dt2,true);
//    if (exist2 >= 0 && Time[exist2] != dt1)   exist2 = -1;
    int exist3 = iBarShift(NULL,tscale,dt3,true);
//    if (exist3 >= 0 && Time[exist3] != dt1)   exist3 = -1;

    double   hi = 0, lo = 999999; 
    double   hivol = 0, lovol = 999999, vol = 0;
    double   hirng = 0, lorng = 999999, rng = 0;
    double   hivtr = 0, lovtr = 999999, vtr = 0;
    double   hivdr = 0, lovdr = 999999, vdr = 0;
    int      bar1 = iBarShift(NULL,tscale,dt1,false);
    int      bar2 = iBarShift(NULL,tscale,dt2,false);
    if (bar2 == 0)   bar2 = -1;
    for (int j=bar1; j>bar2; j--)  {
      hi = MathMax(hi,iHigh(NULL,tscale,j));
      lo = MathMin(lo,iLow(NULL,tscale,j));
      double range    = iHigh(NULL,tscale,j) - iLow(NULL,tscale,j);
      double vtrtmp   = range * iVolume(NULL,tscale,j);
      double vdrtmp   = DivZero(iVolume(NULL,tscale,j), range);
      if (range > rng)    { rng = range;    hirng = iHigh(NULL,tscale,j);    lorng = iLow(NULL,tscale,j);  }  
      if (vtrtmp > vtr)   { vtr = vtrtmp;   hivtr = iHigh(NULL,tscale,j);    lovtr = iLow(NULL,tscale,j);  }  
      if (vdrtmp > vdr)   { vdr = vdrtmp;   hivdr = iHigh(NULL,tscale,j);    lovdr = iLow(NULL,tscale,j);  }
      if (iVolume(NULL,tscale,j) > vol)  {  vol = iVolume(NULL,tscale,j);    hivol = iHigh(NULL,tscale,j);    lovol = iLow(NULL,tscale,j);  } 
    }
    if (StringFind(prop,"E",0) >= 0)  { hi = hivol;   lo = lovol;  }  else
    if (StringFind(prop,"R",0) >= 0)  { hi = hirng;   lo = lorng;  }  else
    if (StringFind(prop,"M",0) >= 0)  { hi = hivtr;   lo = lovtr;  }  else
    if (StringFind(prop,"D",0) >= 0)  { hi = hivdr;   lo = lovdr;  }  
    hi += ClearancePips * pnt;  
    lo -= ClearancePips * pnt;

    if (StringFind(prop,"<",0) >= 0)     hi    = iOpen(NULL,tscale,bar1);
    if (StringFind(prop,">",0) >= 0)     lo    = iOpen(NULL,tscale,bar1);
    
    // Plot box.......
    if (StringFind(prop,"F",0) >= 0  ||  StringFind(prop,"B",0) >= 0  ||  StringFind(prop,"T",0) >= 0)  {
      string objname = UniqueID+"-"+i+"-r";
      if (StringFind(prop,"T",0) >= 0)  {
        datetime dt4 = dt2;
        int exist4 = exist2;
      }  else  {
        dt4 = dt3;
        exist4 = exist3;
      }  
      if (!CandlesMustExist  ||  (exist1 >= 0 && exist4 >= 0))   {
        ObjectCreate(objname,OBJ_RECTANGLE,0,dt1,hi,dt4,lo);
        ObjectSet(objname,OBJPROP_COLOR,BoxColor);            
        ObjectSet(objname,OBJPROP_BACK,false);
        ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);               
        if (StringFind(prop,"F",0) >= 0)    ObjectSet(objname,OBJPROP_BACK,true);
        if (StringFind(prop,"P",0) >= 0)    ObjectSetText(objname,DoubleToStr((hi-lo)/pnt,0));
    } }  

    // Plot horizontal lines..........
    if (StringFind(prop,"H",0) >= 0)  {
      if (!CandlesMustExist  ||  (exist1 >= 0 && exist3 >= 0))   {
        objname = UniqueID+"-"+i+"-hi";
        ObjectCreate(objname,OBJ_TREND,0,dt1,hi,dt3,hi); 
        ObjectSet(objname,OBJPROP_RAY,0);
        if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true); 
        ObjectSet(objname,OBJPROP_COLOR,LineColor);
        ObjectSet(objname,OBJPROP_WIDTH,width);
        ObjectSet(objname,OBJPROP_STYLE,style);
        ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
        objname = UniqueID+"-"+i+"-lo";
        ObjectCreate(objname,OBJ_TREND,0,dt1,lo,dt3,lo); 
        ObjectSet(objname,OBJPROP_RAY,0);
        if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true);  
        ObjectSet(objname,OBJPROP_COLOR,LineColor);
        ObjectSet(objname,OBJPROP_WIDTH,width);
        ObjectSet(objname,OBJPROP_STYLE,style);
        ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
    } } 
    
    if (StringFind(prop,"C",0) >= 0)  {
      if (!CandlesMustExist  ||  (exist1 >= 0 && exist3 >= 0))   {
        for (j=0; j<100; j++)  {
          if (HLL[j] == "")   break;
          objname = UniqueID+"-"+i+"-"+j+"-cl";
          double price = iClose(NULL,tscale,bar1);
          ObjectCreate(objname,OBJ_TREND,0,dt1,price+StrToNumber(HLL[j])*pnt,dt3,price+StrToNumber(HLL[j])*pnt); 
          ObjectSet(objname,OBJPROP_RAY,false);
          if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true); 
          ObjectSet(objname,OBJPROP_COLOR,LineColor);
          ObjectSet(objname,OBJPROP_WIDTH,width);
          ObjectSet(objname,OBJPROP_STYLE,style);
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
    } } }

    if (StringFind(prop,"O",0) >= 0)  {
      if (!CandlesMustExist  ||  (exist1 >= 0 && exist3 >= 0))   {
        for (j=0; j<100; j++)  {
          if (HLL[j] == "")   break;
          objname = UniqueID+"-"+i+"-"+j+"-op";
          price = iOpen(NULL,tscale,bar1);
          ObjectCreate(objname,OBJ_TREND,0,dt1,price+StrToNumber(HLL[j])*pnt,dt3,price+StrToNumber(HLL[j])*pnt); 
          ObjectSet(objname,OBJPROP_RAY,false);
          if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true); 
          ObjectSet(objname,OBJPROP_COLOR,LineColor);
          ObjectSet(objname,OBJPROP_WIDTH,width);
          ObjectSet(objname,OBJPROP_STYLE,style);
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
    } } }

    if (StringFind(prop,"A",0) >= 0)  {
      if (!CandlesMustExist  ||  (exist1 >= 0 && exist3 >= 0))   {
        for (j=0; j<100; j++)  {
          if (HLL[j] == "")   break;
          objname = UniqueID+"-"+i+"-"+j+"-op";
          price = (iHigh(NULL,tscale,bar1)+iLow(NULL,tscale,bar1))/2;
          ObjectCreate(objname,OBJ_TREND,0,dt1,price+StrToNumber(HLL[j])*pnt,dt3,price+StrToNumber(HLL[j])*pnt); 
          ObjectSet(objname,OBJPROP_RAY,false);
          if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true); 
          ObjectSet(objname,OBJPROP_COLOR,LineColor);
          ObjectSet(objname,OBJPROP_WIDTH,width);
          ObjectSet(objname,OBJPROP_STYLE,style);
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
    } } }

    // Plot vertical lines.......
    if (StringFind(prop,"V",0) >= 0)  { 
      if (!CandlesMustExist  ||  exist1 >= 0)   {
        objname = UniqueID+"-"+i+"-va";
        ObjectCreate(objname,OBJ_VLINE,0,dt1,0);
        ObjectSet(objname,OBJPROP_COLOR,LineColor);
        ObjectSet(objname,OBJPROP_WIDTH,width);
        ObjectSet(objname,OBJPROP_STYLE,style);
        ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
        if (StringFind(prop,"^",0) >= 0)    ObjectSet(objname,OBJPROP_BACK,true);
      }  
      if (StringFind(prop,"VV",0) >= 0)  {
        if (!CandlesMustExist  ||  exist3 >= 0)   {
          objname = UniqueID+"-"+i+"-vb";
          ObjectCreate(objname,OBJ_VLINE,0,dt3,0); 
          ObjectSet(objname,OBJPROP_COLOR,LineColor);
          ObjectSet(objname,OBJPROP_WIDTH,width);
          ObjectSet(objname,OBJPROP_STYLE,style);
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
          if (StringFind(prop,"^",0) >= 0)    ObjectSet(objname,OBJPROP_BACK,true);
    } } }
    // Display box height......
    if (TextProperties > "")    {
      StrToStringArray(TextProperties,arr);
      double prc = StrToNumber(arr[3]);
      prc = (hi+(prc+5)*pnt)*(prc>=0) + (lo+prc*pnt)*(prc<0);
      objname = UniqueID+"-"+i+"-t";
      string objtext = "";
      if (arr[5] > "") 
        objtext = objtext + DateToStr(dt1,arr[5]) + " ";
      if (StringFind(StringUpper(arr[4]),"P") >= 0)     objtext = objtext + NumberToStr((hi-lo)/pnt,arr[6]) + " ";
      if (StringFind(StringUpper(arr[4]),"H") >= 0)     objtext = objtext + NumberToStr(hi,"'High='"+arr[6]) + " ";
      if (StringFind(StringUpper(arr[4]),"L") >= 0)     objtext = objtext + NumberToStr(lo,"'Low='"+arr[6]) + " ";
//      objtext = StringRepeat(" ",StringLen(objtext)/2) + objtext;
      ObjectCreate(objname,OBJ_TEXT,0,dt1,prc);
      ObjectSetText(objname,objtext,StrToInteger(arr[1]),arr[0],StrToColor(arr[2])); 
      ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);               
    }
    // Display Wingdings symbol......
    if (StringFind(prop,"W",0) >= 0 && SymbolProperties > "")  {
      if (!CandlesMustExist  ||  exist1 >= 0)   {
        int bar     = iBarShift(NULL,0,dt1,true); 
        double high = iHigh(NULL,0,bar); 
        double low  = iLow(NULL,0,bar); 
        StrToStringArray(SymbolProperties,arr);
        prc = StrToNumber(arr[3]);
        prc = (high+(5+prc)*pnt)*(prc>=0) + (low+prc*pnt)*(prc<0);
        objname = UniqueID+"-"+i+"-wa";
        ObjectCreate(objname,OBJ_ARROW,0,dt1,prc); 
        ObjectSet(objname,OBJPROP_ARROWCODE,StrToInteger(arr[2]));
        ObjectSet(objname,OBJPROP_COLOR,StrToColor(arr[1]));
        ObjectSet(objname,OBJPROP_WIDTH,StrToInteger(arr[0]));
        ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
      }
      if (StringFind(prop,"WW",0) >= 0 && SymbolProperties > "")  { 
        if (!CandlesMustExist  ||  exist3 >= 0)   {
          bar  = iBarShift(NULL,0,dt3,true); 
          high = iHigh(NULL,0,bar); 
          low  = iLow(NULL,0,bar); 
          prc  = StrToNumber(arr[3]);
          prc  = (high+(5+prc)*pnt)*(prc>=0) + (low+prc*pnt)*(prc<0);
          objname = UniqueID+"-"+i+"-wb";
          ObjectCreate(objname,OBJ_ARROW,0,dt3,prc); 
          ObjectSet(objname,OBJPROP_ARROWCODE,StrToInteger(arr[2]));
          ObjectSet(objname,OBJPROP_COLOR,StrToColor(arr[1]));
          ObjectSet(objname,OBJPROP_WIDTH,StrToInteger(arr[0]));
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
    } } }
    if (SecondaryPipCount)   {
      double   sec_hi = 0, sec_lo = 999999; 
      int      sbar2 = iBarShift(NULL,tscale,dt2,false);
      int      sbar3 = iBarShift(NULL,tscale,dt3,false);
      if (sbar3 == 0)   sbar3 = -1;
      for (j=sbar2; j>sbar3; j--)  {
        sec_hi = MathMax(sec_hi,iHigh(NULL,tscale,j));
        sec_lo = MathMin(sec_lo,iLow(NULL,tscale,j));
      }
      if (!CandlesMustExist  ||  (exist1 >= 0 && exist3 >= 0))   {
        objname = UniqueID+"-sec-"+i+"-hi";
        string name_hi = objname;
        if (sec_hi > hi)  {
          ObjectCreate(objname,OBJ_TREND,0,dt2,sec_hi,dt3,sec_hi); 
          ObjectSet(objname,OBJPROP_RAY,false);
          if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true); 
          ObjectSet(objname,OBJPROP_COLOR,LineColor);
          ObjectSet(objname,OBJPROP_WIDTH,width);
          ObjectSet(objname,OBJPROP_STYLE,style);
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
        }  
        objname = UniqueID+"-sec-"+i+"-lo";
        string name_lo = objname;
        if (sec_lo < lo)  {
          ObjectCreate(objname,OBJ_TREND,0,dt2,sec_lo,dt3,sec_lo); 
          ObjectSet(objname,OBJPROP_RAY,false);
          if (StringFind(prop,"X",0) >= 0)    ObjectSet(objname,OBJPROP_RAY,true);  
          ObjectSet(objname,OBJPROP_COLOR,LineColor);
          ObjectSet(objname,OBJPROP_WIDTH,width);
          ObjectSet(objname,OBJPROP_STYLE,style);
          ObjectSet(objname,OBJPROP_TIMEFRAMES,vis);
      } }
      if (TextProperties > "")    {
        if (sec_hi > hi)  {
          StrToStringArray(TextProperties,arr);
          prc = sec_hi + (5 + StrToNumber(arr[3])) * pnt;
          objname = UniqueID+"-sec-"+i+"-hi-t";
          ObjectCreate(objname,OBJ_TEXT,0,dt2,prc);
          ObjectSetText(objname,NumberToStr(MathMax(sec_hi-hi,0)/pnt,arr[4]),StrToInteger(arr[1]),arr[0],StrToColor(arr[2])); 
          ObjectSet(name_hi,OBJPROP_COLOR,StrToColor(arr[2]));
        }
        if (sec_lo < lo)  {
          StrToStringArray(TextProperties,arr);
          prc = sec_lo - StrToNumber(arr[3]) * pnt;
          objname = UniqueID+"-sec-"+i+"-lo-t";
          ObjectCreate(objname,OBJ_TEXT,0,dt2,prc);
          ObjectSetText(objname,NumberToStr(MathMax(lo-sec_lo,0)/pnt,arr[4]),StrToInteger(arr[1]),arr[0],StrToColor(arr[2])); 
          ObjectSet(name_lo,OBJPROP_COLOR,StrToColor(arr[2]));
    } } }
  }
  return(0);
}

#include <hanover --- extensible functions.mqh>