Define
State price field, clock, window and adjustment.
FINANCIAL DATA ENGINEERING · FEATURE LAB
This lab turns prices, volume, quotes, order books and benchmark series into versioned model features. The focus is not memorizing indicators, but defining time, adjustment, window, availability and cost so the same feature can be reproduced honestly.
State price field, clock, window and adjustment.
Build rolling and cross-sectional features safely.
Detect leakage, stale quotes and corporate-action breaks.
Version reusable observations for research and models.
01 · FROM MARKET EVENT TO FEATURE
Ticker is not a permanent identity, close may be adjusted or raw, timestamps may describe event or arrival, and one market may not represent the whole order book.
02 · FIFTEEN CORE FINANCIAL FEATURES
Features overlap. RSI, momentum and MACD may carry related information; spread and Amihud illiquidity describe different liquidity aspects. Correlation and ablation tests should decide what remains—not indicator popularity.
rₜ = ln(Pₜ / Pₜ₋₁)One-period continuously compounded return; use a declared adjusted-price policy.
Window 1 · O(T)ROC_w = Pₜ/Pₜ₋w − 1Price displacement over w observations; observation count differs from calendar days.
Window w · O(T)100 − 100/(1 + avg_gain/avg_loss)Bounded transformation of smoothed gains and losses. Initialization and smoothing convention must be versioned.
Typical w=14 · incremental O(T)EMA_fast − EMA_slowDifference between two exponential trends; signal and histogram require another smoothing definition.
Typical 12/26/9 · O(T)Pₜ / MA_w − 1Scale-free distance from a rolling trend, preferable to raw price differences across instruments.
w=20/50/200 · O(T)(Pₜ − SMA_w) / SD_wPosition relative to a rolling mean and dispersion; bandwidth can be stored separately.
w=20 · O(T)Pₜ / max(P₁…Pₜ) − 1Decline from the running peak under a stated adjusted-price and start-date policy.
Expanding · O(T)SD(rₜ₋w+1…rₜ) × annualizationHistorical return dispersion. Annualization requires a declared frequency/calendar assumption.
w=20/60 · O(T)TR=max(H−L, |H−C₋₁|, |L−C₋₁|)Range-based variability including gaps; normalize by price when comparing instruments.
w=14 · O(T)(Vₜ − mean_w(V)) / sd_w(V)Unusual activity relative to the instrument’s own history; handle zero and regime shifts.
w=20 · O(T)volume / adjusted_free_floatTrading activity relative to tradable shares; denominator changes with corporate actions.
Daily/rolling · O(T)(ask−bid) / midTop-of-book quoted liquidity at one venue and time; filter locked, crossed or stale quotes.
Quote-level · O(Q)(Σbid_size−Σask_size)/(Σbid_size+Σask_size)Displayed depth imbalance for declared levels and venue; orders can be cancelled.
Depth L · O(L) per snapshotmean(|return| / traded_value)Daily price response per currency unit traded; guard against tiny or zero denominator.
Window w · O(T)Cov(rᵢ,rₘ) / Var(rₘ)Historical sensitivity to a declared benchmark, frequency and synchronized calendar.
w=60/252 · O(T)03 · SEE THE INDICATORS AS A SYSTEM
04 · PYTHON LAB: BUILD VERSIONED DAILY FEATURES
This compact example uses pandas-style operations. Production code needs instrument grouping, calendar handling, stable sorting and tests for missing and duplicate observations.
import numpy as np
import pandas as pd
def build_features(df: pd.DataFrame) -> pd.DataFrame:
x = df.sort_values(["instrument_id", "trading_date"]).copy()
g = x.groupby("instrument_id", group_keys=False)
x["log_return_1d"] = g["adjusted_close"].transform(
lambda s: np.log(s / s.shift(1)))
x["momentum_20"] = g["adjusted_close"].transform(
lambda s: s / s.shift(20) - 1)
x["sma_distance_20"] = x["adjusted_close"] / g["adjusted_close"].transform(
lambda s: s.rolling(20, min_periods=20).mean()) - 1
x["volatility_20"] = g["log_return_1d"].transform(
lambda s: s.rolling(20, min_periods=20).std())
x["volume_z_20"] = g["volume"].transform(
lambda s: (s - s.rolling(20).mean()) / s.rolling(20).std())
mid = (x["best_bid"] + x["best_ask"]) / 2
x["relative_spread"] = (x["best_ask"] - x["best_bid"]) / mid
feature_cols = ["log_return_1d", "momentum_20", "sma_distance_20",
"volatility_20", "volume_z_20", "relative_spread"]
# Example contract: a decision at date t uses features available through t-1.
x[feature_cols] = g[feature_cols].shift(1)
x["feature_version"] = "daily_market_v1"
return xYou must also verify when the source became available. A closing price may be usable after market close; a revised fundamental report must use publication and revision timestamps; corporate-action-adjusted history may be recalculated later.
05 · COMPLEXITY AND MATERIALIZATION
For A instruments, T observations and E experiments, rebuilding a linear feature set costs roughly O(EAT). A versioned feature build moves it toward O(AT) computation plus feature reads. Cross-sectional ranking can add sorting cost O(TA log A).
20 experiments × 2,000 stocks × 2,500 days × 15 features
Build once, validate once, reuse across experiments.
instrument_id + venue + feature_timestamp + feature_set_version
+ price_adjustment_version + calendar_version + source_snapshot06 · LEAKAGE AND BIAS CHECKLIST
Using close, volume or report data before it was observable at the decision time.
Training only on instruments that remain listed today.
Using retrospectively adjusted prices without recording adjustment version and purpose.
Normalizing one stock using peers that were unavailable or outside the historical universe.
Treating an old bid/ask as contemporaneous liquidity.
Joining markets with different sessions by date label rather than comparable event time.
Trying many windows and retaining only those that looked successful.
Storing or sharing derived features beyond the permitted market-data terms.
07 · STUDENT CHALLENGES
Implement log return, momentum, rolling volatility, relative spread and Amihud illiquidity from one synthetic dataset.
Compare raw close and adjusted close around a simulated 2-for-1 split; explain which features break.
Show that naive rolling computation and incremental computation produce parity within tolerance.
Create a point-in-time universe that includes delisted instruments and compare with today’s survivor-only universe.
Measure correlations among RSI, momentum, MACD and SMA distance; remove redundant features by an explicit rule.
Design a feature-store contract including market-data source, venue, calendar, adjustment and availability time.
THE CENTRAL IDEA