Skip to content

About

Machine learning equity allocation · 21.22% annualized net return (Python + C++ + SQL cache + Parquet)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Quant Portfolio

Machine learning equity allocation · Portfolio optimization · Reproducible research

A quantitative research platform that turns cross-sectional equity signals into constrained, long-only portfolios. It combines chronological model training, benchmark-relative allocation, transaction-cost accounting, and auditable performance analysis across a multi-currency equity universe.

The latest calendar-corrected Random Forest allocation achieved 21.22% annualized net return versus 17.44% for weekly equal weighting over 2022–2024 — an observed advantage of 3.79 percentage points per year.

Development backtest on previously examined data. The model carries higher volatility; these results are not independent holdout validation or live performance.

Performance · Model · Architecture · Quick start · Documentation

Performance against equal weight

Random Forest and equal-weight cumulative net returns and drawdowns, 2022–2024

The comparison uses the same equity universe, evaluation dates, EUR returns, and modeled trading costs. Equal weight is rebalanced weekly. The active strategies share the same allocation constraints; their signals differ.

Metric · 2022–2024 Random Forest Equal weight Momentum Ridge, α = 10
Annualized net return 21.22% 17.44% 18.91% 19.40%
Cumulative net return 77.97% 61.83% 68.02% 70.10%
Annualized volatility 16.05% 14.87% 15.05% 15.97%
Maximum drawdown, loss magnitude 11.72% 11.87% 10.93% 11.99%
Annual one-way turnover 3.43× 0.94× 2.47× 3.35×

The RF model delivers the highest return in this comparison, with a similar maximum drawdown to equal weight. The trade-off is 1.18 percentage points more annualized volatility and higher turnover. Momentum has the smallest drawdown of these four strategies.

Evaluation basis. Portfolios run continuously from 2020; the table measures the 2022–2024 slice, without resetting holdings each year. Returns include modeled transaction costs of 1 bp plus 2 bps slippage per unit of one-way turnover. CAGR differences use unrounded values. The curve is rebased to 100 immediately before the evaluation period.

Evidence. Figures come from the corrected calendar-20260913-v1 campaign and the matched-allocation signals-no-anchor-20260913-v1 comparison. A small benchmark snapshot with source checksums is included in the repository so these claims remain inspectable without the local research cache.

Robustness checks

Check Observed result
Double modeled trading costs, from 3 to 6 bps RF CAGR 21.18%, versus 17.40% for equal weight at the same costs
One additional global-session execution delay RF CAGR 20.32%, versus 21.22% at the reference delay
Five fixed Random Forest seeds CAGR ranges from 20.93% to 21.62%; the fixed ensemble returns 21.22%
Matched-allocation signal comparison RF exceeds momentum by 2.31 pp/year and Ridge α = 10 by 1.82 pp/year

These checks describe sensitivity within the same development sample. Paired bootstrap intervals for RF versus momentum and Ridge include zero, so the results do not establish statistically reliable superiority over those signals. The detailed performance notes record the scope and source of each check.

How the model works

1. Learn relative equity returns

A shallow Random Forest predicts each asset's 20-session forward return relative to the equal-weight benchmark. Inputs combine momentum, trend, volatility, drawdown, beta, idiosyncratic risk, and market context such as aggregate trend, volatility, and dispersion.

Training expands chronologically and refits quarterly. Only labels whose entire forward window ends before the fit date enter training. Imputation, scaling, and target clipping are fitted on training data. Predictions are standardized across assets before allocation.

The reported RF configuration uses 200 trees, depth 3, a minimum leaf size of 100, and seed 42. Its shallow structure and large leaves constrain model complexity.

2. Translate signals into portfolio weights

The optimizer balances the return signal against benchmark-relative covariance risk and turnover. The reported configuration uses:

Control Setting
Portfolio Long-only, fully invested
Rebalancing Weekly
Covariance lookback 126 sessions
Single-name cap 5%
Active-weight band ±1 percentage point around equal weight
Signal strength 0.02
Turnover penalty / cap 0.002 / 15%
Additional equal-weight anchoring penalty 0

Removing the additional anchoring penalty allows the model to express its signal within the existing active-weight band and risk constraints. Equal weight remains the benchmark and the reference for relative risk.

3. Account for execution and risk

Decisions execute with a one-global-session lag. The backtest charges initial allocations and subsequent trades, tracks explicit cash, and allows weights to drift between rebalances. Calendar-corrected returns are calculated between consecutive observed closes before assets are aligned, preserving returns when a market reopens.

The platform also implements HMM regime detection, GARCH volatility forecasts, Gaussian and Student-t Monte Carlo, and exposure overlays. These are separately evaluated research components. The headline RF result uses the allocation above; it does not attribute its return advantage to those risk modules. The tested overlays did not improve 2022–2024 CAGR.

Research and engineering

flowchart LR
    A[Adjusted prices + FX] --> B[Validated EUR returns]
    B --> C[Asset features + market context]
    C --> D[Chronological signal training]
    D --> E[Constrained allocation]
    B --> F[Covariance + optional risk models]
    F --> E
    E --> G[Lagged execution + costs]
    G --> H[Benchmark comparisons + diagnostics]
Loading
Layer Implementation
Data Versioned universe and FX definitions, incremental ingestion, quality audits, partitioned Parquet
Models scikit-learn signals, HMM regimes, covariance estimation, GARCH and Monte Carlo
Allocation CVXPY / Clarabel, position and turnover constraints, explicit cash and exposure controls
Accounting Shared portfolio simulation, delayed execution, transaction costs, daily position drift
Research Chronological folds, purged labels, signal comparisons, component ablations, block bootstrap diagnostics
Reproducibility Configuration snapshots, run identifiers, source fingerprints, SHA-256 artifact manifests, SQLite experiment records
Performance Optional C++17 / pybind11 Monte Carlo backend alongside the Python reference implementation
Quality Pytest, Ruff, mypy, Python 3.10–3.12 CI, optional C++ parity checks

Tests cover temporal leakage, portfolio accounting, optimizer constraints, calendar handling, model training boundaries, artifact integrity, and the end-to-end pipeline. The C++ backend is optional; portfolio optimization remains with the compiled Clarabel solver.

config/                  Model, execution, universe and research settings
src/quant_portfolio/
  core/                  Accounting, storage, provenance and experiment records
  models/                Statistical models, simulation and allocation
  pipeline/              Ingestion, features, backtesting and research campaigns
  main.py                Command-line interface
src/cpp/                 Optional Monte Carlo acceleration
sql/                     SQLite schema and migrations
benchmarks/              Backend performance measurements
tests/                  Deterministic and integration tests
docs/                   Methodology, setup and published result snapshots

Quick start

Requires Python 3.10+. Run commands from the repository root. Network access is needed for market-data ingestion; C++ compilation is optional.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.lock
python -m pip install -e . --no-deps

quant-portfolio --help
quant-portfolio run-all --run-id portfolio-demo-001 --with-report

run-all executes the configured regime/risk pipeline and produces a standalone HTML report under artifacts/reports/. Use a fresh run ID for each optimization. With prices already cached, add --skip-ingest.

The default pipeline is distinct from the RF research campaign shown above. Its current backtest configuration ends on December 31, 2024. Running it does not reproduce the headline RF table. That comparison depends on the archived development data and the sequence of research campaigns described in the performance notes.

To rerun the matched-signal comparison when its prerequisite local campaign is available:

quant-portfolio research-signals \
  --previous-id calendar-20260913-v1 \
  --research-id signals-review-001

Research artifacts live under data/research/<research-id>/. Raw data, fitted models, and full run histories are excluded from Git; the published result snapshot is included under docs/results/. Fresh market-data downloads can differ from the archived inputs.

For development:

python -m pip install -r requirements-dev.lock
ruff check .
ruff format --check .
mypy
pytest --cov=quant_portfolio

Interpretation and next validation

The observed return advantage is a research result with defined limits:

  • Selection history: 2022–2024 was examined across multiple research iterations. Chronological fitting protects prediction boundaries, but does not undo strategy selection on those years. Data from 2025 onward was excluded from these recent campaigns, although that period had been consulted earlier in the project.
  • Universe: the project uses a static equity snapshot, without verified point-in-time constituent history. Survivorship and selection bias remain unresolved.
  • Execution: daily adjusted prices and simplified fees do not fully model international closing times, tradability, spread variation, or market impact. The extra-delay check is a sensitivity test, not execution certification.

The next validation step is to freeze the candidate, evaluate genuinely unseen data with point-in-time membership, and test realistic execution assumptions before making investability claims.

Documentation

Guide Contents
Performance notes Published results, campaign lineage and interpretation
Getting started Installation and CLI workflow
Architecture Pipeline boundaries, storage and artifacts
Temporal contract Information, decision and execution dates
Data and features Universe, FX conversion and quality controls
Risk and allocation Optimization, cash, Monte Carlo and overlays
Evaluation and reporting Benchmarks, metrics and report generation
Tests and artifacts Verification, CI and reproducibility
C++ acceleration Build instructions and backend benchmarks

Research software. Reported performance is simulated.

About

Machine learning equity allocation · 21.22% annualized net return (Python + C++ + SQL cache + Parquet)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages