Skip to content

Backtests of stocks vs T-bills over 10 years, conditioned on starting valuation (Shiller CAPE (Cyclically Adjusted Price-to-Earnings), Excess CAPE Yield, TSX dividend yield, T-bill level). Covers the US from 1926 and Canada from 1956, all in total return. It also tests no-look-ahead timing rules: lump sum, 12- and 36-month DCA (dollar-cost averaging), valuation-only, trend-only, and valuation + trend.

Built for the SDC Market Down Wins project. Origin task: Market-timing-refined-analysis (2026-09-24).

Terminal window
cd ~/projects/cape-timing
uv run python scripts/run_all.py # results/results.json; asserts the data gates
uv run python scripts/build_report.py # report/cape-timing-report.html

To refresh data, re-download the snapshots listed in the repo README.md into data/raw/, then rerun both commands.

  • The XIC.TO adj_close in the asset-history snapshot stops adjusting after 2025-09. The script rebuilds total return from close + dividend_amount instead.
  • Shiller P is a monthly average price. Trend rules are backtested on CRSP (Center for Research in Security Prices) month-end returns, because averaged prices flatter momentum.
  • Report n_eff, not month counts. Overlapping 10-year windows are not independent, so every bucket reports its episode count and n_eff (months ÷ 120).
  • No current Canadian CAPE. StatCan’s P/E series ends in 2016.