Bar Timestamps, Time Zones and Daylight Saving: the Checklist Before Any Backtest
Which timestamp and time zone should a backtest assign to each market bar?
Record whether each vendor timestamp marks the start or end of its bar, convert source times to a common zone, and verify daylight-saving transitions before aligning signals. A left-labeled aggregate can contain later observations within its interval.
A left-labeled bar becomes fully observable after its interval closes; this loader check does not prove fill timing in every execution graph.

Evidence map
| Aspect | Finding |
|---|---|
| What it is | The set of checks that must pass on a price file before any result computed from it means anything. |
| Key result / practice | Four properties of a timestamp column determine whether a backtest is measuring the market or the file. |
| Practical rules | Before importing, verify four things. That the timestamp convention is known and stated, not assumed. |
What it is
Each of them concerns the index and leaves the prices untouched, and each can produce a convincing backtest artefact when handled incorrectly.
Key result / practice
The first is what the stamp marks: a bar stamped with the time its interval opened contains no information from before that interval, while a bar stamped with the time its interval closed contains information from before its own stamp, so treating the two conventions alike shifts each signal by one bar and manufactures look-ahead. This application resolves the question by resampling with the label and the closed side both set to the left, so a bar carries the timestamp of its opening and the bar's final OHLC becomes observable only after the interval closes. Order action and fill timing depend on the tested execution path. The second is the zone. Exports declare zones inconsistently, and the notation is treacherous: in the IANA database a zone written as Etc/GMT plus two hours means two hours behind universal time, the opposite of what a reader expects, which is why the loader resolves such headers through the database, without reversing signs by hand, and converts all timestamps to universal time. The third is daylight saving. In a local zone one hour is repeated at the autumn transition and another local hour does not exist at the spring transition. When a local zone is declared, the loader raises on ambiguous or nonexistent instants rather than guessing, because a silent guess moves an hour of data and no downstream check will notice. The fourth is the date convention: a file in which day and month are both below thirteen is ambiguous, and the loader applies an explicit convention and does not infer one. A file that mixes explicit offsets with local times is refused for the same reason.
Practical rules
That the entire file is in one zone, ideally universal time already. That the series has no duplicated stamps, which indicate a concatenation, and that its gaps correspond to genuine market closures and are not missing data, which is checked by counting bars per session against the expected count. And that the instrument coverage is the same across the entire period, since a universe that grows midway through changes the meaning of each cross-sectional statistic. Record the answers with the study, because a result whose data provenance is unknown cannot be reproduced (see [Survivorship, Look-Ahead and Timestamp Conventions] and [The practices that make a result recomputable are decided before the research]).
Source
the behaviour described is that of this application's loader and resampler (stochastly/data_source.py); the underlying conventions are those of the IANA time zone database. Primary source