Libraries: Dealing with time (2) functions - page 2

 
Anil Varma #:

Hi @Carl Schreiber

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

It is returning following error:

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

Could it be that you broker does not offer quotes for that and previous times? Have you checked that?

Beside that the time around Christmas (~Dec.20 .. Jan. 8) are not the best for backtests!
 

Hi @Carl Schreiber

Sorry for my above comment, please ignore it. I was really frustrated, as I was having so many challenges for my project VolumeProfile Indicator.

I have tried to incorporate following methods into your code and somehow succeeding to get results. Will keep you posted on developments.

The Constructor method ...

//+-----------------------------------------------------------------------------------------------------------------------------+
//| CLASS:        CDealWithTime()                                                               ... file to be renamed once this class is working properly
//+-----------------------------------------------------------------------------------------------------------------------------+
class CDealWithTime final {                                                                                     // The use of the 'final' specifier during class declaration prohibits further inheritance from this class.

        public:
          // Default Constructor with default parameters. Need so *pointer class can be declared
          CDealWithTime() {     mSymbol = mSymbol;      mTimeFrame = mTimeFrame;        }
         ~CDealWithTime() { }
                void                                                            OnTick(void);

        public:
                bool                                                            setBokerOffset();
                void                                                            checkTimeOffset(datetime tB);
                int                                                             SecTillClose();
        
        private:
                bool                                                            calcSwitchUSD(datetime now=0);
                bool                                                            calcSwitchEUR(datetime now=0);
                bool                                                            calcSwitchAUD(datetime now=0);
                void                                                            calcSwitchRUB(const datetime t);

                datetime                                                arrTme[];                                                                                                                                                                                                               // array to copy time

                string                                                  mSymbol;                                                                                                                                                                                                                // Default EURUSD
                ENUM_TIMEFRAMES                 mTimeFrame;                                                                                                                                                                                                     // Default PERIOD_H1
                datetime                                                mPrevTimeH01;
                bool                                                            IsNewBarH01();

}; // END of class CDealWithTime() definition

The Support Methods OnTick and IsNewBarH01 ...

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

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

                if(IsNewBarH01()) {
                        datetime weekBegin = BoW(TimeCurrent())+26*3600;
                        int attempt = 0;
                        int copied  = 0;
                        // get time last 1h bar before switch in EU
                        int bars = Bars(mSymbol,mTimeFrame,weekBegin,(weekBegin)+(5*24*3600));
                        ResetLastError();
                        while(CopyTime(mSymbol,mTimeFrame,weekBegin,5,arrTme) != bars && attempt <= 10) {
                                Sleep(100);
                                attempt++;
                        }                                                                       
                        if(attempt > 0) {
                                PrintFormat("%s: Error[%i] copiedTime %s-%s for [%i] bars from [%s] to [%s]",vMethod,GetLastError(),mSymbol,EnumToString(mTimeFrame),TimeToString(weekBegin),TimeToString((weekBegin)+(5*24*3600)));
                        }
                        else setBokerOffset();
                }

} // End of checkTimeOffset()

With this I am able to run the code without error Assigning the broker offset went wrong - somehow.

Additional fine tuning is still on to make it a workable solution.

 
Carl Schreiber #:

Could it be that you broker does not offer quotes for that and previous times? Have you checked that?

Beside that the time around Christmas (~Dec.20 .. Jan. 8) are not the best for backtests!

Hi Carl

Thanks for taking off time to reply me.

With the changes as mentioned above, I am able to run it without error in EA. So the Broker is providing data for these days.

Yeh you have a valid point that " Beside that the time around Christmas (~Dec.20 .. Jan. 8) are not the best for backtests!" :)

However, since it is not strategy BackTest, but just to make sure that my VolumeProfile OOP Class is working well and returning correct Session Times.

Have a nice weekend and take care.

 
Amazing job! Thank you!
 
Daniel K #:
Amazing job! Thank you!

:)

 

Very inspiring library!

