# Clenow Weekly Momentum Rotation — System Test A survivorship-bias-free evaluation of Andreas Clenow's weekly momentum rotation (*Stocks on the Move*, 2015; *Trading Evolved*, 2019) on the Nasdaq-100 and S&P 500, on split- and dividend-adjusted prices. The full write-up — methodology, the random-portfolio (monkey) baseline, the sizing ablation, metrics-by-lookback, the sizing out-of-sample test, exposure analysis, and the annotated sample chart — is the [**Deep Dive (`index.html`)**](index.html), which is the authoritative version. This file is the headline summary. ## What it is Each week, rank the large-cap members by the annualized slope × R² of a 90-day log-price regression and hold the top 20; require each name above its 100-day SMA with a positive slope and no recent >15% gap; open new positions only when the index ETF is above its 200-day SMA; size inverse to ATR(14); exit on a broken trend, a gap, or a rank drop. ## Setup - **Universe:** point-in-time, survivorship-bias-free index membership (Nasdaq-100 ~286 ever-members; S&P 500 ~959), resolved per trading date. - **Window:** 2005-01-03 → 2026-05-15 (21.4 years). Starting capital $100,000. - **Prices:** split- and dividend-adjusted (ratio reconstruction from adjusted close) before any indicator, filter, fill price, or P&L — so a stock split is not mistaken for an overnight gap. - **Disclosure / OOS pivot:** published 2019; conservative OOS pivot 2021. - Commissions, slippage, and interest on idle cash are not modeled. ## Headline results | Metric | Nasdaq-100 system | Buy & hold QQQ | S&P 500 system | Buy & hold SPY | |---|---|---|---|---| | CAGR | 11.43% | 15.34% | 9.31% | 10.88% | | Max drawdown | −29.81% | −53.40% | −22.74% | −55.19% | | Sharpe | 0.77 | 0.77 | 0.65 | 0.64 | | Rolling 36m Calmar (median) | 0.64 | 0.90 | 0.48 | 0.62 | | Final equity ($100k) | $1,009,709 | $2,109,756 | $669,487 | $908,276 | | N trades / win rate / PF | 1,356 / 46.9% / 1.42 | — | 1,996 / 48.6% / 1.23 | — | ## Findings - **Near-index return at roughly half the drawdown.** The system captured most of the index's return while cutting the worst-case drawdown by 24–32 points, with Sharpe equal to buy-and-hold on the Nasdaq-100 and slightly above it on the S&P 500. Worst 12-month stretch: −26.1% / −15.8% vs buy-and-hold −48.0% / −47.4%. - **The stock-picking beats a random portfolio.** Against 200 random portfolios run through the identical rules, the momentum ranking lands at the 98th–99th percentile on CAGR (a +3.5 pp/yr increment over the random median) on both universes; it carries a deeper-than-typical drawdown (the cost of concentrating into names that trend together). - **The edge is concentrated in bear markets.** In 100% of rolling 12-month windows where the index fell more than 20%, the system returned more than buy-and-hold — by ~15 points (Nasdaq-100) to ~29 points (S&P 500). It captures most of the index's gain in strong bulls. - **Sizing vs. selection (ablation).** Swapping ATR sizing for equal weight lifts CAGR (NDX 12.07%, SPX 11.04%) and deepens drawdown; under both weightings the ranked book's drawdown is a low-percentile outlier, so the deep drawdown follows the selection, not the sizing. - **Sizing out-of-sample.** The Bandy safe-f fraction fitted pre-2021 is stable across the pivot and its drawdown-95 stays within the −20% target out-of-sample — the sizing is not overfit. - **Exposure.** The book holds a position on ~100% of trading days (dollar deployment ~85–86%), so its exposure-adjusted return equals its CAGR; deployment is cut to ~38–52% in 2008 and 2022. ## Reproduce ``` python prototype.py --index QQQ_Nasdaq-100 --regime-etf QQQ --start 2005-01-01 --end 2026-05-15 python prototype.py --index SPY_SandP_500 --regime-etf SPY --start 2005-01-01 --end 2026-05-15 python monkey_baseline.py --index QQQ_Nasdaq-100 --regime-etf QQQ --k 200 python ablation_weight.py --index QQQ_Nasdaq-100 --regime-etf QQQ --k 200 python refinements.py ``` The data loader and the survivorship-bias-free dataset are internal to the research platform and not redistributed; the engine and analysis code are complete in `code/`. Results are historical simulations, not investment advice.