//+-------------------------------------------------------------------------------------+
//|                                                     iTime III (FutureSeparates).mq4 | // based on:
//|                                                         Copyright © 2011, komposter |	// 1 - TIME II (VBO) by Vadim Baklanov (ispgip@mail.ru)
//|                                                             http://www.komposter.me | // 2 - FutureSeparators by Scriptong (scriptong@mail.ru)
//+-------------------------------------------------------------------------------------+
#property copyright ""
#property link      "sever11"
//v2.0

#property indicator_chart_window
//+-------------------------------------------------------------------------------------+
//|								*** Внешние параметры индиктора ***									 |
//+-------------------------------------------------------------------------------------+
extern string      GeneralSessions="-------Настройки-сессий-------";
extern bool         ShowSessions=true;                     // true - показывать сессии на графике
extern color      OnColor=Lime;                     // Цвет кнопки переключения состояния отрисовки в режиме ВКЛ.
extern color      OffColor=DarkGray;                  // Цвет кнопки переключения состояния отрисовки в режиме ОТКЛ.
extern bool         PlaceUTCPoints=true;                     // Выводить дополнительную информацию по сессиям на график.
extern color      UTCPointColor=Gray;                     // Цвет дополнительной информации.
extern string      TimeSettings      = "----Время----";
extern int         Broker_TimeZone   =+2;                        // Часовой пояс брокера.
extern datetime   Broker_DST_start   = D'01.01.2001 00:00:00';   // Переход на летнее время (Daylight saving time).
extern datetime   Broker_DST_end=D'01.01.2001 00:00:00';   // Переход на летнее время (Daylight saving time).
//+-------------------------------------------------------------------------------------+
extern string      CustomSettings="----Общие----";
extern int         DaysToDisplay      = 10;                        // Количество дней на которых отображаются сессии.
extern int         RectLineStyle      = STYLE_SOLID;               // Стиль линий отрисовки.
extern int         RectLineWidth=1;                        // Толщина линий отрисовки.
//+-------------------------------------------------------------------------------------+
extern string      GeneralDelimeters="-------Настройки-разделителей-------";
extern bool         ShowPrevious      = true;                    //переключатель для отображения истории : TRUE - показать, FALSE - скрыть.
extern datetime   EndDate            = D'2015.01.01 00:00';      // Дата, вплоть до которой идет построение.
extern int         AllOn=0;                        // 1 - включить все разделители, -1 - выключить все разделители
                                                   //	0 - ориентироваться на настройки каждого отдельно
//+-------------------------------------------------------------------------------------+
extern string      MonthlyDelimeter   = "----Месяц----";
extern bool         UseMN1            = true;                     // true - использовать месячный разделитель.
extern color      MonthColor         = Black;                     // Цвет обычной линии.
extern int         MonthWidth         = 1;                        // Толщина обычной линии.
extern int         MonthStyle         = STYLE_DASH;               // Стиль обычной линии.
extern string      Quarter            = "--Кварталы--";
extern color      QuarterColor      = Black;                     // Цвет квартальной линии.
extern int         QuarterWidth      = 2;                        // Толщина квартальной линии.
extern int         QuarterStyle=STYLE_SOLID;               // Стиль квартальной линии.
//+-------------------------------------------------------------------------------------+
extern string      WeeklyDelimeter="----Неделя----";
extern bool         UseW1=true;                     // true - использовать недельный разделитель.
extern color      WeekColor=DodgerBlue;               // Цвет обычной линии.
extern int         WeekWidth=1;                        // Толщина обычной линии.
extern int         WeekStyle= STYLE_DOT;               // Стиль обычной линии.
//+-------------------------------------------------------------------------------------+
extern string      DailyDelimeter="----День----";
extern bool         UseD1=true;                     // true - использовать дневной разделитель.
extern color      BusinessDayColor=Lime;                     // Цвет рабочих дней.
extern color      WeekEndColor=Orange;                  // Цвет выходных дней.
extern int         DayWidth=1;                        // Толщина обычной линии.
extern int         DayStyle= STYLE_DOT;               // Стиль обычной линии.
//+-------------------------------------------------------------------------------------+
extern string      H4Delimeter="----4-Часа----";
extern bool         UseH4=false;                     // true - использовать 4-х часовой разделитель.
extern color      H4Color= LightCoral;               // Цвет обычной линии.
extern int         H4Width=1;                        // Толщина обычной линии.
extern int         H4Style= STYLE_DOT;               // Стиль обычной линии.
//+-------------------------------------------------------------------------------------+
extern string      H1Delimeter="----1-Час----";
extern bool         UseH1=false;                     // true - использовать часовой разделитель.
extern color      H1Color            = White;                     // Цвет обычной линии.
extern int         H1Width            = 1;                        // Толщина обычной линии.
extern int         H1Style=STYLE_DOT;               // Стиль обычной линии.
//+-------------------------------------------------------------------------------------+

string prefix ="FutSep_";
string day[7]={ "ВС","ПН","ВТ","СР","ЧТ","ПТ","СБ" };

bool MondayWeekStart=true;                     // true - начало недели будет показано в понедельник, иначе - воскресенье.
//+-------------------------------------------------------------------------------------+
//--Time of sessions and DST (Daylight saving time) - all in UTC

//--Southern hemisphere.
//--Sydney. EDT (Eastern Daylight Time) UTC offset +10 DST +1 hour. 
int      SydneyTimeZone         = +10;
datetime   SydneyBegins         = D'01.01.2001 23:00:00';
datetime   SydneyEnds=D'01.01.2001 07:00:00';
datetime   SydneyDSTStarts=D'04.10.2009 02:00:00';
datetime   SydneyDSTEnds=D'05.04.2009 03:00:00';
//--Color settings.
color      SydneyColor=DarkSeaGreen;
color      SydneyBackColor=C'12,0,60';
//--ASX Open.
datetime   ASXOpens=D'01.01.2001 00:00:00';
string   ASXOpensText="+ASX";
string   ASXOpensDescr="+Australian SE";
//--ASX Close.
datetime   ASXCloses=D'01.01.2001 06:00:00';
string   ASXClosesText="-ASX";
string   ASXClosesDescr="-Australian SE";
//+-------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------+
//--Northern hemisphere.
//--Tokyo.
int      TokyoTimeZone=+9;
datetime   TokyoBegins=D'01.01.2001 00:00:00'; //+
datetime   TokyoEnds=D'01.01.2001 08:00:00'; //+
                                             //--Color settings.
color      TokyoColor=DeepPink;
color      TokyoBackColor=C'43,0,23';
//--TSE Open.
datetime   TokyoSEOpens=D'01.01.2001 00:00:00';
string   TokyoSEOpensText="+TSE";
string   TokyoSEOpensDescr="+Tokyo SE";
//--TSE Close.
datetime   TokyoSECloses=D'01.01.2001 06:00:00';
string   TokyoSEClosesText="-TSE";
string   TokyoSEClosesDescr="-Tokyo SE";

//+-------------------------------------------------------------------------------------+
//--Hong Kong, Shanghai Standard time zone:	UTC +8 hours No DST in 2009
int      HongKongTimeZone=+8;
datetime   HongKongBegins= D'01.01.2001 01:00:00';
datetime   HongKongEnds=D'01.01.2001 09:00:00';
//--Color Settings.
color      HongKongColor=Red;
color      HongKongBackColor=C'43,0,0';
//--HKEx Open.
datetime   HKExOpens=D'01.01.2001 02:00:00'; // Pre-opening Session 9:30am to 10:00am, Morning Session	begins in 10:00am
string   HKExOpensText="+HKEx";
string   HKExOpensDescr="+Hong Kong HKEx";
//--HKEx Close.
datetime   HKExCloses=D'01.01.2001 08:00:00'; // 4:00pm
string   HKExClosesText="-HKEx";
string   HKExClosesDescr="-Hong Kong HKEx";
//--SSE Open.
datetime   SSEOpens=D'01.01.2001 01:30:00'; // Pre-Market Session: 09:15 - 09:25 Normal Trading Session: 09:30 - 15:00
string   SSEOpensText="+SSE";
string   SSEOpensDescr="+Shanghai SE";
//--SSE Close.
datetime   SSECloses=D'01.01.2001 07:00:00'; // The afternoon session is 13:00pm to 15:00pm
string   SSEClosesText="-SSE";
string   SSEClosesDescr="-Shanghai SE";

//+-------------------------------------------------------------------------------------+
//--Moscow, MSK (Moscow Standard Time) UTC +3 Daylight saving time:	+1 hour
int      MoscowTimeZone         = +3;
datetime   MoscowDSTStarts      = D'29.03.2009 02:00:00';
datetime   MoscowDSTEnds=D'25.10.2009 03:00:00';
//--RTS Open.
datetime   RTSOpens=D'01.01.2001 07:30:00';
string   RTSOpensText="+RTS";
string   RTSOpensDescr="+RTS биржа";
//--RTS Close.
datetime   RTSCloses=D'01.01.2001 15:45:00';
string   RTSClosesText="-RTS";
string   RTSClosesDescr="-RTS биржа";

//+-------------------------------------------------------------------------------------+
//--CEST, UTC +1 Daylight saving time:	+1 hour
int      FrankfurtTimeZone      = +1;
datetime   FrankfurtDSTStarts   = D'29.03.2009 01:00:00';
datetime   FrankfurtDSTEnds=D'25.10.2009 02:00:00';
datetime   FrankfurtBegins=D'01.01.2001 07:00:00';
datetime   FrankfurtEnds=D'01.01.2001 16:00:00';
//--Color settings.
color      FrankfurtColor=Gold;
color      FrankfurtBackColor=C'51,33,0';
//--FSE Open.
datetime   FSEOpens=D'01.01.2001 08:00:00'; // Trading runs from 09:00 to 17:30 with closing auction from 17:30-17:35
string   FSEOpensText="+FSE";
string   FSEOpensDescr="+Frankfurt SE";
//--FSE Close.
datetime   FSECloses=D'01.01.2001 16:30:00';
string   FSEClosesText="-FSE";
string   FSEClosesDescr="-Frankfurt SE";

//+-------------------------------------------------------------------------------------+
//--Madrid, CET UTC +1, No DST
int      MadridTimeZone         = +1;
datetime   MadridDSTStarts      = D'29.03.2009 02:00:00';
datetime   MadridDSTEnds=D'25.10.2009 03:00:00';
//--Spanish Stock Market Interconnection System (SIBE), which handles more than 90% of transactions
//--SIBE Open.
datetime   SIBEOpens=D'01.01.2001 08:00:00'; // Trading on SIBE is conducted from 9am to 5:30pm; open outcry from 10am to 11:30am
string   SIBEOpensText="+SIBE";
string   SIBEOpensDescr="+Madrid SIBE";
//--SIBE Close.
datetime   SIBECloses=D'01.01.2001 16:30:00';
string   SIBEClosesText="-SIBE";
string   SIBEClosesDescr="-Madrid SIBE";

//+-------------------------------------------------------------------------------------+
//--GMT, UTC no offset Daylight saving time:	+1 hour
int      LondonTimeZone         = 0;
datetime   LondonDSTStarts      = D'29.03.2009 01:00:00';
datetime   LondonDSTEnds=D'25.10.2009 02:00:00';
datetime   LondonBegins=D'01.01.2001 08:00:00';
datetime   LondonEnds=D'01.01.2001 17:00:00'; //+
                                              //--Color settings.
color      LondonColor=Orange;
color      LondonBackColor=C'12,0,60';
//--LSE Open.
datetime   LSEOpens=D'01.01.2001 08:00:00';
string   LSEOpensText="+LSE";
string   LSEOpensDescr="+London SE";
//--LSE Close.
datetime   LSECloses=D'01.01.2001 16:30:00';
string   LSEClosesText="-LSE";
string   LSEClosesDescr="-London SE";

//+-------------------------------------------------------------------------------------+
//--EST, UTC -5 Daylight saving time:	+1 hour
int      NewYorkTimeZone= -5;
datetime   NewYorkBegins=D'01.01.2001 13:00:00'; //+
datetime   NewYorkEnds=D'01.01.2001 21:00:00';
datetime   NewYorkDSTStarts=D'08.03.2009 02:00:00';
datetime   NewYorkDSTEnds=D'01.11.2009 02:00:00';
//--Color settings.
color      NewYorkColor=CornflowerBlue;
color      NewYorkBackColor=C'12,0,60';
//--NYSE Open.
datetime   NYSEOpens=D'01.01.2001 14:30:00'; //  The New York Stock Exchange opens Monday through Friday at 9:30 EST
string   NYSEOpensText="+ NYSE, Toronto SE, NASDAQ, SP500";
string   NYSEOpensDescr="+ NYSE, Toronto SE, NASDAQ, SP500";
//--NYSE Close.
datetime   NYSECloses=D'01.01.2001 21:00:00'; // 16:00 EST
string   NYSEClosesText="- NYSE, Toronto SE, NASDAQ, SP500(+15min)";
string   NYSEClosesDescr="- NYSE, Toronto SE, NASDAQ, SP500(+15min)";

//+-------------------------------------------------------------------------------------+
//--CDT, UTC -6 Daylight saving time:	+1 hour
int      ChicagoTimeZone= -6;
datetime   ChicagoBegins= D'01.01.2001 14:00:00';
datetime   ChicagoEnds=D'01.01.2001 22:00:00';
datetime   ChicagoDSTStarts=D'08.03.2009 03:00:00';
datetime   ChicagoDSTEnds=D'01.11.2009 01:00:00';
//--Color settings.
color      ChicagoColor=MediumSlateBlue;
color      ChicagoBackColor=C'12,0,60';

//+-------------------------------------------------------------------------------------+
//--General variables.
datetime   daily[];
datetime HistoryDownloadTime   = 0;
double   high                  = 0;
double   low=0;
bool      SessionRectangleOn=false;
//+-------------------------------------------------------------------------------------+

//--Основные функции.
//--init - при старте программы.
int init()
  {
//--Отрисовка сессий:
   HistoryDownloadTime=0;               //--Подгрузка истории еще не производилась...
   SessionRectangleOn=ShowSessions;   //--Изначальное состояние отрисовки сессий.

                                      //--Рисуем переключатель сессий на графике.
   SwitchStatus();

//--Отрисовки разделителей:
   string   txt= "";
   datetime   i= 0;
   int      wdth=1;
   int      stl=STYLE_SOLID;
   color      clr=Black;

//--Проверяем состояние управляющего флага: запрещаем или разрешаем все сразу.
   if( AllOn > 0 ) { UseMN1 = true;   UseW1 = true;   UseD1 = true;   UseH4 = true;   UseH1 = true;   }
   if( AllOn < 0 ) { UseMN1 = false;   UseW1 = false;   UseD1 = false;   UseH4 = false;   UseH1 = false;   }

//--Рисуем H1.
   if(Period()<PERIOD_H1 && UseH1)
     {
      i=iTime(Symbol(),PERIOD_H1,0);
      while(i<EndDate)
        {
         if(!ShowPrevious || i>iTime(Symbol(),PERIOD_H1,0)) { DrawLine(TimeToStr(i),i,H1Style,H1Width,H1Color); }
         i+=PERIOD_H1*60;
        }
     }

//--Рисуем H4.
   if(Period()<PERIOD_H4 && UseH4)
     {
      i=iTime(Symbol(),PERIOD_H4,0);
      while(i<EndDate)
        {
         if(!ShowPrevious || i>iTime(Symbol(),PERIOD_H4,0)) { DrawLine(TimeToStr(i),i,H4Style,H4Width,H4Color); }
         i+=PERIOD_H4*60;
        }
     }

//--Рисуем D1.
   if(Period()<PERIOD_D1 && UseD1)
     {
      i=iTime(Symbol(),PERIOD_D1,0);
      clr=Black;

      while(i<EndDate)
        {
         //--Выходные и рабочие дни разными цветами.
         if(TimeDayOfWeek(i)==0 || TimeDayOfWeek(i)==6) { clr=WeekEndColor; }
         else { clr=BusinessDayColor; }

         if(!ShowPrevious || i>iTime(Symbol(),PERIOD_D1,0)) { DrawLine(TimeToStr(i)+": "+day[TimeDayOfWeek(i)],i,DayStyle,DayWidth,clr); }
         i+=PERIOD_D1*60;
        }
     }

//--Рисуем W1.
   if(Period()<PERIOD_W1 && UseW1)
     {
      i=iTime(Symbol(),PERIOD_W1,0);

      //--Если выбран российский формат, начинаем неделю в понедельник, иначе - в воскресенье.
      if(MondayWeekStart) { i+=PERIOD_D1*60; }

      while(i<EndDate)
        {
         if(!ShowPrevious || i>iTime(Symbol(),PERIOD_W1,0)) { DrawLine(TimeToStr(i)+": "+day[TimeDayOfWeek(i)]+" (начало недели).",i,WeekStyle,WeekWidth,WeekColor); }
         i+=PERIOD_W1*60;
        }
     }

//--Рисуем MN1.
   if(UseMN1)
     {
      i=iTime(Symbol(),PERIOD_MN1,0);
      int      month=0;
      int      year=0;
      string   m_str="";

      clr=Black;

      while(i<EndDate)
        {
         month=TimeMonth(i);
         year=TimeYear(i);

         //--Считаем месяц не ключевым по умолчанию.
         wdth=MonthWidth;
         stl   = MonthStyle;
         txt   = TimeToStr(i) + ": " + day[TimeDayOfWeek(i)] + " (начало месяца).";
         clr   = MonthColor;

         //--Если это 3, 6, 9 или 12 месяц - выделяем особым способом и подписываем разделитель.
         switch(month)
           {
            case 3:
               wdth=QuarterWidth;
               stl   = QuarterStyle;
               txt   = txt + " - Отчет за I-й квартал.";
               clr   = QuarterColor;
               break;

            case 6:
               wdth=QuarterWidth;
               stl   = QuarterStyle;
               txt   = txt + " - Отчет за II-й квартал.";
               clr   = QuarterColor;
               break;

            case 9:
               wdth=QuarterWidth;
               stl   = QuarterStyle;
               txt   = txt + " - Отчет за III-й квартал.";
               clr   = QuarterColor;
               break;

            case 12:
               wdth=QuarterWidth;
               stl   = QuarterStyle;
               txt   = txt + " - Конец отчетности.";
               clr   = QuarterColor;
               break;

            default: break;
           }

         if(!ShowPrevious || i>iTime(Symbol(),PERIOD_MN1,0)) { DrawLine(txt,i,stl,wdth,clr); }

         //--Если уже отрисовали все месяцы за год, переключаемся на следующий.
         month++;
         if(month>12)
           {
            year++;
            month=1;
           }

         if(month>9) { m_str="0"; }
         else { m_str=""; }

         i=StrToTime(year+"."+m_str+month+".01 00:00");
        }
     }

   if(ShowPrevious)
     {
      datetime time_prev,
      time_next,
      time_line;

      int bars=iBars(Symbol(),Period())-1;

      for(i=bars; i>0; i --)
        {
         time_prev=iTime(Symbol(),Period(),i);      //--время бара, который анализируем
         time_next= iTime(Symbol(),Period(),i-1);   //--время бара на один дальше в истории

                                                    //--Час.
         if(UseH1 && Period()<PERIOD_H1) { if(TimeHour(time_prev)!=TimeHour(time_next)) { DrawLine(TimeToStr(time_next),time_next,H1Style,H1Width,H1Color); } }

         //--4 Часа.
         if(UseH4 && Period()<PERIOD_H4) { if(TimeHour(time_prev)!=TimeHour(time_next) && MathMod(TimeHour(time_next),4)<Point) { DrawLine(TimeToStr(time_next),time_next,H4Style,H4Width,H4Color); } }

         //--День.
         if(UseD1 && Period()<PERIOD_D1)
           {
            if(TimeDay(time_prev)!=TimeDay(time_next))
              {
               //--Выходные и рабочие дни разными цветами.
               if(TimeDayOfWeek(time_next)==0 || TimeDayOfWeek(time_next)==6) { clr=WeekEndColor; }
               else { clr=BusinessDayColor; }

               DrawLine(TimeToStr(time_next)+": "+day[TimeDayOfWeek(time_next)],time_next,DayStyle,DayWidth,clr);
              }
           }

         //--Неделя.
         if(UseW1 && Period()<PERIOD_W1)
           {
            if(TimeDayOfWeek(time_prev)>TimeDayOfWeek(time_next)) { DrawLine(TimeToStr(time_next)+": "+day[TimeDayOfWeek(time_next)]+" (начало недели).",time_next,WeekStyle,WeekWidth,WeekColor); }
            else { if(time_next-time_prev>=PERIOD_D1*420) { DrawLine(TimeToStr(time_next)+": "+day[TimeDayOfWeek(time_next)]+" (начало недели).",time_next,WeekStyle,WeekWidth,WeekColor); } }
           }

         //--Месяц.
         if(UseMN1)
           {
            if(TimeMonth(time_prev)!=TimeMonth(time_next))
              {
               //--Считаем месяц не ключевым по умолчанию.
               wdth=MonthWidth;
               stl   = MonthStyle;
               txt   = TimeToStr(time_next) + ": " + day[TimeDayOfWeek(time_next)] + " (начало месяца).";
               clr   = MonthColor;

               time_line=time_next;

               if(TimeMonth(time_next)>11 && TimeMonth(time_prev)<12)
                 {
                  wdth=QuarterWidth;
                  stl   = QuarterStyle;
                  txt   = txt + " - Конец отчетности.";
                  clr   = QuarterColor;
                 }

               if(TimeMonth(time_next)>=3 && TimeMonth(time_prev)<3)
                 {
                  wdth=QuarterWidth;
                  stl   = QuarterStyle;
                  txt   = txt + " - Отчет за I-й квартал.";
                  clr   = QuarterColor;
                 }

               if(TimeMonth(time_next)>=6 && TimeMonth(time_prev)<6)
                 {
                  wdth=QuarterWidth;
                  stl   = QuarterStyle;
                  txt   = txt + " - Отчет за II-й квартал.";
                  clr   = QuarterColor;
                 }

               if(TimeMonth(time_next)>=9 && TimeMonth(time_prev)<9)
                 {
                  wdth=QuarterWidth;
                  stl   = QuarterStyle;
                  txt   = txt + " - Отчет за III-й квартал.";
                  clr   = QuarterColor;
                 }

               DrawLine(txt,time_line,stl,wdth,clr);
              }
           }
        }
     }

   WindowRedraw();

   return(0);
  }
