Watch how to download trading robots for free
Find us on Facebook!
Join our fan page
Interesting script?
So post a link to it -
let others appraise it
You liked the script? Try it in the MetaTrader 5 terminal
Libraries

Local Timezones and Local Session Hours - library for MetaTrader 5

Views:
12356
Rating:
(12)
Published:
2024.02.28 14:14
Updated:
2025.01.28 05:41
MQL5 Freelance Need a robot or indicator based on this code? Order it on Freelance Go to Freelance

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.


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 terms UTC and GMT are often used interchangeably to express offsets, so UTC+2 and GMT+2 often have the same meaning. 

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


Time Zone Identifiers

//+------------------------------------------------------------------+
//| Time zone identifiers                                            |
//+------------------------------------------------------------------+
enum ENUM_ZONE_ID
  {
   ZONE_ID_SYDNEY,     // Sydney
   ZONE_ID_TOKYO,      // Tokyo
   ZONE_ID_FRANKFURT,  // Frankfurt
   ZONE_ID_LONDON,     // London
   ZONE_ID_NEWYORK,    // New York
   ZONE_ID_UTC,        // UTC
   ZONE_ID_LOCAL,      // LOCAL
   ZONE_ID_BROKER,     // BROKER
   ZONE_ID_CUSTOM      // CUSTOM
  };


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.                           |
//|                                                                  |
//| Offset notation used in the library:                             |
//|          Please note, that the library denotes positive time     |
//|          zones by positive offsets, and negative time zones      |
//|          by negative offsets.                                    |
//|          On the contrary, MQL5's built-in TimeGMTOffset()        |
//|          function denotes positive time zones, such as GMT+3,    |
//|          by negative offsets, such as -10800, and vice versa.    |
//+------------------------------------------------------------------+
class CTimeZoneInfo
  {
public:
                     CTimeZoneInfo( ENUM_ZONE_ID placeId, datetime pLocalTime = TIME_NOW );
                    ~CTimeZoneInfo( void );

   string            Name( void );                                                       // Returns the name of time zone
   string            ToString( bool secs = true, bool tzname = true );                   // Returns a string of local time formatted with TZ/DST offset and tzname
   bool              RefreshTime( void );                                                // Refresh the current local time and populate timezone information
   bool              SetLocalTime( datetime pLocalTime = TIME_NOW );                     // Set the local time for this location to the specified time

   datetime          TimeLocal( void );                                                  // Returns the local time in timezone
   datetime          TimeUTC( void );                                                    // Returns the UTC time (the same in all time zones)
   int               TimeGMTOffset( void );                                              // Positive value for positive timezones (eg, GMT+3), otherwise negative. (includes DST)
   int               TimeDaylightSavings( void );                                        // Returns DST correction (in seconds) for timezone, at the set local time.

   datetime          ConvertLocalTime( ENUM_ZONE_ID destinationId );                     // Convert local time in this time zone to a different time zone
   bool              GetDaylightSwitchTimes( datetime &dst_start, datetime &dst_end );   // Get the Daylight Saving Time start and end times for the year
   datetime          GetDaylightNextSwitch( void );                                      // Get the local time of the next Daylight Saving Time switch
   void              PrintObject( void );

   //--- static methods that do not require the creation of an object.
   static datetime   GetCurrentTimeForPlace ( ENUM_ZONE_ID placeId );                    // Get the current local time for the specified time zone
   static string     FormatTimeForPlace     ( datetime time, ENUM_ZONE_ID placeId, bool secs = true, bool tzname = true );
   static datetime   ConvertTimeForPlace    ( datetime time, ENUM_ZONE_ID placeId, ENUM_ZONE_ID destinationId );
   static int        TimeGMTOffset          ( ENUM_ZONE_ID placeId, datetime time = TIME_NOW );   // Returns total tz offset (UTC+DST) from GMT, for a timezone at given local time
   static int        TimeDaylightSavings    ( ENUM_ZONE_ID placeId, datetime time = TIME_NOW );   // Returns dst correction in seconds, for a timezone at given local time
   static bool       IsDaylightSavingTime   ( ENUM_ZONE_ID placeId, datetime time = TIME_NOW );   // Checks if a specified time falls in the daylight saving time
   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       SetCustomTimeZone( string name, int baseGMTOffset = 0,              // Defines a time zone that is not found in the library.
                                        ENUM_ZONE_ID dstSchedule = ZONE_ID_UTC );
   static void       SetUsingGoldSymbol( bool enabled = true );                          // Sets the option to use Gold symbol for estimation of server TZ/DST
  };


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 );                            // Refresh the current local time and session hours for the day
   bool              SetLocalTime( datetime pLocalTime );

   //--- methods to override default local session hours
   bool              BeginLocalTime( int pHour, int pMinute );       // Set the local session begin time using a begin hour and minute
   bool              EndLocalTime( int pHour, int pMinute );         // Set the local session end time using an end hour and minute

   //--- 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.
  };


