Broker time zone offsets, DST, and the strategy tester

 

Maybe I am not using the right search terms in google or on this forum (if so, please enlighten me so I can find the golden key).  I cannot find easy solutions to aligning my timezone with my broker's timezone in the strategy tester... and take into account DST.  So, I kludged my way through it as best I could.  Find below/attached my chonky fix.  Feel free to adapt it if it works for you, I'd love to see anyone's suggestion for improvements.  I know I would like to make it a little more atomic, and see if I could make the code more efficient, but at least this is working "good enough" for my current purposes.  Except it feels kludgey.

The main return value is: Is it time to trade (bool).  True for trade, false for don't trade (outside of your prescribed hours).  Should work in a live EA as well as in the strategy tester.  Note that I don't mind using "approximate" DST start and end dates in my testing.  You might.

It should compile and work in mt4 and 5. 

There is one important setting that you need, and that you can run this EA on a chart to find out: the ServerOffset value.  Mine, for instance is -7 showing the diff between US Eastern and the MetaQuotes server on MT5.  You can use the value you find for this if you incorporate this code into your own project.  All mistakes are my own - either by being negligent in copy/pasting some tidbits from other sources, or in my own lack of coding acumen. 

Cheers


/*

EA to determine trading times, usable in the Strategy Tester, with DST offset

1. Attach Metatrader to your broker account, then add this EA to a window
2. Observe the "Local time offset from server (Live):" value in the comment
3. Use this value to set ServerOffset (Time zone offset from your broker) in your code
4. If your country uses DST, enter that shift in WinterTimeHourChange, otherwise 0
5. Use approximately good enough dates for springforward and fallback.
6. Choose your Trading Window Start and End times
7. Run the EA in tester mode, with Visual Mode on and ensure that the values change and update properly
8. Modify and use this code in your own EAs
9. Can manage partial server offsets, such as 8.5, etc

*/

input string info_0 = "--> Trading Window Times - Input LOCAL times <--";
input string TradingWindowStartHHMM = "16:45"; // Daily trade time start. HH:MM
input string TradingWindowEndHHMM = "16:59"; // Daily trade time end. HH:MM
//
input string info_1 = "--> Time Management for Strategy Tester <--";
//-------->for GetDSTDates()
input string springforward = "3/20"; // DST Start MM/DD, approximate. Use /
input string fallback      = "10/20"; // DST End MM/DD, approximate. Use /
string SpringForwardDate, FallBackDate;
//<------------------------
input double ServerOffset = -7;  // Time zone offset from your broker
input double WinterTimeHourChange = -1; // When DST time ends, server offset delta
//


//
//
//
void TT_OnInit() {
   UpdateGlobalDSTDates(springforward, fallback);
  }
//
//
//
void TT_OnDeinit() {
   Comment("");
  }
//
//
//
//
bool AreWeTesting() {
   bool return_value;

#ifdef __MQL4__
   return_value = IsTesting();
#endif

#ifdef __MQL5__
   return_value = (bool)MQLInfoInteger(MQL_TESTER);
#endif

   return(return_value);
  }
//
//
//
//
void UpdateGlobalDSTDates(string springforward_in, string fallback_in) {
// springforward_in and fallback_in are from the inputs springforward and fallback

   MqlDateTime timestruct;
   TimeToStruct(TimeCurrent(),timestruct);

// save the results to the global string variables SpringForwardDate and FallBackDate
   SpringForwardDate = IntegerToString(timestruct.year) + "/" + springforward_in;
   FallBackDate = IntegerToString(timestruct.year) + "/" + fallback_in;
  }
//
//
//
//
bool CalculateTradingTimes(string TradingWindowStartHHMM_in, string TradingWindowEndHHMM_in, double ServerOffset_in, double WinterTimeHourChange_in, string SpringForwardDate_in, string FallBackDate_in) {
// takes the inputs TradingWindowStartHHMM and TradingWindowEndHHMM, ServerOffset and WinterTimeHourChange
// These values will have to be validated

   double LiveOffsetFromServer, TestOffsetFromServer;
   datetime TimeWithOffset, TradeWindowStart, TradeWindowEnd, CalcOffsetTime;
   
// IsItTimeToTrade is the MAIN output: should we trade? true/false
   bool IsItTimeToTrade=false;

// The following ONLY works in NORMAL, NON-TESTER mode
   LiveOffsetFromServer = ((int)TimeLocal()-(int)TimeCurrent())/60/60;

// The following ONLY works in STRATEGY TESTER mode
   TestOffsetFromServer = (TimeCurrent() >= StringToTime(SpringForwardDate_in) && TimeCurrent() <= StringToTime(FallBackDate_in))
                          ? ServerOffset_in : ServerOffset_in + WinterTimeHourChange_in;

   string TodaysDate = TimeToString(TimeLocal(),TIME_DATE);
   TradeWindowStart = StringToTime(TodaysDate+" "+TradingWindowStartHHMM_in);
   TradeWindowEnd = StringToTime(TodaysDate+" "+TradingWindowEndHHMM_in);

   if(AreWeTesting()) {
      TimeWithOffset = TimeCurrent() + (int)(TestOffsetFromServer*3600);
      CalcOffsetTime = TimeWithOffset;
      (CalcOffsetTime >= TradeWindowStart && CalcOffsetTime <= TradeWindowEnd) ? IsItTimeToTrade=true : IsItTimeToTrade=false;
     }
   else {
      TimeWithOffset = TimeCurrent() + (int)(TestOffsetFromServer*3600);
      CalcOffsetTime = TimeWithOffset;
      (CalcOffsetTime >= TradeWindowStart && CalcOffsetTime <= TradeWindowEnd) ? IsItTimeToTrade=true : IsItTimeToTrade=false;
     }
   
//-----> Feedback to confirm this is functioning - not needed for regular use
   string TestingLive = (AreWeTesting()==true)?"TESTING":"Live";
   string TradeBool = (IsItTimeToTrade==false)?"false":"true";
   string main = "\n\n"+
          "TimeCurrent:  "+ TimeToString(TimeCurrent(), TIME_SECONDS)+ "\n"+
          "TimeLocal:    "+ TimeToString(TimeLocal(), TIME_SECONDS)+ "\n"+
          "\n"+
          "Testing?: " + TestingLive +"\n"+
          "\n"+
          "SpringForwardDate: "+ SpringForwardDate+ "\n"+
          "FallBackDate: "+ FallBackDate+ "\n"+
          "\n"+
          "Local time offset from server (Live): "+ (string)LiveOffsetFromServer+ "\n"+
          "Time offset from server (TESTING): "+ (string)TestOffsetFromServer+"\n"+
          "\n"+
          "Local TradeWindowStart: "+ TimeToString(TradeWindowStart)+"\n"+
          "Local TradeWindowEnd:   "+ TimeToString(TradeWindowEnd)+"\n"+
          "Local calculated offset time used for testing: "+ TimeToString(CalcOffsetTime)+"\n"+
          "IsItTimeToTrade: "+ TradeBool +"\n";

   Comment(main);
//<-----

// main output: should we trade?  true/false
   return(IsItTimeToTrade);
  }
//+------------------------------------------------------------------+
The Fundamentals of Testing in MetaTrader 5
The Fundamentals of Testing in MetaTrader 5
  • www.mql5.com
What are the differences between the three modes of testing in MetaTrader 5, and what should be particularly looked for? How does the testing of an EA, trading simultaneously on multiple instruments, take place? When and how are the indicator values calculated during testing, and how are the events handled? How to synchronize the bars from different instruments during testing in an "open prices only" mode? This article aims to provide answers to these and many other questions.
Files: