Libraries: Dealing with time (2) functions

 

Dealing with time (2) functions:

Calculate DST for USA, EUR, AUD and RUB and the offset time of the broker from the 70's until 2030 and the automatically even in the Strategy Tester of MQ.

Dealing with time (2) functions

Author: Carl Schreiber

 
Automated-Trading:

Dealing with time (2) functions:

Author: Carl Schreiber

Hi Carl

Please explain me the logic of (> 7200) in while loop at line 245 of DealingWithTime.mqh.

While running code on weekend, I am getting 3600 results for the same,  which is equivalent to One Hour.

2024.02.03 12:29:12.363 iSessionVP (XAUUSD,M15) arrTme[b][2024.02.02 23:00] - arrTme[b-1][2024.02.02 22:00] = [3600] > 7200
2024.02.03 12:29:12.363 iSessionVP (XAUUSD,M15) arrTme[b][2024.02.02 22:00] - arrTme[b-1][2024.02.02 21:00] = [3600] > 7200
2024.02.03 12:29:12.363 iSessionVP (XAUUSD,M15) arrTme[b][2024.02.02 21:00] - arrTme[b-1][2024.02.02 20:00] = [3600] > 7200
2024.02.03 12:29:12.363 iSessionVP (XAUUSD,M15) arrTme[b][2024.02.02 20:00] - arrTme[b-1][2024.02.02 19:00] = [3600] > 7200

I have also added the below code just before b = CopyTime() at line 235.

  // ... Extra code added to check error
  // Note: EURUSD symbol may not be in Market Watch and history may not be found.
  // iSessionVP (XAUUSD,M1)       starting calc Time-Offest for Pepperstone Group Limited at 2024.02.02 16:02:55 found: Switch USD: 2024.03.10 03:00:00 Switch EUR: 2024.03.31 03:00:00  Switch AUD: 2024.04.07 03:00:00
  // iSessionVP (XAUUSD,M1)       241: CopyTime() FAILED for EURUSD H1: need times from 2024.01.29 02:00:00, but there are only from 1970.01.01 00:00:00 error: 4401
  int attempt = 0;
  datetime serverFirstDate = (datetime)SeriesInfoInteger("EURUSD",PERIOD_H1,SERIES_SERVER_FIRSTDATE);
  // checkLoadHisory() returns 0,1 or 2, if bars are synchronized with history, hence used >= 0
  while(!(checkLoadHistory("EURUSD",PERIOD_H1,serverFirstDate) >= 0) && attempt <= 10) {
    Sleep(200);
    attempt++;
  }

Looking forward to a favorable support from you.

 

In this loop:

    while(b-->1)
       {
        if(arrTme[b]-arrTme[b-1]>7200)
           {
            FstBarWk = arrTme[b];
            LstBarWk = FstBarWk + FXOneWeek;
            break;
           }
       }
    if(LstBarWk == 0)
        return(OffsetBroker.set);
...

I am looking for the last weekend, as the time of the last closing price gives an indication of the broker's offset. 7200 corresponds to 2 hours, if you want to change that maybe better to 100800, that would be 28 hours, still less than the 48 hours from Fri 17:00 to Sun 17:00 NY time.

Don't use M15 but H1 and better don't use other symbols than EURUSD the symbol with one of the highest trade volume - this tool is not for trading but only to get the time offset of the broker!

So just add EURUSD to the MarketWatch I think that would be better than the use of XAUUSD.

 
Carl Schreiber #:

In this loop:

I am looking for the last weekend, as the time of the last closing price gives an indication of the broker's offset. 7200 corresponds to 2 hours, if you want to change that maybe better to 100800, that would be 28 hours, still less than the 48 hours from Fri 17:00 to Sun 17:00 NY time.

Don't use M15 but H1 and better don't use other symbols than EURUSD the symbol with one of the highest trade volume - this tool is not for trading but only to get the time offset of the broker!

So just add EURUSD to the MarketWatch I think that would be better than the use of XAUUSD.

Thanks Carl for your reply.

Yes I am aware of that it is not trading tool and I am trying to use it mainly to get Time values for different trading sessions. So I can have info current session is in which market session. 

No I have not modified timeframe and symbol in the code. Have a look below

int attempt = 0;
datetime serverFirstDate = (datetime)SeriesInfoInteger("EURUSD",PERIOD_H1,SERIES_SERVER_FIRSTDATE);			// History Load and Symbol check is included with this
// checkLoadHisory() returns 0,1 or 2, if bars are synchronized with history, hence used >= 0
while(!(checkLoadHistory("EURUSD",PERIOD_H1,serverFirstDate) >= 0) && attempt <= 10) {
  Sleep(200);
  attempt++;
}

b = CopyTime("EURUSD",PERIOD_H1,BegWk+26*3600,5,arrTme);      // get time last 1h bar before switch in EU
if(b < 0) {
  Print(txt4Fail," found: Switch USD: ",_t2s(nxtSwitch_USD)," Switch EUR: ",_t2s(nxtSwitch_EUR),"  Switch AUD: ",_t2s(nxtSwitch_AUD),
        "\n",__LINE__,": CopyTime() FAILED for EURUSD H1: need times from ",_t2s(BegWk+26*3600),", but there are only from ",
        _t2s((datetime)SymbolInfoInteger("EURUSD",SYMBOL_START_TIME))," error: ",_LastError);
  ResetLastError();
  return(OffsetBroker.set);


while(b-- > 1) {


  if(arrTme[b] - arrTme[b-1] > 7200) {
    FstBarWk = arrTme[b];
    LstBarWk = FstBarWk + FXOneWeek;
    break;
  }
}

if(LstBarWk == 0)
  return(OffsetBroker.set);
b = CopyTime("EURUSD",PERIOD_H1,BegWk+26*3600,150,arrTme);			// Copy bar count increased to 150 > i.e. 5 days * 24 hours

2024.02.03 15:13:42.586 iSessionVP (XAUUSD,M15) b--[34] > 1 / arrTme[b][2024.01.29 04:00] - arrTme[b-1][2024.01.29 03:00] = [3600] > 7200
2024.02.03 15:13:42.586 iSessionVP (XAUUSD,M15) b--[33] > 1 / arrTme[b][2024.01.29 03:00] - arrTme[b-1][2024.01.29 02:00] = [3600] > 7200
2024.02.03 15:13:42.586 iSessionVP (XAUUSD,M15) b--[32] > 1 / arrTme[b][2024.01.29 02:00] - arrTme[b-1][2024.01.29 01:00] = [3600] > 7200
2024.02.03 15:13:42.586 iSessionVP (XAUUSD,M15) b--[31] > 1 / arrTme[b][2024.01.29 01:00] - arrTme[b-1][2024.01.29 00:00] = [3600] > 7200
2024.02.03 15:13:42.586 iSessionVP (XAUUSD,M15) b--[30] > 1 / arrTme[b][2024.01.29 00:00] - arrTme[b-1][2024.01.26 23:00] = [176400] > 7200	... here it shows bars greater than 7200
													It also happened to be last Friday of previous week
Seems I should have at least 125 H1 bars to catch week change. 
 
Gold is a somewhat unusual asset with perhaps more broker-dependent settings, so I would be cautious and I can't make any recommendation. On the other hand, the server time (TimeCurrent()) is the same for all assets...
 
Carl Schreiber #:
Gold is a somewhat unusual asset with perhaps more broker-dependent settings, so I would be cautious and I can't make any recommendation. On the other hand, the server time (TimeCurrent()) is the same for all assets...

Hi @Carl Schreiber

I really appreciate your time and efforts to make this useful class and make it available to use by forum members.

It seems there was memory catch problem. When I changed chart to another symbol and back to XAUUSD, the CopyTime() worked well with 5 bars as in your original code.

I am able to get Asian Open/Close, LON Open/Close and NYC Open/Close timings, however still trying to figure out -one day gap which temporarily resolved by adding +1 to DoM value.

//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:     getForexSessions()
//| APPLICAION: Get Forex Market's Asian/London/New York Session Open / Close time in Broker's Server Time
//|                                                     Method should be called only on Daily New Bar
//+-----------------------------------------------------------------------------------------------------------------------------+
void CAccessTimeseries::getForexSessions(const datetime pTimeDailyOpen,SForexSession &pFxSession[]) {

                string vMethod = "[" + mSymbol + "," + TimeToString(TimeCurrent()) + "] " + __FUNCTION__;
                /*
                Are GMT and UTC the same?
                Although both GMT and UTC display the same time, there is a difference: GMT is now considered just a time zone officially
                used in some European and African countries. But UTC is not a time zone, but rather the new time standard that is the basis
                for clock time and time zones worldwide. See Results below ... mGMTCurr[2023.11.07 23:00] mUTCCurr[2023.11.07 23:00]

                Greenwich Mean Time(GMT)                                is 5 hours ahead of Eastern Time(EST)
                Coordinated Universal Time(UTC) is 5 hours ahead of Eastern Time(EST)

                Forex Market Hours
                Local Time                                                      GMT                                     EST     (+5Hrs GMT)                     UTC (+5 Hrs EST)
                Tokyo           Open – 09:00 Hrs Close – 18:00 Hrs              22:00 PM 06:00 AM                       07:00 PM 04:00 AM                       12:00 AM 09:00 AM
                London          Open – 08:00 Hrs Close – 17:00 Hrs              08:00 AM 16:00 AM                       02:00 AM 11:00 AM                       07:00 AM 04:00 PM
                New York        Open – 08:00 Hrs Close – 17:00 Hrs              13:00 AM 21:00 PM                       08:00 AM 05:00 PM                       01:00 PM 10:00 PM
                */

                uint DayOfWeek = ((uint)(((pTimeDailyOpen-259200)%604800)/86400));  // Get 'uint' value for Day of Week Sunday = 0 ... Saturday = 6
                datetime SessionFrom,SessionTo;
                datetime dayFBM1 = 0, dayLBM1 = 0;
                if(SymbolInfoSessionQuote(mSymbol,(ENUM_DAY_OF_WEEK)DayOfWeek,0,SessionFrom,SessionTo)) {
                        dayFBM1  = StringToTime(""+(string)YoY(pTimeDailyOpen)+"."+(string)MoY(pTimeDailyOpen)+"."+(string)DoM(pTimeDailyOpen)+" "+TimeToString(SessionFrom,TIME_MINUTES));
                        dayLBM1 = StringToTime(""+(string)YoY(pTimeDailyOpen)+"."+(string)MoY(pTimeDailyOpen)+"."+(string)DoM(pTimeDailyOpen)+" "+TimeToString(SessionTo,TIME_MINUTES));
                }

                datetime        SVRCurr = dayFBM1;
                datetime        GMTCurr = SVRCurr + OffsetBroker.actOffset;                                                     // GMT = Broker's Server Time + OffsetBroker Time
                datetime        LONCurr = GMTCurr - (LONShift+DST_EUR);                                                         // current local time in London
                datetime        NYCCurr = GMTCurr - (NYCShift+DST_USD);                                                         // current local time in New York

                // Run CDealingWithTime.checkTimeOffset() to check if any changes of DayLightSaving (DST) in time Zone(s)
                checkTimeOffset(SVRCurr);

                // Set Current Day's London Session Open Times (in Local Time of the City)
                int DeltaLON = int(SVRCurr - LONCurr);
                datetime        LONOpen  = StringToTime(""+(string)YoY(LONCurr)+"."+(string)MoY(LONCurr)+"."+(string)(DoM(LONCurr)+1)+" 08:00");
                datetime        LONClose = StringToTime(""+(string)YoY(LONCurr)+"."+(string)MoY(LONCurr)+"."+(string)(DoM(LONCurr)+1)+" 17:00");

                // Set Current Day's New York Session Open Times (in Local Time of the City)
                int DeltaNYC = int(SVRCurr - NYCCurr);
                datetime        NYCOpen  = StringToTime(""+(string)YoY(NYCCurr)+"."+(string)MoY(NYCCurr)+"."+(string)(DoM(NYCCurr)+1)+" 08:00");
                datetime        NYCClose = StringToTime(""+(string)YoY(NYCCurr)+"."+(string)MoY(NYCCurr)+"."+(string)(DoM(NYCCurr)+1)+" 17:00");

                // The 'Asian Session' TimeStart at MidNight on Broker's Server Time (Quote starts at 01.01 Hrs SessionFrom Mon-Fri)
                pFxSession[0].ASAOpen  = dayFBM1;
                pFxSession[0].ASAClose = DeltaLON + LONOpen;                                                            // !!! Subtracted 60 seconds
                pFxSession[0].LONOpen  = DeltaLON + LONOpen;
                pFxSession[0].LONClose = DeltaLON + LONClose;
                pFxSession[0].NYCOpen    = DeltaNYC + NYCOpen;
                pFxSession[0].NYCClose = dayLBM1;
                //PrintFormat("%s: SVRCurr[%s] dayFBM1[%s]",vMethod,TimeToString(SVRCurr),TimeToString(dayFBM1));
                /*
                Note: When +1 is added to DoM, it gives correct result
                CAccessTimeseries::getForexSessions: Broker's SVRTime of SVRCurr[2024.02.05 01:01] ASAOpen[2024.02.05 01:01] LONOpen[2024.02.05 10:00] NYCOpen[2024.02.05 15:00]
                CAccessTimeseries::getForexSessions: Broker's SVRTime of SVRCurr[2024.02.02 01:01] ASAOpen[2024.02.02 01:01] LONOpen[2024.02.02 10:00] NYCOpen[2024.02.02 15:00]
                CAccessTimeseries::getForexSessions: Broker's SVRTime of SVRCurr[2024.02.01 01:01] ASAOpen[2024.02.01 01:01] LONOpen[2024.02.01 10:00] NYCOpen[2024.02.01 15:00]
                CAccessTimeseries::getForexSessions: Broker's SVRTime of SVRCurr[2024.01.31 01:01] ASAOpen[2024.01.31 01:01] LONOpen[2024.01.31 10:00] NYCOpen[2024.01.31 15:00]
                CAccessTimeseries::getForexSessions: Broker's SVRTime of SVRCurr[2024.01.30 01:01] ASAOpen[2024.01.30 01:01] LONOpen[2024.01.30 10:00] NYCOpen[2024.01.30 15:00]
                CAccessTimeseries::getForexSessions: Broker's SVRTime of SVRCurr[2024.01.29 01:01] ASAOpen[2024.01.29 01:01] LONOpen[2024.01.29 10:00] NYCOpen[2024.01.29 15:00]
                */

} // End of method getForexSessions()
 
Anil Varma #:

It seems there was memory catch problem. When I changed chart to another symbol and back to XAUUSD, the CopyTime() worked well with 5 bars as in your original code.

I am able to get Asian Open/Close, LON Open/Close and NYC Open/Close timings, however still trying to figure out -one day gap which temporarily resolved by adding +1 to DoM value.

I don't really understand that as you can't "change" the symbol of a chart only time frames! 1 h more or less might be because of the summer and winter time in that region. UTC and GMT are free from that but I am not sure about EST (can't remember).

My calculation starts from Friday NY 17:00 when the FX market closes with summer/winter time in NY. (XAUUSD might be different, I don't know that and this case this calculation cannot be applied!!) From that I calculate GMT (or UTC - should be the same) and then any other time from that with their local DST setting. That means e.g. only when the DST of LON and NY are the same they have their normal time difference but as the change in DST in NY is not the same in NY and in LON the time difference is +1 or -1 depending of the time on the year!!

 
Carl Schreiber #:
That means e.g. only when the DST of LON and NY are the same they have their normal time difference but as the change in DST in NY is not the same in NY and in LON the time difference is +1 or -1 depending of the time on the year!!

Thanks @Carl Schreiber for reply.

I don't really understand that as you can't "change" the symbol of a chart only time frames! ... I meant that as I did inserted a code for checkLoadHistory() [to make sure timeseries data are in synch], the file was running without this code being implement, and when I changed to different chart symbol and bring back to XAUUSD, the newly inserted code started working as file's old catch was released.

XAUUSD might be different ... On my broker's account XAUUSD calculation type is Forex, so I am sure the timings will be of Forex Market. See attached png for more information.

DST of NYC and LON is not same ... I will dig deeper into it, as I was not aware of this information.

 
Well read my articles about the time, everything is explained there: https://www.mql5.com/en/articles/9929
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.
 
Carl Schreiber #:
Well read my articles about the time, everything is explained there: https://www.mql5.com/en/articles/9929

Thanks a lot Carl.

The article is very informative, and will keep revisiting, as and when needed.

I just run a test and results are correct. So dont need to dig further :)

Testing the correctness
datetime        tBKR = TimeCurrent();
datetime        tGMT = tBKR + OffsetBroker.actOffset;
datetime        tLON = tGMT - (LONShift+DST_EUR);
datetime        tNYC = tGMT - (NYCShift+DST_USD);
PrintFormat("%s: tBKR[%s] tGMT[%s] tLON[%s] tNYC[%s]",vMethod,TimeToString(tBKR),TimeToString(tGMT),TimeToString(tLON),TimeToString(tNYC));

 The results are correct at this moment of time. Will check again on next DST change, i.e. March 10, 2024 3.00 am.

2024.02.07 17:12:33.939 iSessionVP (XAUUSD,M15) [XAUUSD,2024.02.07 13:42] CAccessTimeseries::getForexSessions: tBKR[2024.02.07 13:42] tGMT[2024.02.07 11:42] tLON[2024.02.07 11:42] tNYC[2024.02.07 06:42
Will 
 

Hi @Carl Schreiber

Is the DealWithTime.mqh have problem working on weekend, even in StrategyTester?

It is returning following error:

2024.02.10 15:06:12.638 2024.01.01 00:00:00   Alert: DealingWithTime v2.03.mqh[596]  Assigning the broker offset went wrong - somehow.

You have really made a very useful utility, however complexities involved to implement it in an Indicator or an EA, are outweighing against its benefits. (Or may be my skills are not yet upto mark) :(

Regards

Reason: