Local Timezones and Local Session Hours – library MetaTrader 5

Hello, traders.

This library has all the functions to get the current local time in a specific or all Forex markets. You can convert the local times between time zones or to your broker’s server time. You can also trade in specific sessions by setting the session start and end times for each session, separately. The library will take care of the different time offsets and daylight time changes of the broker and these markets. This relieves the burden of reinventing the wheel every time you program an expert advisor or a technical indicator that has to deal with time zones and local session hours.


Class interface

//+------------------------------------------------------------------+
//| Class CTimeZoneInfo.                                             |

//| Purpose: Class to access to the local time for the specified     |
//|          location, as well as time zone information, time        |
//|          changes for the current year.                           |
//|          Derives from class CObject.                             |
//+------------------------------------------------------------------+
class CTimeZoneInfo : public CObject
  {
public:
                
                     CTimeZoneInfo( ENUM_ZONE_ID placeId );
                    ~CTimeZoneInfo( void );

   string            Name( void );
   string            ToString( void );
   bool              RefreshTime( void );
   bool              SetLocalTime( datetime pLocalTime );

   datetime          TimeLocal( void );
   datetime          TimeUTC( void );
   int               TimeGMTOffset( void );  // positive if the timezone is east of GMT, otherwise negative.
   int               TimeDaylightSavings( void );

   datetime          ConvertLocalTime( ENUM_ZONE_ID destinationId );
   bool              GetDaylightSwitchTimes( datetime &dst_start, datetime &dst_end );
   datetime          GetDaylightNextSwitch( void );
   void              PrintObject( void );

   static datetime   GetCurrentTimeForPlace( ENUM_ZONE_ID placeId );
   static string     FormatTimeForPlace( datetime time, ENUM_ZONE_ID placeId );
   static datetime   ConvertTimeForPlace( datetime time, ENUM_ZONE_ID placeId, ENUM_ZONE_ID destinationId );

   static bool       GetDaylightSwitchTimes( ENUM_ZONE_ID placeId, int iYear, datetime &dst_start, datetime &dst_end );
   static bool       GetDaylightSwitchDeltas( ENUM_ZONE_ID placeId, int iYear, int &delta_start, int &delta_end );
   static bool       IsDaylightSavingTime( datetime time, ENUM_ZONE_ID placeId );
  };


Class interface

//+------------------------------------------------------------------+
//| Class CSessionHours.                                             |
//| Purpose: Class to access the local trading session hours for     |
//|          the specified location.                                 |
//|          Derives from class CTimeZoneInfo.                       |
//| Note:    The default session hours are set to 8:00 am - 5:00 pm  |
//|          local time for new CSessionHours objects.               |
//+------------------------------------------------------------------+
class CSessionHours : public CTimeZoneInfo
  {
public:
                     CSessionHours( ENUM_ZONE_ID placeId );
                    ~CSessionHours( void );

   //--- methods to access the local session time
   bool              RefreshTime( void );
   bool              SetLocalTime( datetime pLocalTime );

   //--- methods to override default local session hours
   bool              BeginLocalTime( int pHour, int pMinute );
   bool              EndLocalTime( int pHour, int pMinute );

   //--- methods to access local session hours
   datetime          BeginLocalTime( void );
   datetime          EndLocalTime( void );
   bool              CheckLocalSession( void );       // Check whether the local trading session is currently active.
   int               SecRemainingSession( void );     // Time remaining in seconds till local session closes for the day.

   //--- static methods that do not require the creation of an object.
   static datetime   ForexCloseTime( void );          // The broker time when the Forex market closes for this week.
   static int        SecRemainingForex( void );       // Time remaining in seconds till Forex market closes for this week.
   static string     SecondsToString( int seconds );  // Format the time in seconds to a string (like 2d 14:58:04)
  };

Note about Compatibility with The Strategy Tester

During testing in the strategy tester, TimeGMT() is always equal to TimeTradeServer() simulated server time.

For proper results during backtesting in the strategy tester, you should also include TimeGMT library  

This library will fix the TimeGMT() function in order to provide the true GMT during testing.

#include "TimeGMT.mqh"  // 
#include "TimeZoneInfo.mqh"


What is the Timezone?

Timezone is defined as the standard time depending on the geographical representation of that place. In other words, timezone refers to the local time of a particular region based on the earth’s rotation. It is defined in UTC (Coordinated Universal Time), the standard against which the world’s region-based time is coordinated.

For Example – Time in New York is 5 hours behind Greenwich and represented as UTC-5 or UTC-4 based on the day light. Time in Sydney is 10 hours ahead of Greenwich and represented as UTC+10 or UTC+11 based on the day light (summer or winter). 

The UTC offset is positive if the timezone is east of GMT, and it is negative if the timezone is west of GMT.




I. Working with Local Timezones

How to get the current time?

The RefreshTime() method will update the current local time of the time zone. Let us see an example to show how we can get the current time.

   Print("\n========== Get the current time in a timezone ==========");

   CTimeZoneInfo tz(ZONE_ID_TOKYO);
   tz.RefreshTime(); // populate current timezone information

   Print("Name()      : ", tz.Name());
   Print("TimeLocal() : ", tz.TimeLocal());
   Print("ToString()  : ", tz.ToString());

output:

   // ========== Get the current time in a timezone ==========
   // Name()      : Tokyo
   // TimeLocal() : 2024.02.28 19:58:50
   // ToString()  : Wed, 2024.02.28 19:58:50 GMT+9 [Tokyo]


Do you need more information?

   Print("\n========== More information about a timezone ==========");

   CTimeZoneInfo tz(ZONE_ID_NEWYORK);
   tz.RefreshTime();

   Print("Name()                : ", tz.Name());
   Print("TimeUTC()             : ", tz.TimeUTC());
   Print("TimeLocal()           : ", tz.TimeLocal());
   Print("TimeGMTOffset()       : ", tz.TimeGMTOffset());
   Print("TimeDaylightSavings() : ", tz.TimeDaylightSavings());
   Print("ToString()            : ", tz.ToString());
   datetime dst_start, dst_end;
   tz.GetDaylightSwitchTimes(dst_start, dst_end);
   Print("dst_start             : ", dst_start);
   Print("dst_end               : ", dst_end);
   Print("GetDaylightNextSwitch() : ", tz.GetDaylightNextSwitch());

output:

   // ========== More information about a timezone ==========
   // Name()                : New York
   // TimeUTC()             : 2024.02.28 10:58:50
   // TimeLocal()           : 2024.02.28 05:58:50
   // TimeGMTOffset()       : -18000
   // TimeDaylightSavings() : 0
   // ToString()            : Wed, 2024.02.28 05:58:50 GMT-5 [New York]
   // dst_start             : 2024.03.10 02:00:00
   // dst_end               : 2024.11.03 02:00:00
   // GetDaylightNextSwitch() : 2024.03.10 02:00:00


Get Current Time in All Timezones

Let us see an example to show how we can get the current local time in all timezones.

   Print("\n========== Get Current Time in All Timezones ==========");

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      CTimeZoneInfo tz(id);
      tz.RefreshTime();

      PrintFormat("%-12s:  %s | %s", tz.Name(), TimeToString(tz.TimeLocal()), tz.ToString());
     }

output:

   // ========== Get Current Time in All Timezones ==========
   // Sydney      :  2024.02.28 21:58 | Wed, 2024.02.28 21:58:50 GMT+11 [Sydney] (DST)
   // Tokyo       :  2024.02.28 19:58 | Wed, 2024.02.28 19:58:50 GMT+9 [Tokyo]
   // Frankfurt   :  2024.02.28 11:58 | Wed, 2024.02.28 11:58:50 GMT+1 [Frankfurt]
   // London      :  2024.02.28 10:58 | Wed, 2024.02.28 10:58:50 GMT+0 [London]
   // New York    :  2024.02.28 05:58 | Wed, 2024.02.28 05:58:50 GMT-5 [New York]
   // UTC         :  2024.02.28 10:58 | Wed, 2024.02.28 10:58:50 GMT+0 [UTC]
   // Home        :  2024.02.28 12:58 | Wed, 2024.02.28 12:58:50 GMT+2 [Home]
   // FXOpen-MT5  :  2024.02.28 12:58 | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]