a little suggestion about macro expansions

   datetime t = TimeCurrent(); 
   int a = DoWi(true ? t : t);
   int b = DoWi(false ? t : t);
   
   Print(a, " ", b);

t needs to be enclosed in parentheses to avoid side effects inside these macros DoWi, SoW, rndHoT, BoW.

#define  DoWi(t) ((int)((((t)-259200)%604800)/86400))      // (int)Day of Week Su=0,Mo=1,...

without the small fix, the above prints 1, 5

 
amrali #:

Very inspiring library!

a little suggestion about macro expansions

t needs to be enclosed in parentheses to avoid side effects inside these macros DoWi, SoW, rndHoT, BoW.

without the small fix, the above prints 1, 5

Thanks, I hadn't thought of such an application, will change that...

 

Forum on trading, automated trading systems and testing trading strategies

Libraries: Dealing with time (2) functions

Anil Varma, 2024.02.10 10:39

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


I also found the same error today (Saturday) when testing the library.

The BoW(t) macro has a bug.

If (t) is anytime in Saturday, BoW(t) calculates the beginning of the NEXT WEEK (wrong ?!), not current week.

This is a fixed version of BoW()

#include "DealingWithTime.mqh"  // to use BoW(t) -- !!! Note: if (t) is Saturday, BoW(t) returns the begining of the NEXT WEEK (wrong ?!), not current week.

#define  BoW_fixed(t) ((t)-((t)+345600)%604800)

void OnStart()

  {
   datetime t;
   t = D'1997.05.31 13:01'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'1998.01.03 05:07'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2001.09.22 18:31'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2009.05.02 18:17'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2013.11.02 05:47'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2017.05.13 17:04'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2019.01.19 10:29'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2022.07.16 04:12'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2024.08.03 07:51'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2024.10.26 10:27'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2028.05.27 04:56'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
   t = D'2035.05.26 20:34'; PrintFormat("BoW_fixed = %s <-| t: %s |-> BoW = %s", t2s(BoW_fixed(t)), t2s(t), t2s(BoW(t)));
  }

string t2s(datetime t, int mode=TIME_DATE|TIME_MINUTES)
  {
   return(DoWs(t) + ", " + TimeToString(t, mode));
  }

/*
 BoW_fixed = Su., 1997.05.25 00:00 <-| t: Sa., 1997.05.31 13:01 |-> BoW = Su., 1997.06.01 00:00
 BoW_fixed = Su., 1997.12.28 00:00 <-| t: Sa., 1998.01.03 05:07 |-> BoW = Su., 1998.01.04 00:00
 BoW_fixed = Su., 2001.09.16 00:00 <-| t: Sa., 2001.09.22 18:31 |-> BoW = Su., 2001.09.23 00:00
 BoW_fixed = Su., 2009.04.26 00:00 <-| t: Sa., 2009.05.02 18:17 |-> BoW = Su., 2009.05.03 00:00
 BoW_fixed = Su., 2013.10.27 00:00 <-| t: Sa., 2013.11.02 05:47 |-> BoW = Su., 2013.11.03 00:00
 BoW_fixed = Su., 2017.05.07 00:00 <-| t: Sa., 2017.05.13 17:04 |-> BoW = Su., 2017.05.14 00:00
 BoW_fixed = Su., 2019.01.13 00:00 <-| t: Sa., 2019.01.19 10:29 |-> BoW = Su., 2019.01.20 00:00
 BoW_fixed = Su., 2022.07.10 00:00 <-| t: Sa., 2022.07.16 04:12 |-> BoW = Su., 2022.07.17 00:00
 BoW_fixed = Su., 2024.07.28 00:00 <-| t: Sa., 2024.08.03 07:51 |-> BoW = Su., 2024.08.04 00:00
 BoW_fixed = Su., 2024.10.20 00:00 <-| t: Sa., 2024.10.26 10:27 |-> BoW = Su., 2024.10.27 00:00
 BoW_fixed = Su., 2028.05.21 00:00 <-| t: Sa., 2028.05.27 04:56 |-> BoW = Su., 2028.05.28 00:00
 BoW_fixed = Su., 2035.05.20 00:00 <-| t: Sa., 2035.05.26 20:34 |-> BoW = Su., 2035.05.27 00:00
*/
 