//--deinit - при завершении работы.
int deinit()
  {
   string name="";
   string fix="#@!_";

   for(int i=ObjectsTotal()-1; i>=0; i --)
     {
      name=ObjectName(i);
      //--Удаляем линии разделителей и рамки сессий.
      if(StringFind(name,fix      ) >= 0 ) { ObjectDelete(name); continue; }
      if( StringFind( name,prefix ) >= 0 ) { ObjectDelete(name); continue; }

      //--Удаляем дополнительную информацию о сессиях.
      if(!PlaceUTCPoints) { continue; }
      if(StringFind(name," UTC ")>=0) { ObjectDelete(name); }
     }

//--Удаляем кнопку переключения.
   if(ObjectFind("Рамки сессий: вкл/откл.")>=0) { ObjectDelete("Рамки сессий: вкл/откл."); }

   return(0);
  }
//--start - каждый тик.
int start()
  {
//--Проверяем состояние переключателя.
   SwitchStatus();
//--Рисуем рамки сессий.
   SessionsDraw(DaysToDisplay-1,0);

   return(0);
  }
//--Вспомогательные функции.
//--DrawLine - для отрисовки вертикальных линий на графике.
void DrawLine(string text,datetime time,int style,int width,color clr)
  {
   string name=prefix+TimeToStr(time);

   if(ObjectFind(name)<0) { ObjectCreate(name,OBJ_VLINE,0,time,0); }

   ObjectSet(name,OBJPROP_COLOR,clr);
   ObjectSet(name,OBJPROP_STYLE,style);
   ObjectSet(name,OBJPROP_BACK,true);
   ObjectSet(name,OBJPROP_WIDTH,width);

   ObjectSetText(name,text);
  }
//--SwitchStatus - включение/отключение сессий на графике.
bool SwitchStatus()
  {
   string   name   = "Рамки сессий: вкл/откл.";
   string   symb   = "";
   color      clr=Black;

   int      currX   = 0;
   int      currY   = 0;
   int      X      = 5;
   int      Y      = 15;

   if(ObjectFind(name)<0)
     {
      //--устанавливаем цвет и состояние переключателя.
      if(SessionRectangleOn) { symb=CharToStr(164); clr=OnColor; }
      else { symb=CharToStr(161); clr=OffColor; }

      ObjectCreate(name,OBJ_LABEL,0,0,0);
      ObjectSet(name,OBJPROP_CORNER,1);
      ObjectSet(name,OBJPROP_XDISTANCE,X);
      ObjectSet(name,OBJPROP_YDISTANCE,Y);
      ObjectSet(name,OBJPROP_BACK,true);

      ObjectSetText(name,symb,14,"Wingdings",clr);
     }

   currX = ObjectGet( name, OBJPROP_XDISTANCE );
   currY = ObjectGet( name, OBJPROP_YDISTANCE );

//--если дергали - меняем состояние
   if(currX-X!=0 || currY-Y!=0)
     {
      SessionRectangleOn=!SessionRectangleOn;
      if(SessionRectangleOn) { symb=CharToStr(164); clr=OnColor; }
      else { symb=CharToStr(161); clr=OffColor; }

      ObjectSet(name,OBJPROP_XDISTANCE,X);
      ObjectSet(name,OBJPROP_YDISTANCE,Y);

      ObjectSetText(name,"",0,"Arial",CLR_NONE);
      ObjectSetText(name,symb,14,"Wingdings",clr);
     }

   WindowRedraw();
  }