Offset Notation Used In The Library

Please note, that the library denotes positive time zones by positive offsets, and negative time zones by negative offsets.

This is the opposite of MQL5's built-in TimeGMTOffset() function which denotes positive time zones, such as GMT+3, by negative offsets, such as -10800, and vice versa.


Selecting The Symbol For Estimation of The Server TZ/DST

By default, the library will search and load the XAUUSD symbol for estimation of server's timezone offset. XAUUSD can provide more reliable results (esp., for brokers that follow EU DST schedule) on weeks during US DST and EU DST schedules are out of sync (March and late October). Optionally, if your broker follows the US DST schedule, or no schedule at all, then using the chart symbol is also fine. Call CTimeZoneInfo::SetUsingGoldSymbol() with 'false' to use the current chart's symbol, instead of XAUUSD.

To determine your broker's daylight (DST) schedule, you can use this script https://www.mql5.com/en/code/48650

//+------------------------------------------------------------------+
//| Sets the option of using XAUUSD (Gold) symbol to estimate the    |
//| server's TZ/DST by analysis of H1 quotes history.                |
//| TRUE  : search for and load Gold symbol (default behavior).      |
//| FALSE : use the symbol of the current chart.                     |
//+------------------------------------------------------------------+
void CTimeZoneInfo::SetUsingGoldSymbol(const bool enabled = true);

Note:

As a side effect that XAUUSD starts an hour after Forex, dst switches will occur one hour later (only in the strategy tester, and not in normal mode).


Note about Compatibility with The Strategy Tester

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

TimeZoneInfo library estimates the proper times in time zones based on the "true" GMT by analysis of H1 quotes history, and not based on the time returned by calling built-in TimeGMT function.

If the XAUUSD symbol is used for estimation of the server's TZ/DST, then dst switches will occur one hour later in the strategy tester.



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.03.17 16:50:38
   // TimeLocal()             : 2024.03.17 12:50:38
   // TimeGMTOffset()         : -14400
   // TimeDaylightSavings()   : 3600
   // ToString()              : Sun, 2024.03.17 12:50:38 GMT-4 [New York] (DST)
   // dst_start               : 2024.03.10 02:00:00
   // dst_end                 : 2024.11.03 02:00:00
   // GetDaylightNextSwitch() : 2024.11.03 02:00:00

Notes:

- TimeUTC() method returns the UTC time, which is equivalent to GMT time.

- TimeLocal() method returns the local time of this time zone (which could have been changed as a result of calling RefreshTime or SetLocalTime methods).

- TimeGMTOffset() method returns the current difference between this time zone's local time and GMT time in seconds, taking into account switch to winter or summer time. The returned offset includes the DST adjustment of the current time zone. The GMT offset is positive if the timezone is east of (ahead of) GMT, and it is negative if the timezone is west of (behind) GMT.

- TimeDaylightSavings() method returns the daylight saving time (DST) adjustment in seconds, if the switch to summer time has been made in the zones where DST is in effect. If switch to winter (standard) time has been made (or, if the time zone does not support DST), it returns 0. The dst adjustment is already part of the the TimeGMTOffset.


How to configure the built-in custom timezone for later use?

The CTimeZoneInfo class includes a SetCustomTimeZone method, which you can use to configure the built-in custom time zone. Later, the custom time zone can be used via the ZONE_ID_CUSTOM identifier. Let us see an example to show how we can configure the built-in custom time zone to a specified name, an offset from Greenwich Mean Time (GMT) and a daylight schedule identifier.

   Print("\n========== Configure the built-in custom timezone ==========");

   string        name  = "Custom+3";               // Custom Timezone's name
   int           baseGMTOffset  = 10800;           // Custom Timezone's base GMT offset (in seconds)
   ENUM_ZONE_ID  daylightRuleId = ZONE_ID_LONDON;  // Custom Timezone's DST schedule

   bool success = CTimeZoneInfo::SetCustomTimeZone(name, baseGMTOffset, daylightRuleId);

   Print("Parameter 'name'            : ", name);
   Print("Parameter 'baseGMTOffset'   : ", baseGMTOffset);
   Print("Parameter 'daylightRuleId'  : ", EnumToString(daylightRuleId));
   Print("SetCustomTimeZone() returns : ", success);

Output:

   // ========== Configure the built-in custom timezone ==========
   // Parameter 'name'            : Custom+3
   // Parameter 'baseGMTOffset'   : 10800
   // Parameter 'daylightRuleId'  : ZONE_ID_LONDON
   // SetCustomTimeZone() returns : true


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 https://www.timeanddate.com/time/dst/transition.html

("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.


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+11 | DST+1
   // Tokyo       : GMT+9 | DST+0
   // Frankfurt   : GMT+1 | DST+0
   // London      : GMT+0 | DST+0
   // New York    : GMT-4 | DST+1
   // UTC         : GMT+0 | DST+0
   // Home        : GMT+2 | DST+0
   // FXOpen-MT5  : GMT+2 | DST+0

Notes:

- TimeGMTOffset() method returns the current difference between this time zone's local time and GMT time in seconds, taking into account switch to winter or summer time. The returned offset includes the DST adjustment of the current time zone. The GMT offset is positive if the timezone is east of (ahead of) GMT, and it is negative if the timezone is west of (behind) GMT.

- TimeDaylightSavings() method returns the daylight saving time (DST) adjustment in seconds, if the switch to summer time has been made in the zones where DST is in effect. If switch to winter (standard) time has been made (or, if the time zone does not support DST), it returns 0. The dst adjustment is already part of the the TimeGMTOffset.


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)
   // ...
   // ...
   // ...

5. Server GMT Offset (Current)

The broker's GMT offset indicates how many seconds the broker time is ahead of GMT, broker offset = TimeTradeServer() - TimeGMT(). Positive values indicates that the server time is ahead of GMT. Let us see an example to show how we can get the current GMT offset of the broker.

   Print("\n========== Current GMT offset of the broker ========== ");

   CTimeZoneInfo broker(ZONE_ID_BROKER);
   broker.RefreshTime();

   Print("Name()          : ", broker.Name());
   Print("TimeLocal()     : ", broker.TimeLocal());  // broker time
   Print("ToString()      : ", broker.ToString());
   Print("TimeGMTOffset() : ", broker.TimeGMTOffset());

output:

   // ========== Current GMT offset of the broker ==========
   // Name()          : ICMarketsSC-Demo
   // TimeLocal()     : 2024.03.08 06:33:06
   // ToString()      : Fri, 2024.03.08 06:33:06 GMT+2 [ICMarketsSC-Demo]
   // TimeGMTOffset() : 7200

Note: An important note for the TimeGMTOffset() is that it will return the utc offset including dst correction (UTC+DST). Positive values indicates that the server time is ahead (east) of GMT.


6. Server GMT offset (Historical)

Past GMT offsets of the server can be calculated as the difference between the time of appearance of the first bar of the server week on the chart, and the UTC time corresponding to Sunday 5 PM, New York time. Let us see an example to show how we can get the past GMT offsets of the broker. For this example, we will use times of chart candles as past time of the broker.

   Print("\n========== Past GMT offsets of the broker (chart candles) ==========");

   datetime bartimes[];
   int copied = CopyTime(Symbol(), PERIOD_D1, D'2022.03.18', 9, bartimes);
   if(copied<=0)
      Print("CopyTime() failed.");

   for(int i =0; i < copied; i++)
     {
      datetime t = bartimes[i];

      CTimeZoneInfo broker(ZONE_ID_BROKER);
      broker.SetLocalTime(t);

      PrintFormat("bar #%i  Time: %s |  offset: %5d (GMT%+g) |  %s",
                  i+1,
                  TimeToString(broker.TimeLocal()),
                  broker.TimeGMTOffset(),
                  broker.TimeGMTOffset()/3600.0,
                  broker.ToString());
     }