amrali #:
#include "DealingWithTime.mqh"  // to use BoW(t) -- !!! Note: if (t) is Saturday, BoW(t) returns the begining of the NEXT WEEK (wrong ?!), not current week. #define  BoW_fixed(t) ((t)-((t)+345600)%604800)

Thanks @amrali to point out the bug.

Will incorporate into my revised version of the Class.

 
amrali #:

I also found the same error today (Saturday) when testing the library.

The BoW(t) macro has a bug.

If (t) is anytime in Saturday, BoW(t) calculates the beginning of the NEXT WEEK (wrong ?!), not current week.

This is a fixed version of BoW()

Hi @amrali

I was trying to run it again today (my CurrentTime 17-Feb-2024 15:47 UTC+5.30) which is Saturday. 

Facing error ... Assigning the broker offset went wrong - somehow. Error occurring in checkTimeOffset() and I have tried to put do..while loop to allow 10 attempts to setBrokerOffset().

The error happened with BoW as well as BoW_fixed variable. I am getting same datetime value with both of them.

Worst thing is there is no Error message, even in the debugging mode, as why it failed to set.

2024.02.17 16:22:35.454 EURUSD,Weekly: 1 bar from 2023.12.31 00:00 added
2024.02.17 16:22:35.454 EURUSD,Weekly: history begins from 2023.01.01 00:00
2024.02.17 16:22:35.454 2024.01.02 01:01:00   USD-DST for 2024.01.02 01:01 DST:     0  nxtSwitch: SUN 2024.03.10 03:00  USD Spring: second 10 Sunday  of March: 3
2024.02.17 16:22:35.454 2024.01.02 01:01:00   DST_EUR for 2024.01.02 01:01 DST:     0  nxtSwitch: SUN 2024.03.31 03:00  EUR Spring: last 31 Sunday  of March: 3
2024.02.17 16:22:35.454 2024.01.02 01:01:00   AUD-DST for 2024.01.02 01:01 DST: -3600  nxtSwitch: SUN 2024.04.07 03:00  AUD Spring: first 7 Sunday  of April: 4
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[1] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[2] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[3] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[4] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[5] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[6] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[7] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[8] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[9] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   CDealWithTime::checkTimeOffset: BoW[2023.12.31 00:00] BoW_fixed[2023.12.31 00:00] setBokerOffset attempt[10] isTimeSet[false]
2024.02.17 16:22:35.454 2024.01.02 01:01:00   Alert:  CDealWithTime::checkTimeOffset [231]  Assigning the broker offset went wrong - somehow.
2024.02.17 16:35:09.321 2024.02.16 01:01:00   USD-DST for 2024.02.16 01:01 DST:     0  nxtSwitch: SUN 2024.03.10 03:00  USD Spring: second 10 Sunday  of March: 3
2024.02.17 16:35:09.321 2024.02.16 01:01:00   DST_EUR for 2024.02.16 01:01 DST:     0  nxtSwitch: SUN 2024.03.31 03:00  EUR Spring: last 31 Sunday  of March: 3
2024.02.17 16:35:09.321 2024.02.16 01:01:00   AUD-DST for 2024.02.16 01:01 DST: -3600  nxtSwitch: SUN 2024.04.07 03:00  AUD Spring: first 7 Sunday  of April: 4
2024.02.17 16:35:09.321 2024.02.16 01:01:00   Setting broker time offset at: FRI, 2024.02.16 01:01 for Pepperstone Group Limited
2024.02.17 16:35:09.321 2024.02.16 01:01:00   Offest (time+diff=GMT): OffsetBroker.actOffset: -7200   sec => GMT: 2024.02.15 23:01  time area: US=Winter & EU=Winter
2024.02.17 16:35:09.321 2024.02.16 01:01:00   get the seconds until FX closes (NY 17:00) with SecTillClose(): 82739 sec or 22 h, close time: FRI, 2024.02.16 23:59
2024.02.17 16:35:09.321 2024.02.16 01:01:00   DealWithTimeV2.03.mqh[513] OffsetBroker.set[true]
2024.02.17 16:35:09.321 2024.02.16 01:01:00   CDealWithTime::checkTimeOffset: TimeCurr[2024.02.16 01:01] BoW[2024.02.11 00:00] BoW_fixed[2024.02.11 00:00] setBokerOffset attempt[1] isTimeSet[true]
2024.02.17 16:35:09.321 2024.02.16 01:01:00   Setting broker time offset at: FRI, 2024.02.16 01:01 for Pepperstone Group Limited
2024.02.17 16:35:09.321 2024.02.16 01:01:00   Offest (time+diff=GMT): OffsetBroker.actOffset: -7200   sec => GMT: 2024.02.15 23:01  time area: US=Winter & EU=Winter
2024.02.17 16:35:09.321 2024.02.16 01:01:00   get the seconds until FX closes (NY 17:00) with SecTillClose(): 82739 sec or 22 h, close time: FRI, 2024.02.16 23:59
2024.02.17 16:35:09.321 2024.02.16 01:01:00   DealWithTimeV2.03.mqh[513] OffsetBroker.set[true]

got totally different results in another run :( ... this time it did setBroker which lead to correct time calculation for Asian/LON/NYC session time in my Broker's Server time. This matched with times at https://www.babypips.com/tools/forex-market-hours. I did used variable ... BoW_fixed (Though BoW and BoW_fixed returned same value)

when set this setting on ...

2024.02.17 16:52:15.694 2024.02.01 01:01:00   CDealWithTime::checkTimeOffset: TimeCurr[2024.02.01 01:01] BoW[2024.01.28 00:00] BoW_fixed[2024.01.28 00:00] setBokerOffset attempt[1] isTimeSet[true]

2024.02.17 16:52:15.694 2024.02.01 01:01:00   DealWithTimeV2.03.mqh[513] OffsetBroker.set[true]


Tools Debug Settings

2024.02.17 16:35:09.398 2024.02.16 01:01:00   [XAUUSD,2024.02.16 01:01] CVPSBase::IsNewBarD01: tSessions Day idx[3]: for [XAUUSD] tSVR[2024.02.16 01:01] Open tASA_SVR[2024.02.13 01:01] tLON_SVR[2024.02.13 10:00] tNYC_SVR[2024.02.13 15:00]
2024.02.17 16:35:09.398 2024.02.16 01:01:00   [XAUUSD,2024.02.16 01:01] CVPSBase::IsNewBarD01: tSessions Day idx[2]: for [XAUUSD] tSVR[2024.02.16 01:01] Open tASA_SVR[2024.02.14 01:01] tLON_SVR[2024.02.14 10:00] tNYC_SVR[2024.02.14 15:00]
2024.02.17 16:35:09.398 2024.02.16 01:01:00   [XAUUSD,2024.02.16 01:01] CVPSBase::IsNewBarD01: tSessions Day idx[1]: for [XAUUSD] tSVR[2024.02.16 01:01] Open tASA_SVR[2024.02.15 01:01] tLON_SVR[2024.02.15 10:00] tNYC_SVR[2024.02.15 15:00]
2024.02.17 16:35:09.398 2024.02.16 01:01:00   [XAUUSD,2024.02.16 01:01] CVPSBase::IsNewBarD01: tSessions Day idx[0]: for [XAUUSD] tSVR[2024.02.16 01:01] Open tASA_SVR[2024.02.16 01:01] tLON_SVR[2024.02.16 10:00] tNYC_SVR[2024.02.16 15:00]

seems more testing is required :)

Carl Schreiber
Carl Schreiber
  • 2024.01.20
  • www.mql5.com
Trader's profile
Reason: