Feature Engineering for Financial Time Series
Every feature must be built from a strictly backward looking window, and normalizing returns instead of price levels prevents the most common leak.
Feature engineering for financial time series means turning raw prices, volumes, and order book snapshots into inputs whose relationship to a future label is stable enough for a model to learn, and the discipline that matters most is keeping every feature strictly backward looking relative to the moment a decision is made. Get that ordering wrong and a model that looks excellent in a backtest will lose money the first week it trades.
Every feature used to predict an outcome at a given time should be computable from information available strictly before that time, and in practice that means building each feature from a trailing window that ends at or before the decision timestamp, never a window that spans across it. A moving average of the last 20 days, a realized volatility measured over the trailing 60 minutes, and a book imbalance measured at the close of the prior bar are all legitimate. A feature built from a window centered on the event, or smoothed with a filter that looks at future values to reduce noise, is not, even when the mistake is a single row at the boundary of a rolling function.
This sounds obvious stated directly, and it is the single most common source of an inflated backtest. Common tooling for rolling statistics defaults to a centered window unless told otherwise, and a careless rolling calculation applied to a labeled data set can leak a few days of the future into a feature without raising any error. The fix is to write the feature pipeline so that it operates causally by construction, generating each row's features from a slice of history that ends at that row, rather than trusting a global transform and hoping the boundaries are honest.
Raw price levels are not stationary, and a tree or linear model trained on price levels from 2020 through 2022 will not generalize to the price levels of 2024 without a huge amount of luck, because the marginal distribution of the input has shifted entirely. Returns, log returns, z-scored deviations from a trailing mean, and ratios such as price relative to a moving average are closer to stationary and transfer across regimes far better.
The same logic applies to volume and order flow. Raw share volume grows with a stock's float and with market wide activity over multi-year horizons, so a feature built from raw volume drifts even when the underlying behavior it is meant to capture has not changed. Normalizing by a trailing average, by average daily volume, or by a cross sectional rank against the rest of the universe on the same day removes most of that drift and gives the model a consistent scale to learn against.