output:

   // ========== Past GMT offsets of the broker (chart candles) ==========
   // bar #1  Time: 2022.03.08 00:00 |  offset:  7200 (GMT+2) |  Tue, 2022.03.08 00:00:00 GMT+2 [ICMarketsSC-Demo]
   // bar #2  Time: 2022.03.09 00:00 |  offset:  7200 (GMT+2) |  Wed, 2022.03.09 00:00:00 GMT+2 [ICMarketsSC-Demo]
   // bar #3  Time: 2022.03.10 00:00 |  offset:  7200 (GMT+2) |  Thu, 2022.03.10 00:00:00 GMT+2 [ICMarketsSC-Demo]
   // bar #4  Time: 2022.03.11 00:00 |  offset:  7200 (GMT+2) |  Fri, 2022.03.11 00:00:00 GMT+2 [ICMarketsSC-Demo]
   // bar #5  Time: 2022.03.14 00:00 |  offset: 10800 (GMT+3) |  Mon, 2022.03.14 00:00:00 GMT+3 [ICMarketsSC-Demo]
   // bar #6  Time: 2022.03.15 00:00 |  offset: 10800 (GMT+3) |  Tue, 2022.03.15 00:00:00 GMT+3 [ICMarketsSC-Demo]
   // bar #7  Time: 2022.03.16 00:00 |  offset: 10800 (GMT+3) |  Wed, 2022.03.16 00:00:00 GMT+3 [ICMarketsSC-Demo]
   // bar #8  Time: 2022.03.17 00:00 |  offset: 10800 (GMT+3) |  Thu, 2022.03.17 00:00:00 GMT+3 [ICMarketsSC-Demo]
   // bar #9  Time: 2022.03.18 00:00 |  offset: 10800 (GMT+3) |  Fri, 2022.03.18 00:00:00 GMT+3 [ICMarketsSC-Demo]

As, you see at bar #5, the server has switched from +2 winter time to +3 summertime, and the time of the switch follows the US DST schedule (2nd Sunday of March). There are five D1 candles per week, and no candles on Saturday and Sunday. The time on these servers is always 7 hours ahead of New York throughout the year and represented as NY+7. Note that NY is -5 in winter, and -4 in summer.

This is the first library on the codebase capable of determining the server's GMT offset in the past (historical GMT offsets). The algorithm implemented in calculations is very fast and accurate, and it is compatible - as much as possible - with different brokers (tested on a large number of brokers with different GMT offsets or DST schedules).



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.

    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 (H1 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 there are five D1 candles per week. There are no candles on Saturday and Sunday throughout the year. Simply, time on these servers is always 7 hours ahead of New York and represented as NY+7. By far this is the most common setting, but there's a lot of less common variations.



Sample indicator TestIndi.mq5


iForexSessions - indicator for MetaTrader 5

Highlights the Forex Market Sessions

Get it here https://www.mql5.com/en/code/48842


Links

World clock: https://www.timeanddate.com/worldclock/

Timezone converter: https://www.timeanddate.com/worldclock/converter-classic.html


Updates:

2024.03.01 - v.1.40 : Removed redundant code in CTimeZoneInfo class (used during testing), added more methods to CSessionHours class, updated TestIndi.mq5 to reflect the new changes.

2024.03.03 - v.1.45 : Updated the example code for "Working with Local Session Hours - CTimeZoneInfo Class".

2024.03.08 - v.1.50 : Added two internal methods HistoryBrokerOffset and FirstBarOfWeek to CTimeZoneInfo class. Handling of server time in the past (UTC offset, text formatting, conversions, etc..).

2024.03.15 - v.1.56 : Added script "SydneySession_Script.mq5" to to show how the session hours in Sydney are fluctuating throughout the year.

2024.03.30 - v.1.65 : Fixed broker GMT offset. Currently, the library scans H1 bars only on the GOLD chart as it has the most accurate start times on all brokers that I have tested.

2024.04.01 - v.1.67 : Fixed potential issue in the calculation of the broker GMT offset during the first hour of the trading week.

2024.04.03 - v.1.70 : Caching of broker GMT offsets into a hash map for faster retrieval (e.g., from indicators). The broker offset cache will contain one entry per trading week.

2024.04.08 - v.1.72 : Improved the performance of the library by at least 2-3x times. Now using StructToTime instead of StringToTime inside the GetNthSunday method.

2024.04.09 - v.1.75 : Fixed potential issue in the calculation of the broker GMT offset during the Christmas holidays on GMT+0 brokers.

2024.04.11 - v.1.77 : Speed-up of the GetDaylightSwitchTimes mehod. Now using a static array to memorize the switch times for the current year.

2024.04.12 - v.1.80 : Fixed issue in the calculation of the broker GMT offset on brokers that do not provide gold trading.

2024.04.15 - v.1.82 : Added SetCustomTimeZone method to CTimeZoneInfo class, which you can use to configure the built-in custom time zone with a specified name, GMT offset and DST identifier. The custom time zone can be accessed via ZONE_ID_CUSTOM.

2024.04.16 - v.1.85 : Replaced the GetNthSunday internal method with the more optimized GetMonthTime method.

2024.04.17 - v.1.87 : Replaced the TimeYear internal method with the more optimized GetYear method.

2024.04.18 - v.1.88 : Added the CreateDateTime internal method to construct datetime values from date components (year, month and day). This is 100-120x times faster than calling the StructToTime function.

2024.10.21 - v.1.90 : Improved detection of the GOLD symbol with fallback to EURUSD symbol.

2024.10.22 - v.1.93 : Faster determination of the server's GMT offset during weekend in live trading.

2024.10.26 - v.1.95 : Added two new static methods: TimeGMTOffset() and TimeDaylightSavings(). Renamed the HistoryBrokerOffset() method to TimeServerGMTOffset().

2024.10.28 - v.1.97 : Converted all macros for dealing with time to functions to avoid double evaluation of parameters inside macro body. More code clean-up in other lines.

2024.10.30 - v.1.98 : Fixed issue of wrong estimation of GMT offset from XAUEUR quotes on some brokers.

2024.11.01 - v.1.99 : Added an option to switch off the default loading of Gold symbol for estimation of the server's TZ/DST. Call CTimeZoneInfo::SetUsingGoldSymbol() with 'false' to use the current chart's symbol, instead.

2024.11.13 - v.2.00 : Improved estimation of online server tz/dst and in the strategy strategy (TimeGMT library is no longer needed). Constructor accepts place and time parameters. New public methods for working with data of datetime type. Improved error handling and debugging support.

2024.11.14 - v.2.02 : Fixed error ERR_HISTORY_NOT_FOUND (4401) when trying to access the XAUUSD,H1 quotes history by the server timezone object.

2024.11.17 - v.2.03 : Minor bug fixes.

2024.11.23 - v.2.04 : Minor improvements and bug fixes.

2024.12.05 - v.2.05 : Added new static method DaylightSavingsSupported(placeId).

2024.12.12 - v.2.10 : Improved performance of HistoryServerGMTOffset() and HistoryServerDaylightSavings() functions, and other minor code changes.

2024.12.14 - v.2.11 : Improved performance of FindSymbol() function.

2024.12.17 - v.2.12 : Further optimization of HistoryServerGMTOffset() and HistoryServerDaylightSavings() functions.

2024.12.24 - v.2.13 : Fixed potential issue in HistoryServerGMTOffset() and HistoryServerDaylightSavings() functions.

2025.01.12 - v.2.15 : Fixed issue in HistoryServerDaylightSavings() of searching for quotes history earlier than the loaded history in the strategy tester.



Class For Working With Databases In A Simplified Manner Class For Working With Databases In A Simplified Manner

easydatabase

Developing a multi-currency Expert Advisor — source codes from a series of articles Developing a multi-currency Expert Advisor — source codes from a series of articles

The source codes written during the development of the library for creating multi-currency Expert Advisors that combine many instances of various trading strategies.

Examples from the book "Neural networks for algorithmic trading with MQL5" Examples from the book "Neural networks for algorithmic trading with MQL5"

The book "Neural networks in algorithmic trading with MQL5" is a comprehensive guide, covering both the theoretical foundations of artificial intelligence and neural networks and practical aspects of their application in financial trading using the MQL5 programming language.

Intraday Currencies Performance Intraday Currencies Performance

A simple observatory of individual currencies.