Modification of Trading Sessions Indicator i-sessions to adjust for DST problem

 

KimIV's excellent indicator i-sessions does not allow adjustment for DST on sessions.  I am trying to modify it for my needs/preferences.

I am doing this in MQL5.

the indicator draws colored rectangles on the chart highlighting the trading session from session opn to session close and at hieght of session low to session high.  The input parameters are session begin time and session end time.  The original code allows for 8 different market sessions.  I only wnat 3 sessions.  And i am using this for back testing and analysis so I need the seesion open time charted to be corrected for Daylight Savings Time (or Summertime/Wintertime) as the case maybe.  End result is I should see the shift in time on the chart at any given date  (so around Mar 30 the London session open would change from 8:00 GMT to 7:00 GMT and so forth for NY Session as well).   

I modified and added input variables in the original code to suit my needs.  (Changed variable S1Begin to TKYBegin; Added TKYBeginDST,  for instance).  I tested my alterations no problem.

Next I altered the program to use my new input variable in place of the original variable.  I am just testing London only in my code.  So rather than using LDNBegin (London session open time) I substituted LDNBeginDST (London Summertime Open).  It functioned as expected so that the full history on the charts (up to 500 bars) showed London session open at 7:00 GMT.  Thus I knew that I was inserting my variable values successfully.

Next I created a test on the date.  I  believe that KimIV the original author of the indicator decrements (decreases) the variable "dt" with each iteration in OnCalculate().  First iteration "dt" is TimeCurrent().  Then each bar shift "dt" is set back by the date/time value of the bar by the function decDateTradeDay().  I reasoned that I did not need to alter any of his functions but rather I could just run a test on the value "dt" in each iteration to see whether it was during DST period (Summertime) or regular time.  If DST time then I would change the session open time.

My code compiles successfully but the rectangles drawn do not change for the sessions during DST.  Could someone look at the code attached and see what I am missing?  

I don't really know this language well but I have coded in c++ and other languages (JavaScript, Basic and others).  I'm not completely following the programming flow and I had hoped to be able to insert a quick test and change.  My new code compile but the session rectangles do't appear to change for dates affected by DST.  

Could some one please identify what I have done wrong?

Thank you in advance.

Dennis

traderdjid@gmail.com


//+------------------------------------------------------------------+
//|                                                   i-Sessions.mq5 |
//|                         Copyright © 2006, Kim Igor V. aka KimIV  |
//|                                              http://www.kimiv.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Kim Igor V. aka KimIV"
#property link      "http://www.kimiv.ru"
#property description "The trade sessions indicator"
//---- indicator version number
#property version   "1.00"
//---- drawing the indicator in the main window
#property indicator_chart_window 
//---- number of indicator buffers
#property indicator_buffers 0 
//---- only 0 plots are used
#property indicator_plots   0


//+-----------------------------------+
//|  declaration of constants         |
//+-----------------------------------+
#define RESET 0 // The constant for returning the indicator recalculation command to the terminal
//+-----------------------------------+
//|  INDICATOR INPUT PARAMETERS       |
//+-----------------------------------+


// modified input variables TKYBegin rather than S1Begin and so forth

input int    NumberOfDays=500;
input string TKYBegin   ="01:00";
input string TKYBeginDST ="01:00";
input string TKYEnd     ="10:00";
input string TKYEndDST  ="10:00";
input color  TKYColor   =C'220,220,255';
input string LDNBegin   ="08:00";
input string LDNBeginDST   ="07:00";
input string LDNEnd     ="17:00";
input string LDNEndDST  ="13:00";
input color  LDNColor   =C'255,252,145';
input string NYBegin    ="14:00";
input string NYBeginDST ="13:00";
input string NYEnd     ="23:00";
input string NYEndDST   ="22:00";
input color  NYColor   =C'255,223,223';
sinput string TKY2018_DSTBegDate ="2018.04.01";
sinput string TKY2018_DSTEndDate ="2018.11.01";
sinput string TKY2019_DSTBegDate ="2018.04.01";
sinput string TKY2019_DSTEndDate ="2018.11.01";
sinput string TKY2020_DSTBegDate ="2019.04.01";
sinput string TKY2020_DSTEndDate ="2019.11.01";
input string LDN2018_DSTBegDate ="2020.03.25";
input string LDN2018_DSTEndDate ="2020.10.28";
input string LDN2019_DSTBegDate ="2019.03.31";
input string LDN2019_DSTEndDate ="2019.10.27";
input string LDN2020_DSTBegDate ="2020.03.29";
input string LDN2020_DSTEndDate ="2020.10.25";
input string NY2018_DSTBegDate ="2018.03.11";
input string NY2018_DSTEndDate ="2018.11.04";
input string NY2019_DSTBegDate ="2019.03.10";
input string NY2019_DSTEndDate ="2019.11.03";
input string NY2020_DSTBegDate ="2020.03.08";
input string NY2020_DSTEndDate ="2020.11.01";


//input string S4Begin   ="09:55";
//input string S4End     ="12:55";
//input color  S4Color   =clrDarkSlateGray;
//input string S5Begin   ="12:55";
//input string S5End     ="15:55";
//input color  S5Color   =clrDarkSlateGray;
//input string S6Begin   ="15:55";
//input string S6End     ="18:55";
//input color  S6Color   =clrDarkSlateGray;
//input string S7Begin   ="18:55";
//input string S7End     ="21:55";
//input color  S7Color   =clrDarkSlateGray;
//input string S8Begin   ="21:55";
//input string S8End     ="23:55";
//input color  S8Color   =clrDarkSlateGray;

//+-----------------------------------+

//---- Declaration of integer variables of data starting point
int min_rates_total;
//+------------------------------------------------------------------+   
//| i-Sessions indicator initialization function                     | 
//+------------------------------------------------------------------+ 
void OnInit()
  {
//---- Initialization of variables of data calculation starting point
   min_rates_total=NumberOfDays*PeriodSeconds(PERIOD_D1)/PeriodSeconds(PERIOD_CURRENT);

//--- creation of the name to be displayed in a separate sub-window and in a pop up help
   IndicatorSetString(INDICATOR_SHORTNAME,"i-Sessions");

//--- determination of accuracy of displaying the indicator values
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- end of initialization
  }
//+------------------------------------------------------------------+
//| i-Sessions deinitialization function                             |
//+------------------------------------------------------------------+    
void OnDeinit(const int reason)
  {
//----
   for(int i=0; i<NumberOfDays; i++)
     {
      ObjectDelete(0,"TKY"+string(i));
      ObjectDelete(0,"LDN"+string(i));
      ObjectDelete(0,"NY"+string(i));
//      ObjectDelete(0,"S4"+string(i));
//      ObjectDelete(0,"S5"+string(i));
//      ObjectDelete(0,"S6"+string(i));
//      ObjectDelete(0,"S7"+string(i));
//      ObjectDelete(0,"S8"+string(i));
     }
//----
   ChartRedraw(0);
  }
