Timezones and Daylight Saving: The Backtest Error That Shifts Every Session by an Hour

8 min readQuantParadox research

Forex trades around the clock across markets that keep different clocks, and a data feed has to choose one of them. Most backtesters never ask which one was chosen, and any rule that mentions an hour of the day inherits the answer without knowing it.

The short answer

A backtest that reads session or daily boundaries from a fixed clock offset grades the wrong hours for several weeks each year, because the London and New York markets change their clocks on different dates, so every time-based trading rule has to be defined in a named local time and converted per date.

Why do the clocks disagree?

The clocks disagree because London and New York each move their clocks for daylight saving on different dates, Tokyo does not move at all, and most broker feeds are stamped in a server time that follows one of those conventions or none of them.

For most of the year the offset between any two of these is constant, and a rule written against one of them is correct. For a few weeks each spring and autumn, when one centre has changed and another has not, the offsets shift by an hour. A fixed offset from the feed's timestamp to the London open is then wrong by an hour for those weeks, and so is every rule that uses it.

Broker server time adds a further layer. Many brokers stamp bars in a time that tracks New York with a fixed offset, so that the daily bar closes at the New York close, and that time changes with New York's clock rather than London's. A trader who assumes the feed is in UTC, or in their own local time, has an error that varies through the year.

The disagreement is small in hours and large in effect, because the hours it moves are precisely the ones session rules care about.

Which rules does it corrupt?

It corrupts every rule that references a clock: session filters, opening-range definitions, daily and weekly bar boundaries, time-of-day exits, and any rule that avoids or targets a scheduled event by its hour.

Session filters are the obvious victims. A rule that trades only between two fixed hours of the feed's time is trading a window that slides against the actual London or New York open by an hour for several weeks a year. The trades taken in those weeks are from the wrong hours, and over a decade they are a meaningful share of the sample.

Daily bars are the less obvious victims. The daily open, high, low and close depend on where the day is cut, and a feed that cuts it at the New York close produces different daily bars from one that cuts it at midnight UTC. Any rule built on the daily bar, such as a daily range breakout or a rule that reads yesterday's close, is a different rule on each feed, and the difference is not visible on a chart.

Weekly bars and event times inherit the same problem. A weekly bar that starts on Sunday evening in one convention starts on Monday morning in another, and a scheduled release at half past eight in one city is a different hour of the feed depending on the season.

How do you detect it in your data?

Detect it by profiling activity by hour of the feed's clock across the year and looking for the step change at the daylight-saving dates, and by checking the timestamps of bars around a known transition against what the exchange clock says they should be.

The activity profile is the quickest check. Average the bar range or the tick count by hour of the day, separately for the weeks before and after each daylight-saving transition. If the feed's clock follows one centre, the profile for the other centre's hours will jump by an hour at that centre's transition date. The jump tells you which centre the feed follows, and that the other one is drifting relative to it.

The timestamp check is the precise one. Take a date on which London and New York had different daylight-saving states and look at the bar that contains a known event, such as the New York equity open. Its timestamp in the feed, compared with the known local time of the event, gives the feed's offset on that date. Repeat for a date in the other state and the two offsets show whether the feed moved with London, with New York, or with neither.

Once the convention is known, it should be written down next to the data, because it is not recoverable from the bars themselves and every rule depends on it.

How do you define time so it stays put?

Define every clock reference in a named local timezone, London time for the London session and New York time for the New York session, convert it to the feed's time per date using the actual daylight-saving rules of that zone, and state the daily-bar boundary as a convention rather than inheriting one.

Naming the zone is the fix for sessions. A rule that says the first three hours after the London open, in London time, is the same rule in every week of the year, and the conversion to the data's clock is done for each date by a timezone library that knows when London changed. The offset is then a function of the date, which is what it always was.

The daily boundary is a choice and the honest thing is to make it explicit. Cutting the day at the New York close produces daily bars that match most retail charts; cutting at midnight UTC produces bars that match most institutional data. A rule that reads daily values should say which, and a backtest of it on the other convention is a backtest of a different rule.

The result should carry the convention with it. A session result that does not state its zone and its daily boundary cannot be reproduced on another feed, and a comparison between two such results is a comparison between two unknown rules.

How does QuantParadox handle time?

QuantParadox stores its archive in a single reference time and defines each session in the local time of its market centre, so the London, New York and Tokyo sessions are converted per date with the actual daylight-saving rules of each zone, and a rule stated in a session's local hours means the same thing across the whole decade.

Clock windows stated in hours and minutes are resolved the same way, against a named zone, so a kill-zone or opening-range rule written in London time is graded on the London hours in every week of the year rather than on a fixed offset that drifts.

The daily-bar boundary on the platform is a stated convention rather than a broker's, and a rule that depends on a specific broker's daily close has to say so; a daily-range rule ported from a feed with a different boundary will produce different daily bars and should be checked for agreement on a sample of days before its results are compared.

The reason to be explicit about all of this is that the error it prevents is invisible in a result. A session rule graded on drifting hours does not fail; it produces a number that is quietly wrong for a tenth of the history, and the only defence is a definition that does not drift.

Questions people actually ask

What timezone is forex data in?

There is no single convention, which is the problem. Broker feeds are usually stamped in a server time that follows either New York or a fixed offset from it, so that the daily bar closes at the New York close; institutional data is more often in UTC; and some feeds follow a European clock. The feed's convention is not recoverable from the bars themselves, and it has to be established by checking timestamps around a known event on dates in each daylight-saving state.

Does daylight saving affect forex backtesting?

Yes, for any rule that references an hour of the day. London and New York change their clocks on different dates, so a fixed offset from the feed's time to either open is wrong by an hour for several weeks each year, and session filters, opening ranges and time-of-day exits are graded on the wrong hours during those weeks. Over a decade that is a meaningful share of the sample. Defining each window in a named local time and converting per date removes the drift.

Should daily candles close at New York time or midnight UTC?

Neither is correct; they are two conventions that produce different daily bars from the same minute data, and a rule that reads daily values is a different rule under each. The New York close matches most retail charts and produces five daily bars per week; midnight UTC matches most institutional data and produces a partial Sunday bar. State the convention with the rule and with the result, and check that a rule ported from one convention agrees with its original on a sample of days before comparing results.

The only backtest that settles it is yours.

Build a strategy from a sentence, paste your own Python, or import your live trade history and have it graded. Five full backtests free, no card, and we'll tell you plainly when the result is indistinguishable from luck.

We publish research and tooling, not trading advice, and we make no claim about future returns. Everything above describes how to test an idea — not a reason to trade one.