Skip to content

Repository files navigation

H5 — M-Signal Portfolio Rotation Backtest

If you trade sector ETFs on a rotation strategy and want to know whether an M-Signal-driven allocation actually beats SPY buy-and-hold, this backtest answers that with a real, tunable exit mechanic — not a single fixed-day snapshot.

Built for systematic ETF traders, sector-rotation strategists, and quant researchers evaluating momentum-signal-driven allocation against a buy-and-hold benchmark. On each M signal, it commits alloc% of portfolio value to that ticker, funded by selling SPY, entering at T+1 open. Positions exit via a tiered profit-target mechanic: a minimum-hold floor, then evenly-spaced % tiers off the entry price, each tier selling a fixed unit-count block (100 / tier count) of the original position size, with the final tier always closing whatever remains. A Broad-market-exit mode force-liquidates every open position the moment a broad-market M signal (SPY/QQQ/DIA/IWM) fires, regardless of tier progress. A No-distinction mode widens the tradeable universe to include QQQ/DIA/IWM alongside the sector ETFs.

Exit timing is path-dependent on the full daily price series, so — unlike the old fixed-exit-day design — it doesn't reduce to a precomputable (allocation, exit-day) grid. The dashboard ships the daily OHLC + entry-signal data and recomputes the equity curve client-side in the browser on demand (the Run button), for whatever min-hold / tier-count / allocation you set on the sliders.

  • Modes: Standard, Broad-market-exit, No-distinction
  • Metrics: CAGR, Volatility, Beta, Max Drawdown, Sharpe
  • Charts: equity curve, transaction log, skip log, time-slice breakdown
  • Try the live interactive dashboard

Files

File Description
05_portfolio_rotation.py Source — writes daily OHLC/signal data and the report shell; simulate_v7() is the Python reference implementation used by tests/parity/ to keep the browser's JS port honest
v7.1/report.html Latest interactive report (open via GitHub Pages — data files must be fetched over HTTP, not opened from disk)
CHANGELOG.md Full version history
_archive/screenshots/ Screenshots of all versions

Each version outputs a folder (vX.Y/report.html + vX.Y/data/*.json). From v7.0 onward the simulation itself runs client-side, so data/ only holds the daily price series and entry signals (prices.daily.json, signals.v7.json) — no precomputed grid. See the v7.0 CHANGELOG entry for why the grid was dropped.

v7.1 is a docs/cleanup/responsive-fix pass on top of v7.0 — no simulation logic changed (confirmed via the 54/54 tests/parity/ harness); see the v7.1 CHANGELOG entry.

Version history

See CHANGELOG.md or git log for the full evolution.


About

H5 M-Signal Portfolio Rotation Backtest — vectorised ETF rotation vs SPY buy-and-hold across 36,966 exit-day x allocation combinations

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages