Current Blog
How to Use Point-in-Time Fundamentals in a Trading Backtest
A point-in-time backtest admits each financial fact only after its filing became public, while preserving later amendments as separate versions.
This article was prepared with AI assistance and checked through automated editorial and source review. No named human review is recorded.
A point-in-time fundamental backtest should use a financial fact only after the filing that disclosed it became public and after any delay needed to receive and process it. The fiscal period end is not the release time. A balance-sheet value for June 30 may not be available until a Form 10-Q is accepted and disseminated weeks later.
The safest design keeps every version of every fact. Each row should identify the company, taxonomy concept, value, unit, period start and end, filing form, accession number, filing acceptance time, source retrieval time, vendor ingestion time, and the first strategy decision allowed to use it.
Separate the dates that answer different questions
Fundamental datasets often contain several dates. They are not interchangeable.
Period end says what accounting interval the fact describes.
Filing date and acceptance time say when the submission entered EDGAR.
Dissemination time says when the public could receive it.
Vendor ingestion time says when the research system actually had a usable record.
Decision time says when the strategy formed an order.
The SEC's EDGAR APIs expose submission history and extracted XBRL data. The SEC says the JSON structures are updated through the day as submissions are disseminated. It also notes that its submissions and XBRL APIs have different typical processing delays. A backtest should therefore record which endpoint or vendor feed supplied the value and when the value was observed.
Using the period end as the availability date creates look-ahead bias. Using today's corrected value for every historical run creates a subtler version of the same problem.
Worked release-gate example
Assume a company reports a quarter ending June 30. Its Form 10-Q is accepted by EDGAR on August 7 at 4:12 p.m. New York time. The strategy makes one decision at the 4:00 p.m. close and needs five minutes to retrieve, parse, and validate a filing.
The August 7 closing decision cannot use the new facts because the filing arrived 12 minutes after that decision. With the stated five-minute processing delay, the earliest usable timestamp is 4:17 p.m. If the strategy trades only the regular session, its next eligible decision is the following session's scheduled decision time.
This is an illustrative timing example, not an empirical result. It assumes minute-level timestamps, a five-minute processing rule, no after-hours trading, and the venue calendar in force for the instrument. A production test should use the actual EDGAR acceptance timestamp, the actual ingestion log, and the strategy's documented decision schedule.
Use acceptance and ingestion times as release gates
The SEC's filing-status guidance explains that EDGAR assigns filing dates based on submission and acceptance rules, including special handling after 5:30 p.m. Eastern Time. That filing date can be less precise than the timestamp needed by an intraday strategy. Keep the accepted timestamp when the source provides it.
Define a release gate such as usable_at = max(public_at, ingested_at) + validation_delay. Compare usable_at with the strategy decision timestamp. The rule should use timezone-aware instants and the same market calendar and time-zone policy as the rest of the backtest.
If historical ingestion logs do not exist, use a conservative, declared latency assumption. Test more than one delay. Do not label an estimated vendor timestamp as observed history.
Do not flatten amendments into the original filing
A company can later amend a filing or restate a reported value. The backtest should preserve the original fact and the amended fact with separate accession numbers and availability times. Before the amendment became public, the simulated strategy should see the original version. After the amendment clears the release gate, it may see the new version.
This requires an append-only fact history. A table that stores only the latest value cannot reproduce what the strategy knew on a past date. Connect each normalized fact to its source document and transformation record using the practices in data lineage for trading research.
Read XBRL context, units, and filing identity
The SEC describes Inline XBRL as a format that puts machine-readable tags inside the human-readable filing. Its context can include the reporting period and other information needed to interpret a value. The tag alone is not enough.
Validate the unit, scale, period, entity, and whether the fact is an instant or a duration. Revenue over a quarter and cash at quarter end are different measurement types. Reject silent conversions between dollars, thousands of dollars, shares, and percentages. Preserve the accession number so duplicate facts from different filings can be resolved by an explicit rule.
The SEC's Company Facts API is useful for extraction, but the SEC notes that frame data aligns facts to calendar periods even though company fiscal calendars can differ. For issuer-level research, retain the filing's own dates and context rather than assuming every company follows the same calendar quarter.
Build an as-of join that cannot see the future
For each decision timestamp, select the latest eligible fact version whose usable_at is not later than the decision. Partition by company, concept, unit, and the accounting context needed by the signal. Never join only on ticker and fiscal period.
Entity history matters too. Tickers change, companies merge, and failed issuers disappear from current universes. Use stable identifiers and a dated membership record so point-in-time fundamentals do not reintroduce survivorship bias.
Keep the query cutoff in the run manifest. A rerun should be able to prove which source snapshot, ingestion policy, and revision set produced every selected row.
Test the data pipeline before testing the signal
Useful invariants include the following.
No selected fact has
usable_atafter its decision time.Every fact has an accession number, unit, period, source URL, and retrieval timestamp.
An amended value does not appear before the amendment's release gate.
A duration fact has both a start and end date.
Duplicate facts are resolved by a documented rule rather than row order.
Changing the latency assumption changes eligibility only where the release gate crosses a decision time.
Create fixtures for a regular quarterly filing, an after-close filing, a late EDGAR submission, an amended filing, a unit change, and two facts with the same concept but different contexts. During each walk-forward test, rebuild features from the point-in-time snapshot available to that fold.
Point-in-time data does not make a signal correct. It makes the information boundary testable. The final result still depends on accounting comparability, stale observations, vendor coverage, portfolio rules, trading costs, and the difference between a public filing and a value that a real system could process in time.
More blogs to read
Public preview · Join the waitlist




