Possible bug in TimeTradeServer

 

Hi,

I'm developing an alert/alarm system which is supposed to trigger when a certain datetime set by the user is reached. For debugging, I'm using my scenario here in Brazil where the stock exchange's and broker's timezone is GMT-3h, the live market opens at 10AM, the futures opens at 9AM and I'm opening by Terminal around 8:55AM. So what I'm doing is trying to calculate the difference in seconds between the moment when the indicator is loaded at the opening of the Terminal's and the desired time (10AM, in my test) and call EventSetTimer on that difference.

Simply put, the code is as follows:

datetime goal = fromUserInput; //In my case, 10AM

datetime currentDT = TimeTradeServer() - 60 * 60 * 3;

int diffInSecs = int (goal - currentDT);

EventSetTimer(diffInSecs);

I've been testing this code for a while now and most of the time it runs fine, but in some days like today, it doesn't. For instance, yesterday I opened the Terminal at 08:04:30 and got a diffInSecs of 6930, so 115,5 min or 1,925h which is precisely the time difference from 08:04 until 10:00. But today I opened my Terminal at 08:54:22 and got diffInSecs of 14738, thus 245,63 min or 4,09 hours, which basically means the aprox. 1h of difference until my goal of 10AM plus 3h like if the GMT part wasn't working properly. 

So, what could be happening here? This isn't the first time this problem happened, the reason why I had a debug Print placed in the first place, but usually things go fine and the alert is triggered when it's suppose to.

 
Use the TimeCurrent() function instead of TimeTradeServer() . TimeCurrent() returns the current time on the client side (your PC time), which in theory already adjusted for your local time zone and DST.
datetime goal = fromUserInput; //In your case, 10AM

datetime currentDT = TimeCurrent();

int diffInSecs = int(goal - currentDT);

EventSetTimer(diffInSecs);


OPTION-2: you can use the TimeGMT() function to get the current GMT time + adjust it to your local time zone by hand:

datetime goal = fromUserInput; //In your case, 10AM

datetime gmtTime = TimeGMT();
datetime currentDT = gmtTime - 60 * 60 * 3; // Adjust for GMT-3

int diffInSecs = int(goal - currentDT);

EventSetTimer(diffInSecs);
 
Check your PC (or vps) time is set to automatically update from internet server.
Windows -> Control panel -> Date and time

TimeTradeServer is a calculated value.

 
Oleksandr Medviediev #:
Use the TimeCurrent() function instead of TimeTradeServer() . TimeCurrent() returns the current time on the client side (your PC time), which in theory already adjusted for your local time zone and DST.


OPTION-2: you can use the TimeGMT() function to get the current GMT time + adjust it to your local time zone by hand:

Hi Oleksandr!

I considered using TimeCurrent, but it doesn't seems to suit my case because it provides the current time based on the last tick received and markets such as B3 are not like Forex which is basically opened almost all the time, rather it closes around 6:30PM and only opens again at 9AM. So if I were to load this indicator inside a Futures symbol such as WIN at the time I normally do, around 08:50, TimeCurrent would give me something like 18:30 as current time, an obviously wrong value.

Regarding option 2, I'll study TimeGMT a little better to see if it suits my case. That being said, manually correcting for my GMT isn't what I have in mind for the final version of this indicator since I want it to be used globally. Imagine, for example, if I decide to travel to Germany with its GMT+1; I wouldn't want to have to manually input that information to correct the time calculation! I prefer a system in which I set the time of the event in relation to the server I'm trading in (B3 in my Brazillian case) and then I can pick my notebook and travel the world and it would still trigger the alarm at the correct B3 hour regardless of my local time.

 
amrali #:
Check your PC (or vps) time is set to automatically update from internet server.
Windows -> Control panel -> Date and time

TimeTradeServer is a calculated value.

Hi,

it is! 

 
Relying on ( TimeTradeServer() ) is likely the best idea:
datetime goal = fromUserInput; // In your case, 10AM

datetime serverTime = TimeTradeServer();
datetime localTime = TimeCurrent();

int offsetSeconds = localTime - serverTime;
datetime adjustedServerTime = serverTime + offsetSeconds;

int diffInSecs = int(goal - adjustedServerTime);

EventSetTimer(diffInSecs);


 

What is your broker, and what is its GMT offset?

Would you please run this script in your terminal and report back the output so that I can help you.

void OnStart()
  {
   datetime tts = TimeTradeServer();
   datetime loc = TimeLocal();
   datetime gmt = TimeGMT();
   int BrokerOffset = (int)(tts - gmt);
   int LocalOffset  = (int)(loc - gmt);
   PrintFormat("Server            = %s", AccountInfoString(ACCOUNT_SERVER));
   PrintFormat("TimeTradeServer() = %s", string(tts));
   PrintFormat("TimeLocal()       = %s", string(loc));
   PrintFormat("TimeGMT()         = %s", string(gmt));
   PrintFormat("BrokerOffset      = %d (GMT%+g)", BrokerOffset, BrokerOffset/3600.0);
   PrintFormat("LocalOffset       = %d (GMT%+g)", LocalOffset, LocalOffset/3600.0);
  }

For example, this is the output that I receive on my terminal

// (USDCHF,H1)  Server            = ICMarketsSC-Demo
// (USDCHF,H1)  TimeTradeServer() = 2024.03.27 00:32:24
// (USDCHF,H1)  TimeLocal()       = 2024.03.27 00:32:24
// (USDCHF,H1)  TimeGMT()         = 2024.03.26 21:32:24
// (USDCHF,H1)  BrokerOffset      = 10800 (GMT+3)
// (USDCHF,H1)  LocalOffset       = 10800 (GMT+3)

