Three things landing atomically because they're load-bearing for each other: 1. **Trend-scanning leakage fix** — trend_scanning.rs was emitting OLS slope+t-stat over a *forward* window [t, t+L]. With the Phase 1a label = sign(price[t+60] − price[t]), the forward feature window overlaps the label window, contaminating it. Purged walk-forward only sterilizes forward-looking *labels* that cross the train/val split, not forward-looking *features* that peek inside the same horizon the label measures. The leak inflated MLP accuracy from 0.49 (legacy 74-dim baseline) to 0.75 — vanished to 0.50 after switching to a trailing window. Bounded the perfect-fit t-stat sentinel from ±1e6 → ±20 (p<1e-30 is already meaningless); eliminated the 16k corruption-cap drops. 2. **Variable-dim alpha column** — fxcache schema now carries the alpha-feature width via metadata (`alpha_feature_dim`), not a compile-time constant. Same on-disk format hosts the 134-dim bar-level stack OR the 81-dim snapshot stack. Reader + auto-detect honor the metadata-declared dim; downstream MLP auto-sizes `in_dim`. Single schema, no forks. 3. **Snapshot pipeline (Phase 1c falsification)** — `snapshot_pipeline.rs`: 81-dim per-MBP10-snapshot extractor reusing 10 snapshot-native alpha blocks + 6 new snapshot-specific features (time-since-trade, time-since-snap, event-rate, spread-bps, L1-imbalance, microprice-mid drift). `precompute_features` gets `--row-unit snapshot` flag; emits one fxcache row per LOB update (1.97M rows from MBP-10 data vs 206K for bar mode). **Smoke verdict on real data** (ES.FUT, 1.97M snapshots, 384K val): - Bar-level honest alpha: accuracy=0.5005, AUC=0.5043 (no signal) - **Snapshot-level alpha**: accuracy=0.5241, AUC=0.6849 (real signal, 384K val) - GBM corroboration: accuracy=0.5401 (non-linear partitioning sees more) - Horizon decay: alpha peaks at K=20-50 snapshots (~5-25ms), gone by K=500 - Regime-conditional: spread-Q4 quintile hits 0.752 accuracy on 76k samples Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
58 lines
2.3 KiB
TOML
58 lines
2.3 KiB
TOML
[package]
|
|
name = "ml-alpha"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
description = "FoxhuntQ-Δ Phase 1a — minimal alpha-only crate for cheapest-cost falsification of bar-resolution signal hypothesis"
|
|
publish = false
|
|
|
|
# Phase 1a discipline: minimal dependency footprint to keep iteration fast.
|
|
# This crate exists to answer ONE question: does supervised alpha at the
|
|
# imbalance-bar resolution exceed validation accuracy > 0.52 (binary direction)
|
|
# on a purged walk-forward held-out fold? If yes, FoxhuntQ-Δ proceeds.
|
|
# If no, the bar-resolution hypothesis from `project_bar_resolution_is_actual_architecture`
|
|
# is confirmed and FoxhuntQ-Δ does not proceed.
|
|
#
|
|
# DESIGN INVARIANT: depends only on ml-core for GPU primitives + std + cudarc.
|
|
# NO ml, NO ml-dqn, NO ml-supervised. This keeps the cold-compile under ~2 min
|
|
# vs ~12 min for the main ml crate. If we ever NEED something from ml, refactor
|
|
# it up to ml-core first.
|
|
|
|
[features]
|
|
default = ["cuda"]
|
|
cuda = []
|
|
|
|
[dependencies]
|
|
ml-core = { workspace = true }
|
|
cudarc = { version = "0.19", default-features = false, features = ["driver", "cublas", "dynamic-linking", "std", "cuda-version-from-build-system", "f16"] }
|
|
|
|
# Standard async + error + logging plumbing
|
|
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "fs", "io-util"] }
|
|
anyhow.workspace = true
|
|
tracing.workspace = true
|
|
tracing-subscriber.workspace = true
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
thiserror.workspace = true
|
|
clap = { workspace = true, features = ["derive"] }
|
|
|
|
# Arrow IPC for fxcache reading (replaces custom binary mmap; eliminates the
|
|
# off-by-8 schema-mismatch bug class by reading dims/version from the file's
|
|
# embedded schema metadata rather than relying on compile-time constants).
|
|
arrow = { workspace = true, features = ["ipc"] }
|
|
|
|
# Deterministic RNG for shuffling, splits, weighted subsampling
|
|
rand = { workspace = true }
|
|
rand_chacha = "0.3"
|
|
|
|
# Pure-Rust gradient boosted decision trees, used as the GBM baseline for
|
|
# Phase 1a falsification (per Grinsztajn et al. NeurIPS 2022, GBM is the
|
|
# canonical baseline for ~74-dim engineered tabular features, not MLP).
|
|
# Pure Rust = no system libLightGBM/libxgboost install. If results show
|
|
# marginal signal worth chasing, can upgrade to `lightgbm3` (real LightGBM)
|
|
# in Phase 1b.
|
|
gbdt = "0.1.3"
|
|
|
|
[dev-dependencies]
|
|
tempfile = "3.10"
|