//+------------------------------------------------------------------+
//|                                                   i-Sessions.mq4 |
//|                                           Ким Игорь В. aka KimIV |
//|                                              http://www.kimiv.ru |
//|                        16.11.2005  Indicator of trading sessions |
//+------------------------------------------------------------------+
#property copyright "Kim Igor V. aka KimIV   ©   http://www.kimiv.ru"
#property link      "https://www.forexfactory.com/forum/69-platform-tech"  
#property version "3.27"  //from "2.66"  //from "2.88"
#property indicator_chart_window
#property strict    //Fx.art color = C'161,161,161';
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//------- External parameters of the indicator  ----------------------

extern int              NumberOfDays     = 50;                   // Number of days

extern string           iSessions        = "+++++++++++++++++++++++++++++++++++";
extern string           SY_Begin         = "00:00";              // Sydney - Open
extern string           SY_End           = "09:00";              // Sydney - Close
extern color            SY_Color         = C'252,218,224';       // Sydney - Color
extern color            SYBox_Color      = clrBlack;             // Sydney - Border Color

extern string           TO_Begin         = "02:00";              // Tokyo - Open
extern string           TO_End           = "11:00";              // Tokyo - Close
extern color            TO_Color         = C'255,217,170';       // Tokyo - Color
extern color            TOBox_Color      = clrBlack;             // Tokyo - Border Color

extern string           FR_Begin         = "09:00";              // Frankfurt - Open
extern string           FR_End           = "18:00";              // Frankfurt - Close
extern color            FR_Color         = C'193,215,232';       // Frankfurt - Color
extern color            FRBox_Color      = clrBlack;             // Frankfurt - Border Color

extern string           LO_Begin         = "10:00";              // London - Open
extern string           LO_End           = "19:00";              // London - Close
extern color            LO_Color         = C'170,234,255';       // London - Color
extern color            LOBox_Color      = clrBlack;             // London - Border Color

extern string           NY_Begin         = "15:00";              // NewYork - Open
extern string           NY_End           = "24:59";              // NewYork - Close
extern color            NY_Color         = C'221,255,170';       // NewYork - Color
extern color            NYBox_Color      = clrBlack;             // NewYork - Border Color

extern bool             Box_Fill         = true;                 // Box - Fill
extern ENUM_LINE_STYLE  Box_Style        = STYLE_DOT;            // Border - Style
extern int              Box_Width        =  0;                   // Border - Width

extern string           KillZones        = "+++++++++++++++++++++++++++++++++++";
extern string           SYkillBegin      = "19:00";              // Sydney + Open
extern string           SYkillEnd        = "21:00";              // Sydney + Close
extern color            SYkillColor      = clrMidnightBlue;      // Sydney + Color

extern string           TOkillBegin      = "02:00";              // Tokyo + Open
extern string           TOkillEnd        = "04:00";              // Tokyo + Close
extern color            TOkillColor      = clrMidnightBlue;      // Tokyo + Color

extern string           FRkillBegin      = "08:30";              // Frankfurt + Open
extern string           FRkillEnd        = "09:30";              // Frankfurt + Close
extern color            FRkillColor      = clrMidnightBlue;      // Frankfurt + Color

extern string           LOkillBegin      = "10:00";              // London + Open
extern string           LOkillEnd        = "12:00";              // London + Close
extern color            LOkillColor      = clrMidnightBlue;      // London + Color

extern string           NYkillBegin      = "14:00";              // NewYork + Open
extern string           NYkillEnd        = "16:00";              // NewYork + Close
extern color            NYkillColor      = clrMidnightBlue;      // NewYork + Color

extern string           Buttons          = "+++++++++++++++++++++++++++++++++++";
extern color            buttColor        = clrLightCyan;         // Text color
extern int              buttSize         = 10;                   // Text width
extern color            backColor        = C'205,0,205';         // Back color                   
extern int              axisX            = 0;                    // Axis X
extern int              axisY            = 525;                  // Axis Y

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string PREF0="iSessions["+(string)NumberOfDays+"]", si;
string PREF1="iKillZone["+(string)NumberOfDays+"]";
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void init() 
{
   for (int i=0; i<NumberOfDays; i++) 
    {  
     si = (string)i;
     
     if (Box_Fill) {
       if (SY_Color!=clrNONE) CreateObjects(PREF0+"SY"+si,  SY_Color, Box_Fill);
       if (TO_Color!=clrNONE) CreateObjects(PREF0+"TO"+si,  TO_Color, Box_Fill);
       if (FR_Color!=clrNONE) CreateObjects(PREF0+"FR"+si,  FR_Color, Box_Fill);     
       if (LO_Color!=clrNONE) CreateObjects(PREF0+"LO"+si,  LO_Color, Box_Fill);     
       if (NY_Color!=clrNONE) CreateObjects(PREF0+"NY"+si,  NY_Color, Box_Fill); }
 
     if (SYBox_Color!=clrNONE) CreateObjects(PREF0+"SYBox"+si, SYBox_Color);   
     if (TOBox_Color!=clrNONE) CreateObjects(PREF0+"TOBox"+si, TOBox_Color);   
     if (FRBox_Color!=clrNONE) CreateObjects(PREF0+"FRBox"+si, FRBox_Color);  
     if (LOBox_Color!=clrNONE) CreateObjects(PREF0+"LOBox"+si, LOBox_Color);  
     if (NYBox_Color!=clrNONE) CreateObjects(PREF0+"NYBox"+si, NYBox_Color);  
     
     if (SYkillColor!=clrNONE) CreateObjects(PREF1+"SY"+si,  SYkillColor, true);
     if (TOkillColor!=clrNONE) CreateObjects(PREF1+"TO"+si,  TOkillColor, true);
     if (FRkillColor!=clrNONE) CreateObjects(PREF1+"FR"+si,  FRkillColor, true);     
     if (LOkillColor!=clrNONE) CreateObjects(PREF1+"LO"+si,  LOkillColor, true);     
     if (NYkillColor!=clrNONE) CreateObjects(PREF1+"NY"+si,  NYkillColor, true); 
    }
//Comment("");
//------ рисуем Кнопку
   if (ObjectFind(0,PrefBT)!=0)  DrawBUTTON(0,PrefBT,"i+Sessions ON", buttColor,backColor);  
   if (ObjectFind(0,PrefKL)!=0)  DrawBUTTON(1,PrefKL,"Kill Zones ON", backColor,buttColor);         
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
//int deinit() { ALL_OBJ_DELETE();  Comment("");  return (0); }  
void OnDeinit(const int reason)
{ 
   ObjectsDeleteAll(0,PREF0,-1,-1);  /*ALL_OBJ_DELETE();*/  Comment("");
   ObjectsDeleteAll(0,PREF1,-1,-1);  
   //---
   switch(reason)
    {
   //case REASON_PARAMETERS  :
     case REASON_CHARTCHANGE :
     case REASON_RECOMPILE   :
     case REASON_CLOSE       : break;
     default : { ObjectDelete(0,PrefBT); ObjectDelete(0,PrefKL); }
    }
}    
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//********************************************************************
void ALL_OBJ_DELETE()
{
   string name;
   for (int s=ObjectsTotal()-1; s>=0; s--) {
     name=ObjectName(s);
     if (StringSubstr(name,0,StringLen(PREF0))==PREF0) ObjectDelete(name); }
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
void start() 
{  
   //if (getButtonState(PrefBT)=="OFF")  return;  //(0);        
   //---
   if (_Period>240)  { ObjectsDeleteAll(0,PREF0,-1,-1); ObjectsDeleteAll(0,PREF1,-1,-1); return; }
   //---
   datetime dt = TimeCurrent();  //CurTime();
 
   for (int i=0; i<NumberOfDays; i++) 
    {  
     if (getButtonState(PrefBT)=="OFF")  { InitZero(0); continue; }
     
     si = (string)i;
     
     DrawObjects(dt, PREF0+"SY"+si, SY_Begin, SY_End);
     DrawObjects(dt, PREF0+"TO"+si, TO_Begin, TO_End);
     DrawObjects(dt, PREF0+"FR"+si, FR_Begin, FR_End);
     DrawObjects(dt, PREF0+"LO"+si, LO_Begin, LO_End);
     DrawObjects(dt, PREF0+"NY"+si, NY_Begin, NY_End);
     
     DrawObjects(dt, PREF0+"SYBox"+si, SY_Begin, SY_End);
     DrawObjects(dt, PREF0+"TOBox"+si, TO_Begin, TO_End);
     DrawObjects(dt, PREF0+"FRBox"+si, FR_Begin, FR_End);
     DrawObjects(dt, PREF0+"LOBox"+si, LO_Begin, LO_End);
     DrawObjects(dt, PREF0+"NYBox"+si, NY_Begin, NY_End);
     
     dt-=24*60*60;
     while (TimeDayOfWeek(dt)<1 || TimeDayOfWeek(dt)>5) dt-=24*60*60;
   }
//---
//---
   datetime dtk = TimeCurrent();  

   for (int i=0; i<NumberOfDays; i++) 
    {  
     if (getButtonState(PrefKL)=="OFF")  { InitZero(1); continue; }
     
     si = (string)i;
     
     DrawObjects(dtk, PREF1+"SY"+si, SYkillBegin, SYkillEnd);
     DrawObjects(dtk, PREF1+"TO"+si, TOkillBegin, TOkillEnd);
     DrawObjects(dtk, PREF1+"FR"+si, FRkillBegin, FRkillEnd);
     DrawObjects(dtk, PREF1+"LO"+si, LOkillBegin, LOkillEnd);
     DrawObjects(dtk, PREF1+"NY"+si, NYkillBegin, NYkillEnd);
     
     dtk-=24*60*60;
     while (TimeDayOfWeek(dtk)<1 || TimeDayOfWeek(dtk)>5) dtk-=24*60*60;
   }  
//------  
} //end of void start()...
//+------------------------------------------------------------------+
//| Creating indicator objects                                       |
//| Options:                                                         |
//|   no - object name                                               |
//|   cl - object color                                              |
//+------------------------------------------------------------------+
void CreateObjects(string no, color cl, bool Fill=false) 
{
   string objName = no;  //PREF+no;
   ObjectCreate(objName, OBJ_RECTANGLE,   0, 0,0, 0,0);
   ObjectSet(objName, OBJPROP_COLOR,      cl);
   ObjectSet(objName, OBJPROP_STYLE,      Box_Style);  
   ObjectSet(objName, OBJPROP_WIDTH,      Box_Width);  
   ObjectSet(objName, OBJPROP_BACK,       Fill);
   ObjectSet(objName, OBJPROP_FILL,       Fill);  
   ObjectSet(objName, OBJPROP_SELECTABLE, false);
   ObjectSet(objName, OBJPROP_HIDDEN,     false);
}
//+------------------------------------------------------------------+
//| Drawing objects on the chart                                     |
//| Options:                                                         |
//|   dt - trading day date                                          |
//|   no - object name                                               |
//|   tb - session start time                                        |
//|   te - session end time                                          |
//+------------------------------------------------------------------+
void DrawObjects(datetime dt, string no, string tb, string te) 
{
   if (Time[0]<StrToTime(TimeToStr(dt,TIME_DATE)+" "+tb))  return;
  
   datetime t1, t2;
   double   p1, p2;
   int      b1, b2;
 
   t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
   t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
   b1=iBarShift(NULL, 0, t1);
   b2=iBarShift(NULL, 0, t2);
   p1=High[Highest(NULL, 0, MODE_HIGH, b1-b2, b2)];
   p2=Low [Lowest (NULL, 0, MODE_LOW , b1-b2, b2)];
   //---
   string objName = no;  //PREF+no;
   ObjectSet(objName, OBJPROP_TIME1 , t1);
   ObjectSet(objName, OBJPROP_PRICE1, p1);
   ObjectSet(objName, OBJPROP_TIME2 , t2);
   ObjectSet(objName, OBJPROP_PRICE2, p2);
}
//********************************************************************
//***             Custom indicator ChartEvent function             ***
//********************************************************************
bool tickCount=false;   string prevState[2], newState[2];  
string PrefBT = "i"+PREF0+"Butt",  PrefKL = "i"+PREF1+"Butt";   //sTFR+
//------
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)       
{  int NB = sparam==PrefBT ? 0 : 1;
   if (id==CHARTEVENT_OBJECT_CLICK && ObjectGet(sparam,OBJPROP_TYPE)==OBJ_BUTTON)            
    {
     newState[NB] = getButtonState(sparam);   tickCount=true;  
     //---
     if (newState[NB]!=prevState[NB])
     if (newState[NB]=="OFF")  { 
       if (NB<1) InitZero(0);   else InitZero(1);
       prevState[NB] = newState[NB]; }  
     else { 
       if (tickCount) { init();  start();  tickCount=false; }
       prevState[NB] = newState[NB]; }
     //---
     if (NB<1) ObjectSetString(0,PrefBT,OBJPROP_TEXT,"i+Sessions "+newState[NB]);
     else      ObjectSetString(0,PrefKL,OBJPROP_TEXT,"Kill Zones "+newState[NB]);
    }
   //---
   ChartRedraw();
   //---
   //if (newState!="OFF" && id==CHARTEVENT_CHART_CHANGE)  { ChartSetInteger(0,CHART_FOREGROUND,0,false);  DrawHistoLine(); }   ChartRedraw();
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool DrawBUTTON(int NB, string Name, string Text, color txtClr=clrWhite, color bckClr=clrBlack)                
{ 
   if (buttColor==clrNONE || buttSize<5)  return(false);
   //---
   string objName = Name; //PREF0+  //+(string)Time[i];  //+TimeToStr(Time[i],TIME_MINUTES)+"_"+DoubleToStr(Close[i],DGTS);
   //--- пред-удаление обектов   
   ObjectDelete(0,objName);   
   //--- создадим кнопку 
   if (!ObjectCreate(0,objName,OBJ_BUTTON, 0, 0, 0)) return(false);
   //--- установим координаты кнопки 
   double YY = NB<1 ? 5+axisY : (5+axisY)+buttSize*2.25;
   ObjectSetInteger(0,objName,OBJPROP_XDISTANCE, 5+axisX);          // координата по оси X 
   ObjectSetInteger(0,objName,OBJPROP_YDISTANCE, (int)YY);          // координата по оси Y 
   ObjectSetInteger(0,objName,OBJPROP_XSIZE, buttSize*11);          // ширина кнопки   //133
   ObjectSetInteger(0,objName,OBJPROP_YSIZE, buttSize*2);           // высота кнопки    //33
   ObjectSetInteger(0,objName,OBJPROP_CORNER, CORNER_LEFT_UPPER);   // угол графика для привязки кнопки
   ObjectSetString (0,objName,OBJPROP_TEXT, Text);                  // текст 
   ObjectSetString (0,objName,OBJPROP_FONT, "Arial Black");         // шрифт 
   ObjectSetInteger(0,objName,OBJPROP_FONTSIZE, buttSize);          // размер шрифта 
   ObjectSetInteger(0,objName,OBJPROP_COLOR, txtClr);               // цвет текста 
   ObjectSetInteger(0,objName,OBJPROP_BGCOLOR, bckClr);             // цвет фона    //C'236,233,216'
   ObjectSetInteger(0,objName,OBJPROP_BORDER_COLOR, clrNONE);       // цвет границы 
   ObjectSetInteger(0,objName,OBJPROP_BACK, false);                 // на заднем плане 
   ObjectSetInteger(0,objName,OBJPROP_SELECTABLE, false);           // кнопку можно выделить
   ObjectSetInteger(0,objName,OBJPROP_SELECTED, false);             // выделить для перемещений 
   ObjectSetInteger(0,objName,OBJPROP_HIDDEN, false);               // скрыт в списке объектов 
   ObjectSetInteger(0,objName,OBJPROP_ZORDER, 0);                   // приоритет на нажатие мышью 
   ObjectSetInteger(0,objName,OBJPROP_STATE, true);                 // кнопка нажата/отжата 
//--- успешное выполнение 
return(true); 
} 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string getButtonState(string Name)
{
   bool curState = ObjectGetInteger(0,Name,OBJPROP_STATE);
   if (curState)   return("ON");
   else            return("OFF");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void InitZero(int NB)
{
   //ArrayInitialize(wkTrenUP,0.0);   ArrayInitialize(wkTrenDN,0.0);
   //ArrayInitialize(bdTrenUP,0.0);   ArrayInitialize(bdTrenDN,0.0);
   //---
   //for (int i=0; i<Bars-1; i++)  ObjectDelete(0,PREF0+"day"+(string)i);   
   if (NB<1) ObjectsDeleteAll(0,PREF0,-1,-1);  
   else      ObjectsDeleteAll(0,PREF1,-1,-1);  
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+