Why
Model results are hard to compare when data windows, targets, portfolio rules, costs, and reports change between experiments.
Tech stack
- Python
- Polars
- Parquet
- cvxpy
- QuantStats
- MLflow
Key metrics
4 portfolio builders
3 chronological split stages
What I built
- Built validated OHLCV loading, Parquet caching, feature and target helpers, and chronological splits.
- Implemented equal-weight, rank, top-k, and risk-adjusted portfolio construction.
- Added cost-aware backtests, benchmark reports, QuantStats artifacts, and MLflow tracking.
How it works
- Dataset preset
- Validated market data
- Features and targets
- Model predictions
- Portfolio weights
- Backtest and MLflow
Evaluation
- Validate dates, tickers, horizons, weights, and transaction-cost assumptions before running a strategy.
- Compare models on fixed chronological windows against SPY and equal-weight baselines.
| Stage | Current implementation | Current boundary |
|---|---|---|
| Data | Validated OHLCV and Parquet cache | No point-in-time fundamentals |
| Models | Shared prediction and weight contracts | Training remains notebook-owned |
| Portfolio | Four construction methods with costs | Long-only v1 |
| Reporting | Benchmarks, QuantStats, and MLflow | No factor-risk attribution |
Limitations
- The current data path does not guarantee point-in-time constituents or delisting-complete coverage.
- Fixed chronological splits are implemented; a rolling walk-forward runner is not.
- No strategy return is published without a frozen, reproducible comparison report.
Links and reproducibility
- Install the repository, select a TOML dataset preset, and run the documented workflow.
- Publish the preset, dates, seed, model settings, costs, predictions, weights, and generated reports together.