//+------------------------------------------------------------------+ 
//| i-Sessions iteration function                                    | 
//+------------------------------------------------------------------+ 
int OnCalculate(
                const int rates_total,    // amount of history in bars at the current tick
                const int prev_calculated,// amount of history in bars at the previous tick
                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[]
                )
  {
//---- checking for the sufficiency of the number of bars for the calculation
   if(rates_total<min_rates_total) return(RESET);

//---- indexing elements in arrays as in timeseries  
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);

   datetime dt=TimeCurrent();
   for(int i=0; i<NumberOfDays; i++) {




// ============================================================================================
//  my added code
      // Adjust for DST          datetime BegDate;          datetime EndDate;          string LDNbt;          string LDNet;          MqlDateTime TestYr;          TimeToStruct(dt,TestYr);               //  Test Year Beg and End dates for DST  if DST adj session begin and end times            if (TestYr.year==2020){             BegDate = StringToTime(LDN2020_DSTBegDate);             EndDate = StringToTime(LDN2020_DSTEndDate);                          if (dt >= BegDate && dt < EndDate) {                // is in DST                LDNbt = LDNBeginDST;                LDNet = LDNEndDST;                               }             else {                // is NOT DST                LDNbt = LDNBegin;                LDNet = LDNEnd;                            }          }                  if (TestYr.year==2019){             BegDate = StringToTime(LDN2019_DSTBegDate);             EndDate = StringToTime(LDN2019_DSTEndDate);                          if (dt >= BegDate && dt < EndDate) {                // is in DST                LDNbt = LDNBeginDST;                LDNet = LDNEndDST;                }             else {                // is NOT DST                LDNbt = LDNBegin;                LDNet = LDNEnd;             }          }                  if (TestYr.year==2018){             BegDate = StringToTime(LDN2018_DSTBegDate);             EndDate = StringToTime(LDN2018_DSTEndDate);                          if (dt >= BegDate && dt < EndDate) {                // is in DST                LDNbt = LDNBeginDST;                LDNet = LDNEndDST;                }             else {                // is NOT DST                LDNbt = LDNBegin;                LDNet = LDNEnd;             }                }       // ======================================================================================                        //----              DrawRectangle(dt,"TKY"+string(i),TKYBegin,TKYEnd,TKYColor,high,low);       DrawRectangle(dt,"LDN"+string(i),LDNbt,LDNet,LDNColor,high,low);      // modified here to use new variable LDNbt & LDNet       DrawRectangle(dt,"NY"+string(i),NYBegin,NYEnd,NYColor,high,low); //      DrawRectangle(dt,"S4"+string(i),S4Begin,S4End,S4Color,high,low);//      DrawRectangle(dt,"S5"+string(i),S5Begin,S5End,S5Color,high,low);//      DrawRectangle(dt,"S6"+string(i),S6Begin,S6End,S6Color,high,low);//      DrawRectangle(dt,"S7"+string(i),S7Begin,S7End,S7Color,high,low);//      DrawRectangle(dt,"S8"+string(i),S8Begin,S8End,S8Color,high,low);       dt = decDateTradeDay(dt);   // function decreases trading day new value in variable "dt"       MqlDateTime ttt;       TimeToStruct(dt,ttt);    // converts current datetime (dt) to MqlDateTime ttt              while(ttt.day_of_week>5)         {          dt=decDateTradeDay(dt);          TimeToStruct(dt,ttt);         }       // end of FOR LOOP, iterates backwards in bars on chart (first/current bar 0, second/last bar 1, third bar 3, etc.        } //----        return(rates_total);   } //+------------------------------------------------------------------+ //| Drawing objects in the chart                                     | //| Parameters:                                                      |//|   dt - date of the trading day                                   | //|   no - name of the object                                        |//|   tb - starting time of the session                              |//|   te - ending time of the session                                |//+------------------------------------------------------------------+void DrawRectangle(datetime dt,string no,string tb,string te,color clr,constdouble &High[],const double &Low[])   { //----    datetime t1,t2;    double p1,p2;    int b1,b2; //----    //    t1=StringToTime(TimeToString(dt,TIME_DATE)+" "+tb);    t2=StringToTime(TimeToString(dt,TIME_DATE)+" "+te); //----    b1=iBarShift(NULL,0,t1);    b2=iBarShift(NULL,0,t2); //----      int res=b1-b2;    int extr=MathMax(0,ArrayMaximum(High,b2,res));    p1=High[extr];    extr=MathMax(0,ArrayMinimum(Low,b2,res));    p2=Low[extr]; //----    SetRectangle(0,no,0,t1,p1,t2,p2,clr,false,no); //----   } //+------------------------------------------------------------------+//| Decrease date on one trading day                                 | //| Parameters:                                                      |//|   dt - date of the trading day                                   | //+------------------------------------------------------------------+ datetime decDateTradeDay(datetime dt)   { //----    MqlDateTime ttt;    TimeToStruct(dt,ttt);    int ty=ttt.year;    int tm=ttt.mon;    int td=ttt.day;    int th=ttt.hour;    int ti=ttt.min; //----    td--;    if(td==0)      {       tm--;       if(!tm)         {          ty--;          tm=12;         }       if(tm==1 || tm==3 || tm==5 || tm==7 || tm==8 || tm==10 || tm==12) td=31;       if(tm==2) if(!MathMod(ty,4)) td=29; else td=28;       if(tm==4 || tm==6 || tm==9 || tm==11) td=30;      }    string text;    StringConcatenate(text,ty,".",tm,".",td," ",th,":",ti); //----    return(StringToTime(text));   }    //+------------------------------------------------------------------+   //| iBarShift() function                                             | //+------------------------------------------------------------------+  intiBarShift(string symbol,ENUM_TIMEFRAMES timeframe,datetime time) // iBarShift(symbol, timeframe, time) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+   { //----    if(time<0) return(-1);    datetime Arr[],time1;    time1=(datetime)SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE);    if(CopyTime(symbol,timeframe,time,time1,Arr)>0)      {       int size=ArraySize(Arr);       return(size-1);      }    else return(-1); //----   } //+------------------------------------------------------------------+//| Creating rectangle object:                                       | //+------------------------------------------------------------------+ void CreateRectangle ( long     chart_id,      // chart ID string   name,          // object name int      nwin,          // window index datetime time1,         // time 1 double   price1,        // price 1 datetime time2,         // time 2 double   price2,        // price 2 color    Color,         // line color bool     background,    // line background display string   text           // text ) //----   { //----    ObjectCreate(chart_id,name,OBJ_RECTANGLE,nwin,time1,price1,time2,price2);    ObjectSetInteger(chart_id,name,OBJPROP_COLOR,Color);    ObjectSetInteger(chart_id,name,OBJPROP_FILL,true);    ObjectSetString(chart_id,name,OBJPROP_TEXT,text);    ObjectSetInteger(chart_id,name,OBJPROP_BACK,background);    ObjectSetString(chart_id,name,OBJPROP_TOOLTIP,"\n"); // tooltip disabling    ObjectSetInteger(chart_id,name,OBJPROP_BACK,true); // background object //----   } //+------------------------------------------------------------------+//|  Reinstallation of the rectangle object                          |//+------------------------------------------------------------------+void SetRectangle ( long     chart_id,      // chart ID string   name,          // object name int      nwin,          // window index datetime time1,         // time 1 double   price1,        // price 1 datetime time2,         // time 2 double   price2,        // price 2 color    Color,         // line color bool     background,    // line background display string   text           // text ) //----   { //----    if(ObjectFind(chart_id,name)==-1) CreateRectangle(chart_id,name,nwin,time1,price1,time2,price2,Color,background,text);    else      {       ObjectSetString(chart_id,name,OBJPROP_TEXT,text);       ObjectMove(chart_id,name,0,time1,price1);       ObjectMove(chart_id,name,1,time2,price2);      } //----   } //+------------------------------------------------------------------+
Documentation on MQL5: Object Functions / ObjectCreate
Documentation on MQL5: Object Functions / ObjectCreate
  • www.mql5.com
The function creates an object with the specified name, type, and the initial coordinates in the specified chart subwindow. During creation up to 30 coordinates can be specified. The function returns true if the command has been successfully added to the queue of the specified chart, or false otherwise. If an object has already been created, an...
 
Traderdj:

KimIV's excellent indicator i-sessions does not allow adjustment for DST on sessions.  I am trying to modify it for my needs/preferences.

...

The original doesn't do it because it's not possible to do it correctly.

To do it correctly you would need to know the broker server DST, if any. Maybe you can get this information from your broker and do it for your own usage.

Beside that, if you want coding help you should post clear code, what you posted is a mess.

 
Alain Verleyen:

The original doesn't do it because it's not possible to do it correctly.

To do it correctly you would need to know the broker server DST, if any. Maybe you can get this information from your broker and do it for your own usage.

Beside that, if you want coding help you should post clear code, what you posted is a mess.

I apologize for the coding "mess".  I have never posted on this forum before so I am uncertain how to best present my problem.  The coding is by another author who has several very good custom indicators and I presumed that his coding was not a "mess".  Let me try to re-phrase my question.

1) The program flow is like this (I believe)

OnCalculate()

- Iterate through NumberOfDays

- DrawRectangle(datetime dt, string NameOfRectangle(i), SessionOpenTime, SessionEndTime, SessionColor, SessionHigh, SessionLow)

- Decrement  datetime value dt function decDateTradeDay(dt)

- test while day_of_week Mon-Fri (1-5) true

2)  I don't really understand the iteration of the draw function.  I believe that on each iteration, a rectangle is drawn for the bar by the paramenters SessionOpen, SessionClose, SessionHigh, and SessionLow.  I believe each bar is iterated going from the current bars backwards to the furthest bay represented by NumberOfDays.  Is each rectangle (each bar) parameters independent of the previous iteration?  If that is true, why could the parameters change for bars 50-60 from the parameters for bars 0-49?

3) Finally, you say the original doesn't do it because its not possible.  I don't understand why representing the changed time values for half of the year can not be represented in a chart.  The broker (Oanda) is using a GMT+2 server (a MetaQuotes Demo server).  If the server time changes with DST, then I guess no adjustment is needed for the sessions which also change to DST (London and NY for instance).  But then what about Tokyo which does not use DST? I have been presuming that this server is always GMT+2 but perhaps it is now GMT+3.   This is what I am trying to understand.

I am sincerely trying to find a solution from others who have expertise. I am sorry if I have offended you.


Dennis

Step on New Rails: Custom Indicators in MQL5
Step on New Rails: Custom Indicators in MQL5
  • www.mql5.com
Finally we've got an opportunity to try the new trade terminal - MetaTrader 5. No doubt, it is noteworthy and has many new features as compared to its predecessor. The important advantages of this platform among others are: Essentially modified language allowing now to use the object-oriented programming, still allowing to use the rich...
 
Traderdj:

I apologize for the coding "mess".  I have never posted on this forum before so I am uncertain how to best present my problem.  The coding is by another author who has several very good custom indicators and I presumed that his coding was not a "mess".  Let me try to re-phrase my question.

1) The program flow is like this (I believe)

OnCalculate()

- Iterate through NumberOfDays

- DrawRectangle(datetime dt, string NameOfRectangle(i), SessionOpenTime, SessionEndTime, SessionColor, SessionHigh, SessionLow)

- Decrement  datetime value dt function decDateTradeDay(dt)

- test while day_of_week Mon-Fri (1-5) true

2)  I don't really understand the iteration of the draw function.  I believe that on each iteration, a rectangle is drawn for the bar by the paramenters SessionOpen, SessionClose, SessionHigh, and SessionLow.  I believe each bar is iterated going from the current bars backwards to the furthest bay represented by NumberOfDays.  Is each rectangle (each bar) parameters independent of the previous iteration?  If that is true, why could the parameters change for bars 50-60 from the parameters for bars 0-49?

3) Finally, you say the original doesn't do it because its not possible.  I don't understand why representing the changed time values for half of the year can not be represented in a chart.  The broker (Oanda) is using a GMT+2 server (a MetaQuotes Demo server).  If the server time changes with DST, then I guess no adjustment is needed for the sessions which also change to DST (London and NY for instance).  But then what about Tokyo which does not use DST? I have been presuming that this server is always GMT+2 but perhaps it is now GMT+3.   This is what I am trying to understand.

I am sincerely trying to find a solution from others who have expertise. I am sorry if I have offended you.


Dennis

Offended ? Not at all.

It can't be coded for all brokers because the DST/GMT can be different for each broker and there is no coding way to know the DST of the server.

It can be coded if you know the server GMT/DST. You said Oanda is GMT+2 but what about DST ? I see a lot of assumptions in your post, but it's not nothing you can "understand", it's something you need to know and the only way to know it is to ask to your broker.

ONLY when you know the server GMT/DST what you want to do will be codable reliably. It then becomes trivial to apply the different time shift according to the sessions GMT/DST.

 
Alain Verleyen:

Offended ? Not at all.

It can't be code for all brokers because the DST/GMT can be different for each broker and there is no coding way to know the DST of the server.

It can be coded if you know the server GMT/DST. You said Oanda is GMT+2 but what about DST ? I see a lot of assumptions in your post, but it's not nothing you can "understand", it's something you need to know and the only way to know it is to ask to your broker.

ONLY when you know the server GMT/DST what you want to do will be codable reliably. It then becomes trivial to apply the different time shift according to the sessions GMT/DST.

I have read articles on time functions and daylight saving time and other related articles since your last response.  I understand now the difficulties and obstacles in  my question.  Thak you for giving me direction.  Yes I can do it under limits of my brokers server but it won't apply on another server with different time.  I was hoping for an easy answer and there isn't one apparently,  Thank you for your time.

Dennis

Reason: