Subject: Clarification needed: MT5 Python timestamps appear 3 hours ahead of UTC on FundedNext

Hello MetaQuotes team,

I am developing a Python market-data pipeline and need clarification about the timestamp behavior of the official MetaTrader 5 Python API.

Environment

  • MT5 terminal: build 6231

  • Python MetaTrader5 package: 5.0.6231

  • Broker: FundedNext-Server 2

  • Symbol: XAUUSD

  • Timeframe: M15

  • Windows clock: independently checked against an NTP time source, with measured offsets below 0.2 seconds

Observed behavior

At approximately 2026-10-16 16:43 UTC, the Python API returned a tick timestamp that mechanically decoded to approximately 19:43 UTC.

The difference was approximately 10,800 seconds.

The raw bar timestamp for an M15 candle also matched the time displayed on the MT5 chart. Its OHLC, tick volume, and spread matched the API data exactly.

FundedNext confirmed that its server display clock uses GMT+2 or GMT+3 depending on daylight saving time, but could not confirm the timestamp convention used by the Python API.

Questions

  1. Are symbol_info_tick().time and .time_msc guaranteed to represent true Unix UTC timestamps?

  2. Do the time fields from copy_rates_from_pos() and other history functions represent UTC or broker-server wall time?

  3. If timestamps are expected to be UTC, what would explain the reproducible three-hour discrepancy when the Windows clock is synchronized?

  4. What is the supported way to convert these timestamps correctly across historical daylight saving transitions?

I have not applied a fixed offset or modified the code. The investigation is read-only, and no trades were placed.

I would appreciate an authoritative explanation of the intended timestamp semantics and any known issues affecting this terminal/API version.

Thank you.

Forum on trading, automated trading systems and testing trading strategies

Authoritative MetaQuotes-Demo tick timestamp and copy_ticks_range time-domain semantics

Alain Verleyen, 2026.09.24 17:35

I reported the documentation issue about datetime and timezone to MetaQuotes. 

Where is the documentation wrong ? Each time it claims the following :

The confusion comes from how Python datetime is working, by default it will use the local timezone, the one of the computer where the python code is running, so to avoid returning different data depending where your code run, it's requested to set UTC timezone for each datetime parameter used in a python/MQL5 functions. So you need to use an UTC timezone datetime to finally receive data using the broker server timezone including DST.

An example to illustrate this :

# set time zone to UTC
timezone = pytz.timezone("Etc/UTC")
# create 'datetime' object in UTC time zone to avoid the implementation of a local time zone offset
utc_from = datetime(2025, 1, 10, 0, 0, tzinfo=timezone)
# get 10 EURUSD H4 bars starting from 01.10.2020 in UTC time zone
rates = mt5.copy_rates_from("EURUSD", mt5.TIMEFRAME_H1, utc_from, 1)

# Check without any UTC reference
dt_from = datetime(2025, 1, 10, 0, 0)
ratesCheck = mt5.copy_rates_from("EURUSD", mt5.TIMEFRAME_H1, dt_from, 1)

 
# shut down connection to the MetaTrader 5 terminal
mt5.shutdown()
# display each element of obtained data in a new line
print("Display obtained 'UTC TZ' data 'as is'")
for rate in rates:
   print(rate)
 
# create DataFrame out of the obtained data
rates_frame = pd.DataFrame(rates)
# convert time in seconds into the datetime format
rates_frame['time']=pd.to_datetime(rates_frame['time'], unit='s')
                           
# display data
print("\nDisplay dataframe with date_from using UTC")
print(rates_frame)  

# display each element of obtained data in a new line
print("Display obtained 'local TZ' data 'as is'")
for rate in rates:
   print(ratesCheck)

# create DataFrame out of the obtained data
rates_frame_check = pd.DataFrame(ratesCheck)
# convert time in seconds into the datetime format
rates_frame_check['time']=pd.to_datetime(rates_frame_check['time'], unit='s')
                           
# display data
print("\nDisplay dataframe with date_from using local time (no TZ specified)")
print(rates_frame_check)  

2026.09.24 13:27:39.878    Display obtained 'UTC TZ' data 'as is'
2026.09.24 13:27:39.878    (1736467200, 1.03011, 1.03011, 1.0294, 1.02998, 288, 4, 0)
2026.09.24 13:27:39.878    
2026.09.24 13:27:39.878    Display dataframe with date_from using UTC
2026.09.24 13:27:39.878            time     open     high     low    close  tick_volume  spread  real_volume
2026.09.24 13:27:39.878    0 2025-01-10  1.03011  1.03011  1.0294  1.02998          288       4            0
2026.09.24 13:27:39.878    Display obtained 'local TZ' data 'as is'
2026.09.24 13:27:39.878    [(1736485200, 1.03016, 1.03031, 1.02975, 1.02983, 698, 0, 0)]
2026.09.24 13:27:39.878    
2026.09.24 13:27:39.878    Display dataframe with date_from using local time (no TZ specified)
2026.09.24 13:27:39.878                     time     open     high      low    close  tick_volume  spread  real_volume
2026.09.24 13:27:39.878    0 2025-01-10 05:00:00  1.03016  1.03031  1.02975  1.02983          698       0            0

2025.10.01 00:00 is 1736467200 (epoch time in seconds) 

2025.10.01 05:00 is 1736485200 with my local timezone shift at that date. If you run this code from a different timezone, the first one will be the same, but the second one will differ.

So you get different data because you request different datetime, python/MQL5 API request UTC datetime. But the data MT5 returns are ALWAYS broker server time data.