Status: DONE (2026-08-15) · Suite: 260 passed (9 new tests in tests/test_alpaca_dataset.py)
What was built
| File | Role |
|---|---|
data/alpaca/labels.py | Executable labels for the long/flat bar system |
data/alpaca/dataset.py | Dataset assembly, persistence, walk-forward split tooling |
Labels (labels.py)
The bar-close signal must be executable: a signal read at bar t close enters at
the next open and exits h bars later at the open — the only honest leg
(this matches the repo's PANEL open-entry book).
- Primary label:
y[t] = open[t+1+h] / open[t+1] - 1(executable, long/flat). - Research label:
y_cc[t] = close[t+h] / close[t] - 1— not the executable leg; kept only for IC diagnostics side-by-side withy. hmust be ≥ 1 (raising otherwise); NaN only at tail rows that lack the futuret+1+hbar — never imputed.add_labels()merges labels onto a Phase-2 feature frame on the bar-close timestamp grid; if feature/bars lengths diverge (dropped/duplicate bars) it reindexes labels onto the feature timestamps instead of assuming alignment.
Dataset assembly (dataset.py)
assemble_dataset(symbol, timeframe, h)— features + labels, then:- drop tail rows with NaN
y(never impute); - optional warmup drop (rolling-feature warmup rows);
- enforce fixed schema
[timestamp, symbol, y, y_cc] + FEATURE_SCHEMA[2:].
- drop tail rows with NaN
- Persistence:
data/processed/alpaca/datasets/{SYM}/{TF}/h{h}.parquetwith a strict pyarrow schema (dataset_schema(), ns timestamps), safe reload. build_all_datasets(...)bulk-builds (symbol × timeframe × horizon).
Walk-forward splits (leakage-free by construction)
wf_splits(ts, n_splits, gap_bars)— reference-based, expandable splits over the sorted timestamp axis: splitktests intervalkwith train = all rows before it minus an embargo ofgap_barsrows. Earlier splits carry less history (the honest walk-forward property); no randomized/CV splitting.leakage_check(train_ts, test_ts, gap_bars)— asserts the actual timestamps of train/test respect the embargo before training starts (ground-truth check, converts to ns for exact timedelta math).
Tests (tests/test_alpaca_dataset.py, isolated dirs → tmp)
forward_open_returnexact math (andforward_close_return);add_labelsalignment, incl. reindex path when bars are dropped;- tail rows without future label dropped; warmup trim;
- dataset save/load round-trip with strict schema;
wf_splitsinvariants + embargo respected (gap_barshonored in timestamps);leakage_checkraises on overlap.
Integration notes
- Datasets are inputs to Phase 4 (per-symbol walk-forward trainer): config
defaults
gap_bars = config.ml.embargo_bars(50 for the PANEL-style monthly cadence; crypto runs use same default), horizons(1, 5, 12, 24). - Real datasets get built after the historical backfill completes (Phase 1/2 raw/feature stores are currently being repopulated 2021→now).