quant-ai / tests /test_no_future_leak.py
Ypeng12's picture
feat: 10/10 HRT style point-in-time alpha research platform, purged walk-forward CV, risk parity & test suite
b54319d
Raw
History Blame Contribute Delete
1.73 kB
import pytest
import pandas as pd
import numpy as np
from src.data.hf_loader import HuggingFaceETFLoader
from src.features.momentum import FeaturePipeline
from src.labels.excess_returns import calculate_forward_excess_returns
def test_zero_future_leakage():
"""
CRITICAL UNIT TEST:
Verifies that for every observation at date t, all feature values depend strictly on history <= t,
and forward label evaluation starts at date >= t+1.
"""
# Create clean test dataset
df_raw = HuggingFaceETFLoader.generate_synthetic_prices(["SPY", "QQQ", "TLT"], num_days=100)
# Feature engineering
pipeline = FeaturePipeline(lookback_windows=[5, 20])
df_feat = pipeline.transform(df_raw)
# Label calculation
df_labeled = calculate_forward_excess_returns(df_feat, horizons=[5])
# Check that for any row i at date t:
# fwd_ret_5d uses price at t+1 and price at t+6
valid_rows = df_labeled.dropna(subset=["fwd_ret_5d", "cs_z_mom_20d"])
for idx, row in valid_rows.iterrows():
date_t = row["date"]
symbol = row["symbol"]
# Verify that feature mom_20d uses only prices <= date_t
past_prices = df_raw[(df_raw["symbol"] == symbol) & (df_raw["date"] <= date_t)]["close"]
assert len(past_prices) >= 20, "Feature must have 20 historical prices"
# Verify forward return calculation starts after date_t
future_prices = df_raw[(df_raw["symbol"] == symbol) & (df_raw["date"] > date_t)]["close"]
assert len(future_prices) >= 6, "Forward label requires future prices > date_t"
print("[TEST PASSED] Zero future leakage verified successfully!")
if __name__ == "__main__":
test_zero_future_leakage()