Edit:

To check the pc time is accurate:  https://time.is/

Germany
Germany
  • 2024.03.26
  • time.is
7 million locations, 57 languages, synchronized with atomic clock time.
 
Oleksandr Medviediev #:
Relying on ( TimeTradeServer() ) is likely the best idea:


Hello Oleksandr,

I'm not sure I understood the operation of "adjustedServerTime".

Suppose the market closed yesterday at 18:30 and now I'm at 08:50 (same GMT as broker) and the market is going to open at 09:00. So TimeCurrent will give me 18:30 and TimeTradeServer will give me presumably 08:50. So the offset between TimeTradeServer and TimeCurrent will be huge, and why would I need to add that offset to TimeTradeServer's result?


amrali #:
Would you please run this script in your terminal and report back the output so that I can help you.

Hi amrali,

here are the results of the code you provided:

//Server            = XPMT5-DEMO
//TimeTradeServer() = 2024.03.27 10:53:01
//TimeLocal()       = 2024.03.27 10:53:01
//TimeGMT()         = 2024.03.27 13:53:01
//BrokerOffset      = -10800 (GMT-3)
//LocalOffset       = -10800 (GMT-3)

Notice the market is currently open and I guess the most interesting results would be the ones from before the opening of the market.

Bonus: As of now, I'm using the following code to determinate the time:

   const datetime serverDT = TimeTradeServer();
   const datetime terminalDT = TimeCurrent();

   if (serverDT > terminalDT - 60 && serverDT < terminalDT + 60)
   {
      //Print("DEBUG using TimeCurrent");
      return terminalDT;
   }
   else
   {
      //Print("DEBUG using TimeTradeServer");
      return serverDT;
   }

So I'm trying to see if the market is currently open; if it is, use TimeCurrent, otherwise I assum the market is closed and I use TimeTradeServer instead. The problem is that this gives me the apparent bug mentioned in the first post.

 

I suspect the problem is here:

datetime goal = fromUserInput; //In my case, 10AM

in the way you parse user input.

Edit:

I could not replicate the 'bug' in TimeTradeServer() on indicator OnInit()

 

Hello Oleksandr,

I'm not sure I understood the operation of "adjustedServerTime".

Suppose the market closed yesterday at 18:30 and now I'm at 08:50 (same GMT as broker) and the market is going to open at 09:00. So TimeCurrent will give me 18:30 and TimeTradeServer will give me presumably 08:50. So the offset between TimeTradeServer and TimeCurrent will be huge, and why would I need to add that offset to TimeTradeServer's result?

When you say that TimeCurrent() gives 18:30, it implies that the last received tick or market data update was from the previous day's trading session (18:30). However, TimeCurrent() should reflect the current time on your local machine, which should be in sync with the actual time (08:50 in your example).

The purpose of using TimeCurrent() is to get the correct time on your local machine, which should already be adjusted for your local time zone and DST settings. This time should be accurate and up-to-date, regardless of the last received market data update.

On the other hand, TimeTradeServer() returns the current time on the broker-server, which may or may not be in sync with your local time, depending on the time zone difference and DST adjustments.

The offset calculation ( offsetSeconds = localTime - serverTime ) is used to determine the difference between your local time ( TimeCurrent() ) and the broker-server time ( TimeTradeServer() ). This offset accounts for the time zone difference and any DST adjustments automatically, without need to manually adjust for a specific time zone.

By adding this offset to the server time ( adjustedServerTime = serverTime + offsetSeconds ) we effectively convert the server time to your local time, taking into account any time zone and DST differences.

So, in your example:

  • TimeCurrent()  should show the correct time on your local machine, which is 08:50
  • TimeTradeServer()  might show the broker-server time, let's assume it's also 08:50 (assuming the broker is in the same time zone as you)
  • The offset ( offsetSeconds ) would be  TimeCurrent() - TimeTradeServer()  = 08:50 - 08:50 = 0 seconds
  • adjustedServerTime  would be  serverTime + offsetSeconds  = 08:50 + 0 = 08:50 (which is the correct local time)

The advantage this approach:

  •  you don't need to manually adjust for specific time zones or DST change
  •  ensures that you're working with the correct local time, regardless of your location or the broker's server location.
 
Oleksandr Medviediev #:

On the other hand, TimeTradeServer() returns the current time on the broker-server, which may or may not be in sync with your local time, depending on the time zone difference and DST adjustments.

    This is wrong!

    TimeTradeServer

    Returns the calculated current time of the trade server. Unlike TimeCurrent(), the calculation of the time value is performed in the client terminal and depends on the time settings on your computer.

    FYI, all time functions except TimeCurrent() returns calculated values (i.e., depending on the time settings of your computer):

    TimeTradeServer()
    TimeLocal()
    TimeGMT();
    

    Proof: change your computer's time from Windows -> Control Panel -> Date and Time and run the script above in #6 and you will find that these functions actually returns wrong times.



    Also, I have a concern on this code:

    Doing simple math, it turns out the code does nothing actually:

    datetime adjustedServerTime = serverTime + (localTime - serverTime);
    datetime adjustedServerTime = localTime;
    

    I do not see any adjustments here!

    As I said before, there is no bugs in TimeTradeServer(), the bug lies in this line of code

    datetime goal = fromUserInput; //In my case, 10AM
    

    because the OP did not post the actual code he used and he did not provide any example to reproduce the bug.