This can be done in the other way using the static method GetCurrentTimeForPlace(). Also, note that there is another static method FormatTimeForPlace() that can be used to format plain mql datetime variables to a string  (similar to TimeToString) but with the weekday, date, time, the timezone name and offsets. These static methods do not require the creation of objects to call them.

   Print("\n========== GetCurrentTimeForPlace() ==========");

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      datetime time = CTimeZoneInfo::GetCurrentTimeForPlace(id);

      PrintFormat("Time        :  %s | %s", TimeToString(time), CTimeZoneInfo::FormatTimeForPlace(time, id));
     }

output:

   // ========== GetCurrentTimeForPlace() ==========
   // Time        :  2024.02.28 21:58 | Wed, 2024.02.28 21:58:50 GMT+11 [Sydney] (DST)
   // Time        :  2024.02.28 19:58 | Wed, 2024.02.28 19:58:50 GMT+9 [Tokyo]
   // Time        :  2024.02.28 11:58 | Wed, 2024.02.28 11:58:50 GMT+1 [Frankfurt]
   // Time        :  2024.02.28 10:58 | Wed, 2024.02.28 10:58:50 GMT+0 [London]
   // Time        :  2024.02.28 05:58 | Wed, 2024.02.28 05:58:50 GMT-5 [New York]
   // Time        :  2024.02.28 10:58 | Wed, 2024.02.28 10:58:50 GMT+0 [UTC]
   // Time        :  2024.02.28 12:58 | Wed, 2024.02.28 12:58:50 GMT+2 [Home]
   // Time        :  2024.02.28 12:58 | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]


How to set the local time for the timezone?

The SetLocalTime() method will set the specified local time. Let us see an example to show how we can set the local time for the timezone.

   Print("\n========== Set the local time for a timezone ==========");

   CTimeZoneInfo tz(ZONE_ID_NEWYORK);

   if(tz.SetLocalTime(D'2021.07.15 09:31'))
      PrintFormat("%-12s:  %s | %s", tz.Name(), TimeToString(tz.TimeLocal()), tz.ToString());

   if(tz.SetLocalTime(D'2022.01.23 17:04'))
      PrintFormat("%-12s:  %s | %s", tz.Name(), TimeToString(tz.TimeLocal()), tz.ToString());

   if(tz.SetLocalTime(D'2023.03.12 02:21'))
      PrintFormat("%-12s:  %s | %s", tz.Name(), TimeToString(tz.TimeLocal()), tz.ToString());

output:

   // ========== Set the local time for a timezone ==========
   // New York    :  2021.07.15 09:31 | Thu, 2021.07.15 09:31:00 GMT-4 [New York] (DST)
   // New York    :  2022.01.23 17:04 | Sun, 2022.01.23 17:04:00 GMT-5 [New York]
   // >>Error: The time 2023.03.12 02:21 does not exist in New York. This is because Daylight Saving Time skipped one hour.

The cause for the last error message we get will be explained in the next paragraph.


Daylight Saving Time (DST):

DST is a seasonal time change measure where clocks are set ahead of standard time during part of the year.

see 

(“Summer Skip”, “Winter Wind-back”)

When DST starts in the spring, our clocks are set forward by a certain amount of time, usually by one hour. This means that one hour is skipped on the clock. In the fall (autumn), the DST period usually ends, and our clocks are set back to standard time again.

Alternative:   Exp_ColorPEMA_Digit_Tm_Plus - EA MetaTrader 5

Example of DST Start

(the non-existing hour)

In the United States, DST always begins at 02:00 (2 am) local time. The moment when the time first reaches 1:59:59 standard time, the clocks jump forward to 3:00:00 Daylight Saving Time. So the hour from 2:00:00 to 2:59:59 does not exist in the night of the switch.



II. Get Timezone Information

1. UTC offset and current DST offset

Let us see an example to show how we can get the timezone name, UTC offset, and current DST offset if DST is in effect.

   Print("\n========== UTC offset and current DST offset ==========");

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      CTimeZoneInfo tz(id);
      tz.RefreshTime(); // populate current timezone information

      PrintFormat("%-12s: GMT%+g | DST%+g", tz.Name(), tz.TimeGMTOffset()/3600., tz.TimeDaylightSavings()/3600.);
     }

output:

   // ========== UTC offset and current DST offset ==========
   // Sydney      : GMT+10 | DST+1
   // Tokyo       : GMT+9 | DST+0
   // Frankfurt   : GMT+1 | DST+0
   // London      : GMT+0 | DST+0
   // New York    : GMT-5 | DST+0
   // UTC         : GMT+0 | DST+0
   // Home        : GMT+2 | DST+0
   // FXOpen-MT5  : GMT+2 | DST+0

