ML sector strategies
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.
- ✗ FAIL ML moderate: 7.2%/yr vs 9.6% for SPY · Sharpe 0.37 vs 0.53 · worst drop -65% (limit -60%) · t = -1.7, needed 2.6
- ✗ FAIL ML safe: 9.6%/yr vs 9.6% for SPY · Sharpe 0.65 vs 0.53 · worst drop -21% (limit -30%) · t = +0.5, needed 2.6
- ✗ FAIL ML moderate (gbm): 7.7%/yr vs 9.6% for SPY · Sharpe 0.42 vs 0.53 · worst drop -56% (limit -60%) · t = -1.1, needed 2.6
- ✗ FAIL ML safe (gbm): 9.9%/yr vs 9.6% for SPY · Sharpe 0.71 vs 0.53 · worst drop -20% (limit -30%) · t = +0.8, needed 2.6
Scorecard
| CAGR | Sharpe | Max drawdown | Turnover / yr | Excess vs risk-matched SPY / yr | t-stat vs risk-matched SPY | Needed t | Drawdown limit | Result | |
|---|---|---|---|---|---|---|---|---|---|
| ML moderate | 7.2% | 0.37 | -65% | 1131% | -3.5% | -1.7 | 2.6 | -60% | ✗ FAIL |
| ML safe | 9.6% | 0.65 | -21% | 969% | +1.7% | +0.5 | 2.6 | -30% | ✗ FAIL |
| ML moderate (gbm) | 7.7% | 0.42 | -56% | 1395% | -2.0% | -1.1 | 2.6 | -60% | ✗ FAIL |
| ML safe (gbm) | 9.9% | 0.71 | -20% | 1192% | +2.3% | +0.8 | 2.6 | -30% | ✗ FAIL |
| Sector momentum | 9.1% | 0.50 | -46% | 589% | -0.5% | -0.2 | — | — | reference |
| Buy & hold SPY | 9.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.
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 weight | Meaning | |
|---|---|---|
| Last 3 months' return | -0.014 | favors sectors low on this |
| Volatility, last 3 months | +0.011 | favors sectors high on this |
| Last 6 months' return | +0.008 | favors sectors high on this |
| Last month's return | -0.007 | favors sectors low on this |
| Distance above its 200-day average | +0.005 | favors sectors high on this |
| 12-month return, skipping last month | +0.000 | no real effect |
| Market: SPY volatility, last 3 months | +0.000 | no real effect |
| Market: SPY vs its 200-day average | +0.000 | no real effect |
| Market: T-bill rate | +0.000 | no real effect |
| Market: change in T-bill rate, 3 months | -0.000 | no real effect |
Year by year
Blue = up, red = down; deeper shade = bigger move.
| ML moderate | ML safe | ML moderate (gbm) | ML safe (gbm) | Sector momentum | Buy & hold SPY | |
|---|---|---|---|---|---|---|
| 2003 | 35.4% | 29.1% | 26.2% | 25.8% | 25.3% | 24.1% |
| 2004 | 16.7% | 16.7% | 10.0% | 10.0% | 12.6% | 10.7% |
| 2005 | 12.3% | 12.3% | 0.9% | 0.9% | 17.6% | 4.8% |
| 2006 | 10.4% | 10.4% | 13.9% | 13.9% | 4.6% | 15.8% |
| 2007 | 4.8% | 4.8% | 15.7% | 15.7% | 9.7% | 5.1% |
| 2008 | -43.7% | 0.2% | -41.9% | 0.4% | -30.1% | -36.8% |
| 2009 | 7.7% | 18.0% | 21.0% | 19.7% | 21.0% | 26.4% |
| 2010 | 13.0% | 2.7% | 9.8% | 3.8% | 13.9% | 15.1% |
| 2011 | -2.5% | -4.4% | 2.5% | -2.5% | -2.2% | 1.9% |
| 2012 | 5.1% | 2.8% | 16.0% | 14.0% | 7.7% | 16.0% |
| 2013 | 25.7% | 25.7% | 25.4% | 25.4% | 38.3% | 32.3% |
| 2014 | 11.6% | 11.6% | 18.5% | 18.5% | 10.5% | 13.5% |
| 2015 | 3.7% | -4.6% | 1.2% | -8.3% | 1.6% | 1.2% |
| 2016 | 18.8% | 12.3% | 17.4% | 16.1% | 6.7% | 12.0% |
| 2017 | 13.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_tried | config |
|---|---|
| 2026-10-12 | ML moderate | ridge | top 3 | features v1 |
| 2026-10-12 | ML safe | ridge | top 3 | 200-day crash filter | features v1 |
| 2026-10-12 | ML moderate | gbm | top 3 | features v1 |
| 2026-10-12 | ML safe | gbm | top 3 | 200-day crash filter | features v1 |
| 2026-10-12 | Day trader | ridge | SPY+QQQ 30-min blocks | enter above round-trip cost | features intraday-v1 |
| 2026-10-12 | Day trader | gbm | SPY+QQQ 30-min blocks | enter above round-trip cost | features intraday-v1 |
How it works
- Features (from past data only), for each sector each month-end: returns over 1, 3, 6 and 12 months (skipping the latest month), volatility, and distance from the 200-day average, each ranked against the other sectors; plus market trend, market volatility and the T-bill rate.
- Target: how the sector ranks against the others next month.
- Walk-forward training: at each month-end the model trains on every earlier month (at least 36), then predicts. It never sees a month before deciding on it.
- Portfolios: ML moderate holds the top 3 sectors, always invested. ML safe holds the same 3 but moves to T-bills when SPY ends the month below its 200-day average.
- Holdout: 2018–today stays locked until the design is final, then gets tested once. Caveat: the baseline report already showed how simple momentum did after 2018, so the holdout isn't perfectly blind.
- Same engine as the baselines: next-day fills, drift between rebalances, 5 bps costs, cash earns T-bills. Past results are not a forecast.