// Отображение торговых сессий в заданном интервале времени
//
// barshiftD1from - смещение дневного бара начала периода отображения
// barshiftD1to - смещение дневного бара окончания периода отображения
//
void SessionsDraw(int barshiftD1from,int barshiftD1to)
  {
// Дозагрузка истории инструмента
   if(HistoryDownloadTime<TimeCurrent()-3600)
     {
      CopySeries(daily,MODE_TIME,Symbol(),PERIOD_D1);
      HistoryDownloadTime=TimeCurrent();
     }

   if(!SessionRectangleOn || Period()>PERIOD_H1) { SessionsClose(); return; }

   static datetime counted_bar=0;

   if(iTime(Symbol(),PERIOD_D1,0)>counted_bar)
     {
      SessionsClose();
      counted_bar=iTime(Symbol(),PERIOD_D1,0);
     }

   datetime SessionBeginUTC=0;
   datetime   SessionBegin=0;
   datetime   SessionEndUTC      = 0;
   datetime   SessionEnd         = 0;

   barshiftD1from=MathMax(0,barshiftD1from);
   barshiftD1to=MathMax(0,barshiftD1to);

   for(int daybarshift=barshiftD1from; daybarshift>=barshiftD1to; daybarshift --)
     {
      // Дата отрисовки:
      datetime   day      = iTime ( Symbol(), PERIOD_D1, daybarshift );
      string   idstring   = TimeToStr ( day, TIME_DATE );

      if(day<1) { continue; }

      // Здесь и далее приводим время к времени брокера, для коректного позиционирования на графике цены.

      //+-------------------------------------------------------------------------------------+
      //--Сиднейская сессия
      SessionBeginUTC   = TimeTableToUTC ( day, SydneyBegins, SydneyDSTStarts, SydneyDSTEnds );
      SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end ) - 24*3600;
      SessionEndUTC      = TimeTableToUTC ( day, SydneyEnds, SydneyDSTStarts, SydneyDSTEnds );
      SessionEnd         = UTCToLocalTime ( SessionEndUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("Sydney "+idstring,"Sydney",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,SydneyColor,SydneyBackColor,3);

      // Начало следующей сиднейской сессии, исключая пятницу:
      if(TimeDayOfYear(day)==DayOfYear() && DayOfWeek()!=5)
        {
         SessionBeginUTC   = TimeTableToUTC ( day, SydneyBegins, SydneyDSTStarts, SydneyDSTEnds );
         SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );
         SessionEndUTC      = TimeTableToUTC ( day, SydneyEnds, SydneyDSTStarts, SydneyDSTEnds ) + 24*3600;
         SessionEnd         = UTCToLocalTime ( SessionEndUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );

         OHLC(SessionBegin,SessionEnd);
         PlaceRectangle("Sydney "+idstring+".","Sydney",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,SydneyColor,SydneyBackColor,3);
        }

      //+-------------------------------------------------------------------------------------+
      //--Токийская сессия
      SessionBeginUTC      = TimeTableToUTC ( day, TokyoBegins, 0, 0 );
      SessionBegin         = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );
      SessionEnd=SessionBegin+(TokyoEnds-TokyoBegins);

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("Tokyo "+idstring,"Tokyo",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,TokyoColor,TokyoBackColor,0);

      //+-------------------------------------------------------------------------------------+
      //--Гонконгская сессия
      SessionBeginUTC   = TimeTableToUTC ( day, HongKongBegins, 0, 0 );
      SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );
      SessionEnd=SessionBegin+(HongKongEnds-HongKongBegins);

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("Hong Kong "+idstring,"Hong Kong",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,HongKongColor,HongKongBackColor,1);

      //+-------------------------------------------------------------------------------------+
      //--Франкфурт
      SessionBeginUTC   = TimeTableToUTC ( day, FrankfurtBegins, FrankfurtDSTStarts, FrankfurtDSTEnds );
      SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );
      SessionEnd=SessionBegin+(FrankfurtEnds-FrankfurtBegins);

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("Frankfurt "+idstring,"Frankfurt, Madrid",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,FrankfurtColor,FrankfurtBackColor,2);

      //+-------------------------------------------------------------------------------------+
      //--Лондон
      SessionBeginUTC   = TimeTableToUTC ( day, LondonBegins, LondonDSTStarts, LondonDSTEnds );
      SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );
      SessionEnd=SessionBegin+(LondonEnds-LondonBegins);

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("London "+idstring,"London",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,LondonColor,LondonBackColor,3);

      //+-------------------------------------------------------------------------------------+
      //--Чикаго
      SessionBeginUTC   = TimeTableToUTC ( day, ChicagoBegins, ChicagoDSTStarts, ChicagoDSTEnds );
      SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end );
      SessionEnd=SessionBegin+(ChicagoEnds-ChicagoBegins);

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("Chicago "+idstring,"Chicago",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,ChicagoColor,ChicagoBackColor,1);

      //+-------------------------------------------------------------------------------------+
      //--Нью-Йорк
      SessionBeginUTC   = TimeTableToUTC ( day, NewYorkBegins, NewYorkDSTStarts, NewYorkDSTEnds);
      SessionBegin      = UTCToLocalTime ( SessionBeginUTC, Broker_TimeZone, Broker_DST_start, Broker_DST_end);
      SessionEnd=SessionBegin+(NewYorkEnds-NewYorkBegins);

      OHLC(SessionBegin,SessionEnd);
      PlaceRectangle("NewYork "+idstring,"New York",SessionBeginUTC-SessionBegin,SessionBegin,low,SessionEnd,high,NewYorkColor,NewYorkBackColor,0);

      //+-------------------------------------------------------------------------------------+
      if(PlaceUTCPoints)
        {
         //--Australian Securities Exchange (ASX)
         PlaceImportantPointsUTC(TimeTableToUTC(day,ASXOpens,0,0),ASXOpensText,ASXOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,ASXCloses,0,0),ASXClosesText,ASXClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // Tokyo TSE
         PlaceImportantPointsUTC(TimeTableToUTC(day,TokyoSEOpens,0,0),TokyoSEOpensText,TokyoSEOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,TokyoSECloses,0,0),TokyoSEClosesText,TokyoSEClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // Hong Kong HKEx
         PlaceImportantPointsUTC(TimeTableToUTC(day,HKExOpens,0,0),HKExOpensText,HKExOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,HKExCloses,0,0),HKExClosesText,HKExClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // Shanghai SSE
         PlaceImportantPointsUTC(TimeTableToUTC(day,SSEOpens,0,0),SSEOpensText,SSEOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,SSECloses,0,0),SSEClosesText,SSEClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // Moscow РТС
         PlaceImportantPointsUTC(TimeTableToUTC(day,RTSOpens,MoscowDSTStarts,MoscowDSTEnds),RTSOpensText,RTSOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,RTSCloses,MoscowDSTStarts,MoscowDSTEnds),RTSClosesText,RTSClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // Frankfurt FSE
         PlaceImportantPointsUTC(TimeTableToUTC(day,FSEOpens,FrankfurtDSTStarts,FrankfurtDSTEnds),FSEOpensText,FSEOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,FSECloses,FrankfurtDSTStarts,FrankfurtDSTEnds),FSEClosesText,FSEClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // Madrid SIBE
         PlaceImportantPointsUTC(TimeTableToUTC(day,SIBEOpens,MadridDSTStarts,MadridDSTEnds),SIBEOpensText,SIBEOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,SIBECloses,MadridDSTStarts,MadridDSTEnds),SIBEClosesText,SIBEClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // London LSE
         PlaceImportantPointsUTC(TimeTableToUTC(day,LSEOpens,LondonDSTStarts,LondonDSTEnds),LSEOpensText,LSEOpensDescr);
         PlaceImportantPointsUTC(TimeTableToUTC(day,LSECloses,LondonDSTStarts,LondonDSTEnds),LSEClosesText,LSEClosesDescr);

         //+-------------------------------------------------------------------------------------+
         // New York NYSE
         PlaceImportantPointsUTC(SessionBeginUTC+(NYSEOpens-NewYorkBegins),NYSEOpensText,NYSEOpensDescr);
         PlaceImportantPointsUTC(SessionBeginUTC+(NYSECloses-NewYorkBegins),NYSEClosesText,NYSEClosesDescr);
        }
     }

   WindowRedraw();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OHLC(datetime fromtime,datetime totime)
  {
   int barshiftfrom=iBarShift(Symbol(),PERIOD_H1,fromtime);
   int barshiftto=iBarShift(Symbol(),PERIOD_H1,totime-1);

   if(iTime(Symbol(),PERIOD_H1,barshiftto) > totime - 1) { barshiftto      ++; }
   if(iTime(Symbol(),PERIOD_H1,barshiftfrom) > fromtime) { barshiftfrom   ++; }

   int highestbarshift=iHighest(Symbol(),PERIOD_H1,MODE_HIGH,barshiftfrom-barshiftto+1,barshiftto);
   int lowestbarshift=iLowest(Symbol(),PERIOD_H1,MODE_LOW,barshiftfrom-barshiftto+1,barshiftto);

   high=iHigh(Symbol(),PERIOD_H1,highestbarshift);
   low=iLow(Symbol(),PERIOD_H1,lowestbarshift);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime TimeTableToUTC(datetime date,datetime time,datetime DSTStarts,datetime DSTEnds)
  {
   datetime UTC=StrToTime(TimeToStr(date,TIME_DATE)+" "+TimeHour(time)+":"+TimeMinute(time)+":"+TimeSeconds(time));

   if(DSTStarts<=DSTEnds) { if(UTC>=DSTStarts && UTC<=DSTEnds) { UTC-=3600; } }
   else { if(!(UTC>DSTEnds && UTC<DSTStarts)) { UTC-=3600; } }

   return(UTC);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime UTCToLocalTime(datetime UTC,int TimeZone,datetime DSTStarts,datetime DSTEnds)
  {
   datetime timeyear=StrToTime("01.01."+TimeYear(UTC));
   datetime dstyear=StrToTime("01.01."+TimeYear(DSTStarts));

   datetime dststart=timeyear+DSTStarts-dstyear;
   datetime dstend=timeyear+DSTEnds-dstyear;

   if(DSTStarts<=DSTEnds && DSTStarts!=0) { if(UTC>=dststart && UTC<=dstend) { UTC+=3600; } }
   else if(DSTStarts>=DSTEnds && DSTEnds!=0)
     {
      datetime endofyear=StrToTime("31.12."+TimeYear(dststart));
      if(( UTC>=timeyear && UTC<=dstend) || (UTC>=dststart && UTC<=endofyear)) { UTC+=3600; }
     }

   return(UTC+TimeZone*3600);
  }
// Удалить все графические объекты индикатора торговых сессий
//
void SessionsClose()
  {
   int      obj_total=ObjectsTotal()-1;
   string   objname="";
   string   fix="#@!_";

   for(int obj=obj_total; obj>=0; obj --)
     {
      objname=ObjectName(obj);
      if(StringFind(objname,fix)>=0) { ObjectDelete(objname); continue; }

      if(!PlaceUTCPoints) { continue; }
      if(StringFind(objname," UTC ")>=0) { ObjectDelete(objname); }
     }
  }
// Отрисовать одну сессию
//
void PlaceRectangle(string session,string description,int toUTC,datetime time1,double price1,datetime time2,double price2,color session_color,color rect_color,int level)
  {
   if(time2<time1 || time2>time1+12*3600) { return; }

   string fix="#@!_";
   string objname="";
// Рамки сессий на графике цены
   objname=fix+session+" Session High";
   if(ObjectFind(objname)<0) { ObjectCreate(objname,OBJ_TREND,0,time1,price2,time2,price2); }
   ObjectSet(objname,OBJPROP_COLOR,session_color);
   ObjectSet(objname,OBJPROP_BACK,true);
   ObjectSet(objname,OBJPROP_STYLE,RectLineStyle);
   ObjectSet(objname,OBJPROP_WIDTH,RectLineWidth);
   ObjectSet(objname,OBJPROP_RAY,0);

   objname=fix+session+" Session Low";
   if(ObjectFind(objname)<0) { ObjectCreate(objname,OBJ_TREND,0,time1,price1,time2,price1); }
   ObjectSet(objname,OBJPROP_COLOR,session_color);
   ObjectSet(objname,OBJPROP_BACK,true);
   ObjectSet(objname,OBJPROP_STYLE,RectLineStyle);
   ObjectSet(objname,OBJPROP_WIDTH,RectLineWidth);
   ObjectSet(objname,OBJPROP_RAY,0);

   objname=fix+session+" Session Begin";
   if(ObjectFind(objname)<0) { ObjectCreate(objname,OBJ_TREND,0,time1,price2,time1,price1); }
   ObjectSet(objname,OBJPROP_COLOR,session_color);
   ObjectSet(objname,OBJPROP_BACK,true);
   ObjectSet(objname,OBJPROP_STYLE,RectLineStyle);
   ObjectSet(objname,OBJPROP_WIDTH,RectLineWidth);
   ObjectSet(objname,OBJPROP_RAY,0);

   objname=fix+session+" Session End";
   if(ObjectFind(objname)<0) { ObjectCreate(objname,OBJ_TREND,0,time2,price1,time2,price2); }
   ObjectSet(objname,OBJPROP_COLOR,session_color);
   ObjectSet(objname,OBJPROP_BACK,true);
   ObjectSet(objname,OBJPROP_STYLE,RectLineStyle);
   ObjectSet(objname,OBJPROP_WIDTH,RectLineWidth);
   ObjectSet(objname,OBJPROP_RAY,0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlaceImportantPointsUTC(datetime UTC,string text,string description)
  {
   datetime   time=UTCToLocalTime(UTC,Broker_TimeZone,Broker_DST_start,Broker_DST_end);
   string   name=TimeToStr(UTC,TIME_DATE|TIME_MINUTES)+" UTC ";

   int      barshift=iBarShift(Symbol(),0,time);

   if((IndicatorCounted()<barshift+1) || (barshift==0) || (IndicatorCounted()==0)) return;

   string   settext="";
   low=MathMin(MathMin(Low[barshift],Low[barshift+1]),Low[barshift-1]);
   if(low<0.1) { low=Bid; }

   if(ObjectFind(name)<0) { ObjectCreate(name,OBJ_ARROW,0,time,low-8*Point); settext=description; }
   else
     {
      settext=ObjectDescription(name);
      if(StringFind(settext,description)<0) { settext=settext+", "+description; }
     }

   ObjectSet(name,OBJPROP_ARROWCODE,191);
   ObjectSet(name,OBJPROP_BACK,true);
   ObjectSet(name,OBJPROP_COLOR,UTCPointColor);
   ObjectSetText(name,settext);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CopySeries(datetime &array[],int MODE,string SYMBOL,int PERIOD)
  {
   ArrayCopySeries(array,MODE,SYMBOL,PERIOD);
   int lasterror=GetLastError();

   if(lasterror==4066) // ERR_HISTORY_WILL_UPDATED
     {
      int attempt=0;
      while(lasterror==4066 && attempt<10)
        {
         Sleep(5000);
         ArrayCopySeries(array,MODE,SYMBOL,PERIOD);
         lasterror=GetLastError();
        }
     }
  }
//+------------------------------------------------------------------+
