Skip to content

How to Predict Stock Returns Without Leaking Future Information

Original question

How can I use machine learning to predict stock returns without accidentally introducing data leakage into my model?

Define the decision time, execution time and target horizon before constructing features. Join each feature using when it became available, fit preprocessing and models only on eligible history, and evaluate forward in time. Audit a few individual rows against the raw data timestamps. A good feature must be reproducible by the system operating at the stated decision time.

Give every training row three timestamps

Define a row at the close of session tt. If the strategy enters at open t+1t+1 and exits at open t+2t+2, its target return is

yt=Ot+2Ot+1−1.y_t=\frac{O_{t+2}}{O_{t+1}}-1.

Feature values can use the close at tt if your live system waits for it and executes the next day. For periodic data, use a point-in-time join keyed by the release timestamp and, where possible, the vintage actually available. Build the cross-sectional universe as it existed on the decision date, and keep assets with valid past observations even if they delisted later.

When fitting at a cutoff, include only training rows whose label ended by that cutoff. Put imputation, scaling, and feature selection inside the training fold. Run the strategy over later contiguous dates, grouping securities by decision date when the input is a panel. Compare with a zero-return, historical mean or regularised linear baseline on exactly the same rows.

A company reports quarterly revenue at 17:00 on Friday, after the 16:00 decision. Its fiscal quarter ended in September. A join on the quarter end makes the figure appear during September, and a join on a date stripped of its time makes it appear in Friday's decision. A timestamped join makes it available for the next eligible decision. If your data provider delivers it at 08:15 on Monday and you use end-of-day decisions, Monday's close is the first eligible row.

For your test, pick this release and manually verify the feature value on Thursday, Friday and Monday. Run a second assertion that changes Monday's release value and confirms Friday's feature vector stays identical. This catches regressions in an otherwise plausible merge.

A practical leakage test is to rebuild an old feature row after adding data that arrived later. The row should be identical. Apply that test to revisions as well as first releases. If a vendor replaces the original value with a restated value, the latest file alone cannot recreate what the model saw. Keep a release or ingestion timestamp and historical versions for information that can change. Use the same timestamp conventions at feature generation, fitting, and historical execution.

For a strategy implementation to compare with your dated labels and fills, inspect the code in Strategy Lab.

References and next steps