← Research and backtests

ML sector strategies

Development period: 2003-01-02 → 2017-12-29 (15.0 years) · trained walk-forward and retrained every month · 5 bps cost per dollar traded · Holdout (2018 to today) is still locked and unseen.

Bottom line

6 variants tried so far, so a strategy needs t ≥ 2.6 against a risk-matched SPY, plus a worst drop within its limit, to pass.

Scorecard

CAGRSharpeMax drawdownTurnover / yrExcess vs risk-matched SPY / yrt-stat vs risk-matched SPYNeeded tDrawdown limitResult
ML moderate7.2%0.37-65%1131%-3.5%-1.72.6-60%✗ FAIL
ML safe9.6%0.65-21%969%+1.7%+0.52.6-30%✗ FAIL
ML moderate (gbm)7.7%0.42-56%1395%-2.0%-1.12.6-60%✗ FAIL
ML safe (gbm)9.9%0.71-20%1192%+2.3%+0.82.6-30%✗ FAIL
Sector momentum9.1%0.50-46%589%-0.5%-0.2——reference
Buy & hold SPY9.6%0.53-55%7%————reference

Risk-matched SPY: a mix of SPY and cash with the same volatility as the strategy. The safe strategy isn't failed for being safe, and a risky one can't pass just by taking more risk. Needed t: the score the luckiest of all variants tried would beat only 2.5% of the time by chance; it rises with every variant. Sector momentum is the simple rule the ML has to beat to be worth its complexity.

Growth of $100 for each strategy, log scale
Drawdowns for each strategy

What the main (ridge) model learned

Average weight on each feature across the monthly retrains. Positive means the model favors sectors ranked high on that feature. Market-wide features are the same for every sector, so a linear model can't use them to rank sectors and their weights sit near zero; only the gbm variant can use them, through interactions.

Average weightMeaning
Last 3 months' return-0.014favors sectors low on this
Volatility, last 3 months+0.011favors sectors high on this
Last 6 months' return+0.008favors sectors high on this
Last month's return-0.007favors sectors low on this
Distance above its 200-day average+0.005favors sectors high on this
12-month return, skipping last month+0.000no real effect
Market: SPY volatility, last 3 months+0.000no real effect
Market: SPY vs its 200-day average+0.000no real effect
Market: T-bill rate+0.000no real effect
Market: change in T-bill rate, 3 months-0.000no real effect

Year by year

Blue = up, red = down; deeper shade = bigger move.

ML moderateML safeML moderate (gbm)ML safe (gbm)Sector momentumBuy & hold SPY
200335.4%29.1%26.2%25.8%25.3%24.1%
200416.7%16.7%10.0%10.0%12.6%10.7%
200512.3%12.3%0.9%0.9%17.6%4.8%
200610.4%10.4%13.9%13.9%4.6%15.8%
20074.8%4.8%15.7%15.7%9.7%5.1%
2008-43.7%0.2%-41.9%0.4%-30.1%-36.8%
20097.7%18.0%21.0%19.7%21.0%26.4%
201013.0%2.7%9.8%3.8%13.9%15.1%
2011-2.5%-4.4%2.5%-2.5%-2.2%1.9%
20125.1%2.8%16.0%14.0%7.7%16.0%
201325.7%25.7%25.4%25.4%38.3%32.3%
201411.6%11.6%18.5%18.5%10.5%13.5%
20153.7%-4.6%1.2%-8.3%1.6%1.2%
201618.8%12.3%17.4%16.1%6.7%12.0%
201713.2%13.2%1.4%1.4%14.9%21.7%

Every variant tried

Never delete rows from experiments.csv: forgotten failures are how backtests lie.

first_triedconfig
2026-10-12ML moderate | ridge | top 3 | features v1
2026-10-12ML safe | ridge | top 3 | 200-day crash filter | features v1
2026-10-12ML moderate | gbm | top 3 | features v1
2026-10-12ML safe | gbm | top 3 | 200-day crash filter | features v1
2026-10-12Day trader | ridge | SPY+QQQ 30-min blocks | enter above round-trip cost | features intraday-v1
2026-10-12Day trader | gbm | SPY+QQQ 30-min blocks | enter above round-trip cost | features intraday-v1

How it works