Note: The TimeGMTOffset() method in this library returns the timezone UTC offset in seconds. The UTC offset is positive if the timezone is east of GMT, and it is negative if the timezone is west of GMT.


2. DST switch times for the current year

Let us see an example to show how we can get the DST information.

   Print("\n========== DST switch times for the current year ==========");

   datetime dst_start, dst_end;

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      CTimeZoneInfo tz(id);
      tz.RefreshTime(); // populate current timezone information

      //--- only for time zones that observe daylight time.
      if(tz.GetDaylightSwitchTimes(dst_start, dst_end))
        {
         PrintFormat("%-12s:  DST starts on %s |  DST ends on %s", tz.Name(), TimeToString(dst_start), TimeToString(dst_end));
        }
     }

output:

   // ========== DST switch times for the current year ==========
   // Sydney      :  DST starts on 2024.04.07 03:00 |  DST ends on 2024.10.06 02:00
   // Frankfurt   :  DST starts on 2024.03.31 02:00 |  DST ends on 2024.10.27 03:00
   // London      :  DST starts on 2024.03.31 01:00 |  DST ends on 2024.10.27 02:00
   // New York    :  DST starts on 2024.03.10 02:00 |  DST ends on 2024.11.03 02:00


3. Time of the next DST switch

Let us see an example to show how we can get the time of the next DST switch.

   Print("\n========== Time of the next DST switch ==========");

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      CTimeZoneInfo tz(id);
      tz.RefreshTime();

      datetime nxswitch = tz.GetDaylightNextSwitch();

      //--- only for time zones that observe daylight time.
      if(nxswitch)
        {
         PrintFormat("%-12s:  Time: %s |  dstNextSwitch: %s", tz.Name(), TimeToString(tz.TimeLocal()), TimeToString(nxswitch));
        }
     }

output:

   // ========== Time of the next DST switch ==========
   // Sydney      :  Time: 2024.02.28 21:58 |  dstNextSwitch: 2024.04.07 03:00
   // Frankfurt   :  Time: 2024.02.28 11:58 |  dstNextSwitch: 2024.03.31 02:00
   // London      :  Time: 2024.02.28 10:58 |  dstNextSwitch: 2024.03.31 01:00
   // New York    :  Time: 2024.02.28 05:58 |  dstNextSwitch: 2024.03.10 02:00


4. DST List

Let us see an example to show how we can get the DST information for all timezones in this library for a range of years.

   Print("\n========== DST List ==========");

   datetime dst_start, dst_end;
   int delta_start, delta_end;  // clock changes in sec

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      CTimeZoneInfo timezone(id);

      PrintFormat("========= %s Summer Time (DST) =========", timezone.Name());
      for(int year=2008; year<=2030; year++)
        {
         //--- only for time zones that observe daylight time.
         if(CTimeZoneInfo::GetDaylightSwitchTimes(id, year, dst_start, dst_end))
           {
            CTimeZoneInfo::GetDaylightSwitchDeltas(id, year, delta_start, delta_end);

            PrintFormat("DST starts on %s (%+d) and ends on %s (%+d)",TimeToString(dst_start), delta_start/3600, TimeToString(dst_end), delta_end/3600);
           }
        }

     }

output:

   // ========== DST List ==========
   // ========= Sydney Summer Time (DST) =========
   // DST starts on 2008.04.06 03:00 (-1) and ends on 2008.10.05 02:00 (+1)
   // DST starts on 2009.04.05 03:00 (-1) and ends on 2009.10.04 02:00 (+1)
   // DST starts on 2010.04.04 03:00 (-1) and ends on 2010.10.03 02:00 (+1)
   // DST starts on 2011.04.03 03:00 (-1) and ends on 2011.10.02 02:00 (+1)
   // DST starts on 2012.04.01 03:00 (-1) and ends on 2012.10.07 02:00 (+1)
   // ...
   // ...
   // ...



III. Converting Between Timezones

Convert current local time to another timezone

Use the ConvertLocalTime() method to convert the set local time of this timezone instance to a specific timezone. This method returns a new time of a given timezone.

Let us see an example to show how we can convert the “current” local time to a specific timezone.

   Print("\n========== Convert current local time in Sydney to New York ==========");

   CTimeZoneInfo sydney(ZONE_ID_SYDNEY);
   sydney.RefreshTime();

   datetime localtime = sydney.TimeLocal();
   datetime converted = sydney.ConvertLocalTime(ZONE_ID_NEWYORK);

   PrintFormat("%s | %s", TimeToString(localtime), sydney.ToString());
   PrintFormat("%s | %s", TimeToString(converted), CTimeZoneInfo::FormatTimeForPlace(converted, ZONE_ID_NEWYORK));

output:

   // ========== Convert current local time in Sydney to New York ==========
   // 2024.02.28 21:58 | Wed, 2024.02.28 21:58:50 GMT+11 [Sydney] (DST)
   // 2024.02.28 05:58 | Wed, 2024.02.28 05:58:50 GMT-5 [New York]


Convert a specific local time to another timezone

Let us see an example to show how we can convert a specific local time to a specific timezone.

   Print("\n========== Convert a specific local time in Sydney to New York ==========");

   CTimeZoneInfo sydney(ZONE_ID_SYDNEY);
   sydney.SetLocalTime(D'2016.05.21 14:47:08');

   datetime localtime = sydney.TimeLocal();
   datetime converted = sydney.ConvertLocalTime(ZONE_ID_NEWYORK);

   PrintFormat("%s | %s", TimeToString(localtime), sydney.ToString());
   PrintFormat("%s | %s", TimeToString(converted), CTimeZoneInfo::FormatTimeForPlace(converted, ZONE_ID_NEWYORK));

output:

   // ========== Convert a specific local time in Sydney to New York ==========
   // 2016.05.21 14:47 | Sat, 2016.05.21 14:47:08 GMT+10 [Sydney]
   // 2016.05.21 00:47 | Sat, 2016.05.21 00:47:08 GMT-4 [New York] (DST)


Convert the current local time in all timezones to the broker time

Let us see an example to show how we can convert the current local time in all timezones to the broker time.

   Print("\n========== Convert the current local time in all timezones to the broker time ==========");

   for(ENUM_ZONE_ID id=0; id <= MAX_ZONE_ID; id++)
     {
      datetime localtime = CTimeZoneInfo::GetCurrentTimeForPlace(id);
      datetime converted = CTimeZoneInfo::ConvertTimeForPlace(localtime, id, ZONE_ID_BROKER);

      PrintFormat("%-49s | %s", CTimeZoneInfo::FormatTimeForPlace(localtime, id), CTimeZoneInfo::FormatTimeForPlace(converted, ZONE_ID_BROKER));
     }

output:

   // ========== Convert the current local time in all timezones to the broker time ==========
   // Wed, 2024.02.28 21:58:50 GMT+11 [Sydney] (DST)    | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 19:58:50 GMT+9 [Tokyo]            | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 11:58:50 GMT+1 [Frankfurt]        | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 10:58:50 GMT+0 [London]           | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 05:58:50 GMT-5 [New York]         | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 10:58:50 GMT+0 [UTC]              | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 12:58:50 GMT+2 [Home]             | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]
   // Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]       | Wed, 2024.02.28 12:58:50 GMT+2 [FXOpen-MT5]



IV. Working with Local Session Hours

A. CTimeZoneInfo Class

Note that using the parent CTimeZoneInfo class, rather than CSessionHours class, is not preferred as it requires more coding and therefore prone to errors. Let us see an example to show how we get the Forex session hours in all timezones, and convert them to the broker’s time.

   Print("\n======= Local Session Hours (CTimeZoneInfo Class) =======");

   const ENUM_ZONE_ID ids[] = {ZONE_ID_SYDNEY, ZONE_ID_TOKYO, ZONE_ID_FRANKFURT, ZONE_ID_LONDON, ZONE_ID_NEWYORK};

   for(int i = 0; i < ArraySize(ids); i++)
     {
      ENUM_ZONE_ID id = ids[i];

      CTimeZoneInfo tz(id);
      tz.RefreshTime();

      datetime localtime = tz.TimeLocal();

      //--- set session hours to 8:00 am - 5:00 pm local time
      datetime beginlocal = StringToTime(TimeToString(localtime, TIME_DATE) + " " + "08:00");
      datetime endlocal   = StringToTime(TimeToString(localtime, TIME_DATE) + " " + "17:00");

      //--- conversion to broker time
      tz.SetLocalTime(beginlocal);
      datetime beginbroker = tz.ConvertLocalTime(ZONE_ID_BROKER);

      tz.SetLocalTime(endlocal);
      datetime endbroker = tz.ConvertLocalTime(ZONE_ID_BROKER);

      //--- local day of week in timezone
      MqlDateTime st;
      TimeToStruct(localtime, st);
      int dow = st.day_of_week;

      //string state_str = ((dow != SATURDAY && dow != SUNDAY) && (localtime >= beginlocal && localtime < endlocal)) ? "open" : "closed";
      string state_str = ((dow != SATURDAY && dow != SUNDAY) && (TimeTradeServer() >= beginbroker && TimeTradeServer() < endbroker)) ? "open" : "closed";

      PrintFormat("%-12s:  %s |  %s  [session %s]", tz.Name(), CTimeZoneInfo::FormatTimeForPlace(beginbroker, ZONE_ID_BROKER), CTimeZoneInfo::FormatTimeForPlace(endbroker, ZONE_ID_BROKER), state_str);
     }

   Print("-----------------------------------");
   Print("broker time :  ", TimeTradeServer());
   Print("broker time :  ", CTimeZoneInfo::FormatTimeForPlace(TimeTradeServer(), ZONE_ID_BROKER));

output:

   // ======= Local Session Hours (CTimeZoneInfo Class) =======
   // Sydney      :  Wed, 2024.02.28 23:00:00 GMT+2 [FXOpen-MT5] |  Thu, 2024.02.29 08:00:00 GMT+2 [FXOpen-MT5]  [session closed]
   // Tokyo       :  Wed, 2024.02.28 01:00:00 GMT+2 [FXOpen-MT5] |  Wed, 2024.02.28 10:00:00 GMT+2 [FXOpen-MT5]  [session closed]
   // Frankfurt   :  Wed, 2024.02.28 09:00:00 GMT+2 [FXOpen-MT5] |  Wed, 2024.02.28 18:00:00 GMT+2 [FXOpen-MT5]  [session open]
   // London      :  Wed, 2024.02.28 10:00:00 GMT+2 [FXOpen-MT5] |  Wed, 2024.02.28 19:00:00 GMT+2 [FXOpen-MT5]  [session open]
   // New York    :  Wed, 2024.02.28 15:00:00 GMT+2 [FXOpen-MT5] |  Thu, 2024.02.29 00:00:00 GMT+2 [FXOpen-MT5]  [session open]
   // -----------------------------------
   // broker time :  2024.02.28 15:32:30
   // broker time :  Wed, 2024.02.28 15:32:30 GMT+2 [FXOpen-MT5]



B. CSessionHours Class

    Purpose: Class to access the local trading session hours for the specified location.

Alternative:   CCMx - indicator MetaTrader 5

    Derives from class CTimeZoneInfo.

    Note: The default session hours are set to 8:00 am – 5:00 pm local time for new CSessionHours objects. These default values can be overridden as desired.


Working with CSessionHours Objects

Let us see an example of how to use the object.

   Print("\n========== Working with CSessionHours Objects  ==========");

   CSessionHours tz(ZONE_ID_SYDNEY);
   tz.RefreshTime(); // populate timezone and session information

   //--- from parent
   Print("Name()                : ", tz.Name());
   Print("TimeUTC()             : ", tz.TimeUTC());
   Print("TimeLocal()           : ", tz.TimeLocal());
   Print("ToString()            : ", tz.ToString());
   //--- from class
   Print("BeginLocalTime()      : ", tz.BeginLocalTime());
   Print("EndLocalTime()        : ", tz.EndLocalTime());
   Print("CheckLocalSession()   : ", tz.CheckLocalSession());
   Print("SecRemainingSession() : ", tz.SecRemainingSession());
   Print("SecondsToString()     : ", CSessionHours::SecondsToString(tz.SecRemainingSession()));

output:

   // ========== Working with CSessionHours Objects  ==========
   // Name()                : Sydney
   // TimeUTC()             : 2024.02.28 10:58:50
   // TimeLocal()           : 2024.02.28 21:58:50
   // ToString()            : Wed, 2024.02.28 21:58:50 GMT+11 [Sydney] (DST)
   // BeginLocalTime()      : 2024.02.28 08:00:00
   // EndLocalTime()        : 2024.02.28 17:00:00
   // CheckLocalSession()   : false
   // SecRemainingSession() : 0
   // SecondsToString()     : 00:00:00


