Discussion of article "Dealing with Time (Part 2): The Functions" - page 2

 
Carl Schreiber #:

From GMT (=UTC) the time diff is 0900 hours (from https://www.worldtimeserver.com/current_time_in_JP.aspx?city=Tokyo)

= 9*-3600=32400 seconds:

And this is is set:

Mistake that I made. It's not tokyo but sydney.


 
It could be that the calculation of the Australian DST switch is faulty - I'll look into it, thanks.
Time Zones - WorldTimeServer.com
  • www.worldtimeserver.com
A list of all worldwide time zones with abbreviation and name. Click on a time zone to see more details.
 

Australian First Sunday of October at 02:00 to First Sunday of April at 02:00

Australian DST 2010 start 2010.10.03 - end 2010.04.04
Australian DST 2011 start 2011.10.02 - end 2011.04.03
Australian DST 2012 start 2012.10.07 - end 2012.04.01
Australian DST 2013 start 2013.10.06 - end 2013.04.07
Australian DST 2014 start 2014.10.05 - end 2014.04.06
Australian DST 2015 start 2015.10.04 - end 2015.04.05
Australian DST 2016 start 2016.10.02 - end 2016.04.03
Australian DST 2017 start 2017.10.01 - end 2017.04.02
Australian DST 2018 start 2018.10.07 - end 2018.04.01
Australian DST 2019 start 2019.10.06 - end 2019.04.07
Australian DST 2020 start 2020.10.04 - end 2020.04.05
Australian DST 2021 start 2021.10.03 - end 2021.04.04
Australian DST 2022 start 2022.10.02 - end 2022.04.03
Australian DST 2023 start 2023.10.01 - end 2023.04.02
Australian DST 2024 start 2024.10.06 - end 2024.04.07
Australian DST 2025 start 2025.10.05 - end 2025.04.06
Australian DST 2026 start 2026.10.04 - end 2026.04.05
Australian DST 2027 start 2027.10.03 - end 2027.04.04
Australian DST 2028 start 2028.10.01 - end 2028.04.02
Australian DST 2029 start 2029.10.07 - end 2029.04.01

Australia & New Zealand End DST
Australia & New Zealand End DST
  • www.timeanddate.com
People in New Zealand and parts of Australia will get an additional hour to enjoy when Daylight Saving Time (DST) ends on Sunday, April 2, 2023.
 

I found the problem: I missed a check:

At the beginning of the function void checkTimeOffset(datetime tB) I placed a check:

if(tB < nxtSwitch_USD && tB < nxtSwitch_EUR)
      return;  

And this I had to change to:

if(tB < nxtSwitch_USD && tB < nxtSwitch_EUR && tB < nxtSwitch_AUD)
      return;  

I'll update it ...

 
Carl Schreiber #:

I found the problem: I missed a check:

At the beginning of the function void checkTimeOffset(datetime tB) I placed a check:

And this I had to change to:

I'll update it ...

Hi Carl, Unfortunately changing the corresponding code doesn't fix the issue. I also found that Moscow time is different from universal time.


 

The version of DealingWithTime.mqh v. 1.01 of the article Dealing with Time (Part 2): The Functions ( https://www.mql5.com/en/articles/9929 ) stopped working because MQ changed the behavior of the CopyTime() function some Time after publication of this article. Now this function no longer returns future time values if they are greater than TimeCurrent() specified for the start_time and/or stop_time parameters. Instead, the open time of the last, current bar is returned as the largest possible value.

Since the end of the FX session was determined in this way in order to determine the broker time offset, this now leads to incorrect values!

This calculation was changed in version 2.03. This version is now available in the CodeBase here: https://www.mql5.com/en/code/45287 .

But also the calculation of the time change was completely changed, so that now the complicated times of the time change from Sydney (Australia) back to the 70s are covered.

Also attached is the table DST 1975 - 2030.xlsx as a zip file with all the time changes since the 70's so everyone can check the correct working of the formulas, here is an example series of the table:

January 1, 1982 is standard time in the USA (DST==0) and the next changeover will be on April 25, 1982, the last (25th of the month) Sunday in April (4). The table is already sorted by geographic time zone (column A), then by time zone of the year (column L, spr=spring, aut=autumn,) and finally by query date (column C). The table can be created automatically by the included EA (a script cannot be run in debug mode). Test_DST 2.mq5 if you run it in debug mode and copy the lines of the journal log in the debugger and paste them into a spreadsheet; The cell separator would be the space.

Also, there is now a new, simple function SecTillClose() , which gives you the remaining time in seconds (the time currency of MQ) until the forex market is closed - without CopyTime() . This is interesting for those who want to close their positions before the weekend or do not want to open a new position in a defined period before the weekend.

The included indicator DealingWithTime_TestIndi.mq5, as a comment on the chart, shows not only daylight saving time in Europe, the USA and Australia (Sydney), but also the current time and the time difference of various cities. Here you can find a table with different local times of major cities for comparison: https://www.timeanddate.com/worldclock/ . You can therefore check the values at any time. This indicator also shows how these values are determined and used (what is subtracted or added from what), making it easier to use yourself - copy and paste, the fastest form of programming.

The last two lines also show the last second of the current FX session and the remaining time in hours (which is easier to judge) and in seconds. In New York, when the FX session closes at 5:00 pm local time on a Friday, there is no valid bar open at 5:00 pm New York time. Therefore, in this function, 1 second is subtracted to get the last valid open time of the last bar in the broker time. However, some brokers end their FX session a few minutes early by no longer providing prices and no longer accepting trade orders.


Dealing with Time (Part 2): The Functions
Dealing with Time (Part 2): The Functions
  • www.mql5.com
Determing the broker offset and GMT automatically. Instead of asking the support of your broker, from whom you will probably receive an insufficient answer (who would be willing to explain a missing hour), we simply look ourselves how they time their prices in the weeks of the time changes — but not cumbersome by hand, we let a program do it — why do we have a PC after all.
 

Hi @Anil Varma

I read the last post of the author @Carl Schreiber about CopyTime() function but since I'm finding more understandable the 1st version I'm still using  DealingWithTime.mqh v. 1.01.

In my indicator I want to:

Assign NY raw time seconds), NY hour and NY minute to each bar using the following buffers in order to displaying them in the data window:
double      NyRawTimeBuffer[];
double      NyHourBuffer[];
double      NyMinuteBuffer[];
 void AssignNyTime (const datetime& time[],int rates_total)
   {
      
      MqlDateTime dT_struc;
      
      //--- Assign too each candle: NY raw Time (in seconds), NY hour, NY min
      ArraySetAsSeries(time,true);
      for(int z=0;z<rates_total;z++)
         { 
            checkTimeOffset(time[z]);                   // check changes of DST
            datetime tC, tGMT, tNY;
            tC    = time[z];
            tGMT  = time[z] + OffsetBroker.actOffset;   // GMT
            tNY   = tGMT - (NYShift+DST_USD);           // time in New York
            int j = int (tNY);                          // casting datetime to int 
            NyRawTimeBuffer[z]=j;
            
            TimeToStruct(tNY,dT_struc);
            NyHourBuffer[z]=dT_struc.hour;
            NyMinuteBuffer[z]=dT_struc.min;
 
         }        
       
   return;
   }

The function works just when the timeframe chart where the terminal starts it's set to H1.

If I close the terminal and the timeframe is set to let's say M5, and then I restart the terminal it gives me the following error:

2024.02.18 15:33:38.048 MyFractals_V4 (EURUSD,M5) 240: CopyTime() FAILED for EURUSD H1: need times from 2024.02.12 02:00:00, but there are only from 1970.01.01 00:00:00 error: 4401

You already suggested me through messaging to use CheckLoadHistory() from this article ( https://www.mql5.com/en/code/1251 ) and placing it before CopyXXXX() function in your library:

//--- find the broker offset
    OffsetBroker.set = false;
    
    CheckLoadHistory("EURUSD",PERIOD_H1,TERMINAL_MAXBARS,true);
      
    b = CopyTime("EURUSD",PERIOD_H1,BegWk+26*3600,5,arrTme);      // get time last 1h bar before switch in EU

But the issue is still there.

In the checkhistory.mqh (row 19) I noted the following comment but I don't understand if it could be an issue. I tried to comment it ad test the program again but did not work.

//--- don't ask for load of its own data if it is an indicator
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol) return(true);

Is there a way to adjust the bug without to switch to the updated library DealingWithTimeV2.03.mqh without to re-write all the code?




CheckHistory - Check and load history function
CheckHistory - Check and load history function
  • www.mql5.com
Slightly modified history load function from MetaQuotes.
 
Nauris Zukas #:

Hello,

As I understand from the article, the function "setBokerOffset ()" should work in the strategy tester as well, but it doesn't work.


Does the "The Alternative using it via Input Variables" the only way to get correct times in the strategy tester?

Hi

I have tried to modify the code as below and so far it is working for me. Note that I have converted the Class with constructors and all methods are part of class. Class needs to be called in and initialized in your EA/Strategy Class.

CDealWithTime.OnTick() should be placed in EA/Strategy OnTick()

//+-----------------------------------------------------------------------------------------------------------------------------+
//| function to determin broker offset for the time given (tB)
//+-----------------------------------------------------------------------------------------------------------------------------+
void CDealWithTime::OnTick(void) {

                string vMethod = __FUNCTION__ + " Line[" + (string)__LINE__ + "] ";

                // Perform Hourly update of TimeH01[]
                if(IsNewBarH01()) {
      // ... BegWk = BoW(tC), Original code
                        datetime weekBegin = BoW(TimeCurrent());
                        // Original code added 5 bars to WeakBegin Time.
                        // Adding 5 days * 3600 secondsInHour to weak begin time, is not equal to five bars, as there may not be bars on
                        // weekend/holiday. Hence WeekBegin+5*3600 may result a time while there is no bar on it.
                        int                      barShift  = iBarShift(mSymbol,mTimeFrame,weekBegin+(5*3600));
                        // Will return first available bar at Time(weekBegin+(5*3600)
                        datetime timeStop        = iTime(mSymbol,mTimeFrame,barShift);          // Last One Hour bar of Friday, before switch in EU.
                        // Result when seconds added (weekBegin)+(5*3600): CDealWithTime::OnTick Line[229] : GetLastError[0] copiedTime EURUSD-PERIOD_H1 for [0] bars weekBegin[2024.01.01 02:00] to timeStop[2023.12.31 21:00] time5th[2023.12.29 23:00]
                        int bars = Bars(mSymbol,mTimeFrame,weekBegin,timeStop);

                        // We need while..loop, as IsNewBarH01() will be checked only once on the Tick, if true then untill next new bar no further check
                        ResetLastError();
                        int attempt = 0;
                        while(CopyTime(mSymbol,mTimeFrame,weekBegin,timeStop,TimeH01) != bars && attempt <= 10) {
                                Sleep(100);
                                attempt++;
                        }
                        if(attempt > 0) {
                                PrintFormat("%s: GetLastError[%i] copiedTime %s-%s for [%i] bars weekBegin[%s] to timeStop[%i][%s]",vMethod,GetLastError(),mSymbol,EnumToString(mTimeFrame),bars,TimeToString(weekBegin),barShift,TimeToString(timeStop));
                        }
                }

                // Perform a weekly check, if there is change in Day Light Saving Times (DST)
                if(IsNewBarW01()) {
                        checkTimeOffset(TimeCurrent());
                        int  attempt  = 0;
                        bool isOffset = false;
                        do{
                                isOffset = setBokerOffset();
                                attempt++;
                        } while(!isOffset && attempt <= 10);
                }

} // End of OnTick()
 
amrali #:

This code calculates the DST automatically for European and US brokers:

https://www.mql5.com/en/code/27860

The above code was used in Forex Market Hours https://www.mql5.com/en/code/27771 to calculate the day-light saving time changes.

Similar functions can be constructed for different areas of the world.

Hi Amrali

Nice and simple code as an alternative to DealingWithTime v2.03 article. Will look into it for more detailed study.

 
Daniel K #:
DealingWithTime.mqh v. 1.01.

Hi Daniel

DealingWithTime.mqh v. 1.01. This article and its code does not work any more due to changes in MQL calculation methods, as explained by Carl in DealingWithTime.mqh v 2.03 article https://www.mql5.com/en/code/45287

You should not be using it at all.

Dealing with time (2) functions
  • www.mql5.com
Calculate DST for USA, EUR, AUD and RUB and the offset time of the broker automatically from the 70's until 2030 - even in the Strategy Tester of MQ.