A good price backtest can still have the wrong trading hours
A session filter sounds simple: allow the Expert Advisor to evaluate signals during a chosen market window. But the label “London morning” is not a permanent hour on every broker server. Trading-server conventions, computer clocks, daylight-saving transitions, exchange holidays and thinly traded periods all complicate the mapping. A profitable-looking backtest does not prove that the EA interpreted these hours correctly. This guide treats time handling as an engineering test, not as an invitation to place a trade.
Start by writing down the reference session, the location or time-zone rules you intend, the broker-server convention you have actually observed and the dates to which each observation applies. If a historical offset is unknown, record it as unknown. Do not recover a missing time-zone policy by simply selecting the version that makes the equity curve look better.
Know which clock your EA actually reads
The MQL5 documentation describes TimeCurrent as the time of the latest known quote from the trading server. In an OnTick callback it refers to the tick being handled; in other event handlers it can refer to the latest quote for a symbol in Market Watch [1]. TimeTradeServer is different: the terminal calculates an estimate of server time using the computer time settings [2]. This is relevant when there are few incoming quotes or an EA uses a timer to perform housekeeping.
TimeGMT ordinarily calculates GMT from the computer’s local clock with daylight-saving considerations [3]. It does not by itself supply the complete historical offset policy for every broker or market venue. A rule that subtracts two current clock readings and applies that difference to many years of historical data is relying on an unverified assumption. Make the assumed reference time zone, changeover rules and data provenance visible in your test description.
Why the Strategy Tester can conceal this difference
MetaQuotes documents a special behavior in the Strategy Tester. During historical testing, TimeTradeServer equals simulated TimeCurrent, and TimeGMT is also equal to that simulated server time [2, 3]. The testing reference states that local, GMT and server clocks are intentionally treated as equal in this environment [4]. This promotes reproducible testing without depending on a connection, but it is not a replay of all live time-zone differences between a real VPS and a broker server.
If the subtraction TimeCurrent minus TimeGMT yields zero throughout a test, that is not proof the broker has historically operated on UTC. Equally, an EA that passes a historical session-filter test may behave differently on a forward demo if the mapping around a seasonal transition was coded incorrectly. Compare intended time windows with actual observed events rather than assuming that a familiar function name handles the entire calendar.
An explicitly hypothetical offset-change example
Consider a synthetic timeline, not a broker measurement. On hypothetical day A, an event at 13:00 UTC appears at 15:00 server time. On hypothetical day B, another event at 13:00 UTC appears at 16:00 server time. The offset in the invented example changed by one hour. An EA hard-coded to examine 15:00 server time on both dates would evaluate a different reference window on day B. The arithmetic is easy; verifying the historical conversion is the real challenge. For a hypothetical 13:00–14:00 UTC window with the end excluded, day A requires 15:00–16:00 server time and day B requires 16:00–17:00. On day B, 15:00 server time corresponds to 12:00 UTC and should be skipped under that rule.
The example does not assert that a particular broker changes its clocks. Some operators may keep one fixed offset, while others may use a seasonal schedule. Region-specific daylight-saving dates and trading holidays need their own checks. Record offset evidence for each relevant date and do not quietly edit the table after learning which outcomes were favorable. Past observations are not a guarantee of future broker policy.
Create a test log that never places an order
Use a demo-only or log-only EA with order submission disabled. Capture the symbol, server label, UTC reference, observed TimeCurrent, observed TimeTradeServer, callback type, proposed window bounds, date, expected decision and actual allow/skip decision. Define which event identity may be evaluated once, and decide how you will label incomplete records. Every rejection is evidence; it should not disappear from a report just because it produces an untidy table.
Build cases covering a first quote a few seconds after opening, another just after closing, thin quotes, a weekend, a restart and a pair of dates on either side of a relevant seasonal boundary. Run the cases historically, then compare with separate forward-demo observations. Do not invent missing ticks or classify an unknown date conversion as a successful pass. Neither a tester log nor a callback timestamp represents a guaranteed broker fill.
A practical acceptance criterion and its limits
A narrow acceptance criterion is useful: with a documented per-date conversion and predetermined synthetic timestamps, the session filter produces the expected allow/skip decision for each event. Keep the original inputs and failed cases. This can expose scheduling bugs, but it cannot validate profitability, predict broker execution conditions or eliminate slippage, commissions and liquidity risks. It is one engineering check in a wider EA evaluation process.
For the next exercise, create a twelve-row worksheet with normal-day observations, seasonal-boundary tests and missing-quote scenarios. Write down the expected answer before running your code. BamaUp’s free Auto-Trading Foundations lesson and EA checklist can help you structure the exercise without a purchase or funded account. This is educational testing rather than investment advice or a live trading signal.