Local Session Hours

The CSessionHours provides more functionality with less code. Let us see an example to show how we get the Forex session hours in all timezones using CSessionHours Class, and convert them to the broker’s time. Note that conversion to the broker’s time is an optional step, and it is not required for checking the start and end times of each session

   Print("\n======= Local Session Hours (CSessionHours Class) =======");

   const ENUM_ZONE_ID ids[] = {ZONE_ID_SYDNEY, ZONE_ID_TOKYO, ZONE_ID_FRANKFURT, ZONE_ID_LONDON, ZONE_ID_NEWYORK};

   for(int i = 0; i < ArraySize(ids); i++)
     {
      ENUM_ZONE_ID id = ids[i];

      CSessionHours tz(id);
      tz.RefreshTime();

      //--- default session hours are set to 8:00 am - 5:00 pm local time
      datetime beginlocal = tz.BeginLocalTime();
      datetime endlocal   = tz.EndLocalTime();

      //--- conversion to broker time
      datetime beginbroker = CTimeZoneInfo::ConvertTimeForPlace(beginlocal, id, ZONE_ID_BROKER);
      datetime endbroker = CTimeZoneInfo::ConvertTimeForPlace(endlocal, id, ZONE_ID_BROKER);

      string state_str = tz.CheckLocalSession() ? "open, ends in " + CSessionHours::SecondsToString(tz.SecRemainingSession()) : "closed";

      PrintFormat("%-12s:  %s |  %s  [session %s]", tz.Name(), CTimeZoneInfo::FormatTimeForPlace(beginbroker, ZONE_ID_BROKER), CTimeZoneInfo::FormatTimeForPlace(endbroker, ZONE_ID_BROKER), state_str);
     }

   Print("-----------------------------------");
   Print("broker time :  ", TimeTradeServer());
   Print("broker time :  ", CTimeZoneInfo::FormatTimeForPlace(TimeTradeServer(), ZONE_ID_BROKER));
   Print("Fx close    :  ", CTimeZoneInfo::FormatTimeForPlace(CSessionHours::ForexCloseTime(), ZONE_ID_BROKER));
   int sec = CSessionHours::SecRemainingForex();
   Print("closes in   :  ", sec, " sec = ", CSessionHours::SecondsToString(sec));

output:

   // ======= Local Session Hours (CSessionHours Class) =======
   // Sydney      :  Wed, 2024.02.28 23:00:00 GMT+2 [FXOpen-MT5] |  Thu, 2024.02.29 08:00:00 GMT+2 [FXOpen-MT5]  [session closed]
   // Tokyo       :  Wed, 2024.02.28 01:00:00 GMT+2 [FXOpen-MT5] |  Wed, 2024.02.28 10:00:00 GMT+2 [FXOpen-MT5]  [session closed]
   // Frankfurt   :  Wed, 2024.02.28 09:00:00 GMT+2 [FXOpen-MT5] |  Wed, 2024.02.28 18:00:00 GMT+2 [FXOpen-MT5]  [session open, ends in 02:27:29]
   // London      :  Wed, 2024.02.28 10:00:00 GMT+2 [FXOpen-MT5] |  Wed, 2024.02.28 19:00:00 GMT+2 [FXOpen-MT5]  [session open, ends in 03:27:29]
   // New York    :  Wed, 2024.02.28 15:00:00 GMT+2 [FXOpen-MT5] |  Thu, 2024.02.29 00:00:00 GMT+2 [FXOpen-MT5]  [session open, ends in 08:27:29]
   // -----------------------------------
   // broker time :  2024.02.28 15:32:30
   // broker time :  Wed, 2024.02.28 15:32:30 GMT+2 [FXOpen-MT5]
   // Fx close    :  Sat, 2024.03.02 00:00:00 GMT+2 [FXOpen-MT5]
   // closes in   :  203249 sec = 2d 08:27:29


How to override the default local session hours?

Let us see an example to show how we can override the default session hours in CSessionHours Class.

   Print("\n=========== Override the default session hours ===========");

   CSessionHours frankfurt(ZONE_ID_FRANKFURT);

   // change default session times
   frankfurt.BeginLocalTime(9, 0);
   frankfurt.EndLocalTime(19, 0);

   frankfurt.RefreshTime(); // populate new session hours

   datetime beginlocal = frankfurt.BeginLocalTime();
   datetime endlocal   = frankfurt.EndLocalTime();

   PrintFormat("new session hours  :  %s | %s", CTimeZoneInfo::FormatTimeForPlace(beginlocal, ZONE_ID_FRANKFURT), CTimeZoneInfo::FormatTimeForPlace(endlocal, ZONE_ID_FRANKFURT));
   PrintFormat("current local time :  %s", frankfurt.ToString());

output:

   // =========== Override the default session hours ===========
   // new session hours  :  Wed, 2024.02.28 09:00:00 GMT+1 [Frankfurt] | Wed, 2024.02.28 19:00:00 GMT+1 [Frankfurt]
   // current local time :  Wed, 2024.02.28 11:58:50 GMT+1 [Frankfurt]


How to check for closing positions at weekend?

The SecRemainingForex() static method will return the time remaining in seconds till Forex market closes for this week. This method should be called from the OnTick() event handler (or better from OnTimer() in case no ticks are coming just before weekend) to repeatedly check for the closing condition. Let us see an example to show how we can check for closing positions at weekend.

   Print("\n======= Check For Closing Positions at Weekend =======");

   int InpHours   = 2;   // Hours before weekend
   int InpMinutes = 30;  // Minutes before weekend

   int sec = CSessionHours::SecRemainingForex();
   PrintFormat("Time remaining till the weekend : %s", CSessionHours::SecondsToString(sec));
   PrintFormat("Close all if remaining time becomes %s or less.", CSessionHours::SecondsToString(InpHours * 3600 + InpMinutes * 60));

   // check time remaining has reached target
   if(sec <= InpHours * 3600 + InpMinutes * 60)
     {
      // CloseAll();
     }

Alternatively, the previous condition can be checked using absolute times:

   // check broker's time has reached target
   if(TimeTradeServer() >= CSessionHours::ForexCloseTime() - (InpHours * 3600 + InpMinutes * 60))
     {
      // CloseAll();
     }

output:

   // ======= Check For Closing Positions at Weekend =======
   // Time remaining till the weekend : 3d 03:32:27
   // Close all if remaining time becomes 02:30:00 or less.



End of Week – Broker’s Timezone and DST Schedule

The Forex market opens Sunday at 17:00 New York time (GMT-5 in winter and GMT-4 in summer) and closes Friday at the same time. The opening time in NYC corresponds to Sun, 10:00 PM UTC in winter (and Sun, 09:00 PM UTC in summer). Forex closes on Fri, 10:00 PM UTC in winter (and 09:00 PM UTC in summer). Gold and silver spot market usually starts an hour later. link 

Each forex broker has its time zone and server time. Therefore, the start of the trading week (D1 candles) is variable between brokers, and it can vary from Sun, 02:00 PM server time for brokers in San Francisco (GMT-8), up to Mon, 09:00 AM server time for brokers in Sydney (GMT+11). The end of trading week also varies from Fri, 02:00 PM server time, up to Sat, 09:00 AM server time.

Each broker is free to choose their Daylight-saving time (DST). And DST is not necessarily the same for that time zone. Sometimes they mix it using an EU time zone and a US DST instead of the EU DST. For brokers that do not follow the US schedule, the server time for the start (and end) of week varies by +/- one hour for the same broker throughout the year. The ForexCloseTime() method handle these inter- and intra-broker variations by converting the close time in NYC at Fri, 17:00 to broker’s time, taking into consideration the time offsets and DST, thus providing accurate results.

Using a time zone of +2 (and +3 in summer on the US schedule) therefore means that candles each week start at midnight Monday, and there are five D1 candles per week and the start of a daily candle (and H4) is the start of a new FX day. Each week ends just before midnight Saturday. There are no candles on Saturday and Sunday. By far this is the most common setting, but there’s a lot of less common variations.



Sample indicator TestIndi.mq5



Links

World clock: 

Timezone converter: converter-classic.html


📈 ROBOTFX MetaTrader Expert Advisors and Indicators to maximize profits and minimize the risks