New to these reports? Start here
- Dotted-underlined words have a plain-English definition — hover or tap them. Every term is also on the glossary page.
- "Null" means we found nothing, not that something broke. Most reports here are negative results, on purpose — knowing an idea doesn't work is the point.
- Two questions get asked separately. First, is the effect real? Second, is it already priced into the betting odds? An effect can be completely real and still useless to bet on.
- A "calibration" row is a self-check. It runs the same method on something already known to be true. If that fails, the whole report is unreliable — so it's reported alongside the findings.
- If a confidence interval includes zero, the real effect might be nothing at all, so no claim gets made.
Strategy 002: 12-1 Cross-Sectional Momentum
Source
Jegadeesh & Titman, Returns to Buying Winners and Selling Losers (Journal of Finance, 1993). Still one of the most-replicated equity anomalies.
Thesis
Stocks that have outperformed over the past 12 months (excluding the most recent month) tend to continue outperforming for the next 1-3 months. The exclusion of the most recent month avoids capturing short-term reversal (1-week loser-winner bounce).
The mechanism is hotly debated — gradual diffusion of information, investor underreaction, behavioral anchoring, herd flows — but the effect is among the most robust in equity literature.
Formula
For each stock at month T: * Compute return from month T-12 to T-1 (skip the most recent month) * Rank universe descending * Hold top decile (~10% of universe), equal-weight * Rebalance monthly
Why it might still work in 2025
- Anomaly has survived 30+ years of academic publication
- Persists despite being well-known — institutional implementation has capacity limits (size + turnover)
- Works across asset classes (commodity futures, currencies, sectors) — not a stock-specific artifact
Why it might NOT work
- High turnover → slippage destroys the edge for retail-sized trades
- Severe drawdowns during reversal regimes (March 2009, November 2020, April 2009 — "momentum crashes")
- Our universe (~150 liquid large-caps) is too small; classic momentum tests use ~500-3,000 names
- Crowded trade since 2010+ — MTUM ETF popularized it
Implementation details
- Universe:
liquid_us(~150 US stocks) - Lookback: 12 months ending 1 month before rebalance date
- Hold count: top 15 (~10% of universe)
- Equal weight
- Rebalance: monthly
- No shorting (long-only — closer to retail-implementable)
Data requirements
- Daily prices only (no fundamentals needed)
- ~13 months of history per signal
Expected outcome
Academic literature: long-only top decile earns +8-12%/yr over equal- weight universe baseline, before transaction costs. After realistic slippage on small accounts, real-world retail experience is more like +2-5% vs SPY, with much higher drawdowns.
Test period 2015-2025 includes the 2020 momentum crash — expect a big drawdown in Q2 2020 even if overall result is positive.
Results (002b, survivorship-adjusted — 2026-06)
Running 002b (S&P 500, top 50) both ways over 2015-02 → 2026-06:
| Universe | CAGR | Alpha vs SPY | SharpeSharpe ratioReturn relative to how much it bounced around. Higher means smoother returns for the same profit. |
|---|---|---|---|
| Survivor-biased (ranks within current index members) | +25.4% | +11.3% | 1.07 |
Point-in-time (members_asof at each rebalance) |
+13.3% | −0.8% | 0.68 |
The +11pp headline alpha is a survivorship artifact: ranking momentum within today's index over history only ever picks firms that survived into the present. On a point-in-time universe — names actually in the index at each rebalance, with removed names still trading through their decline — the alpha is ≈0.
This is a conservative lower bound: 631 of 748 union tickers had cached
prices; the 117 excluded delisted names are the worst survivors, so the true
de-biased alpha is if anything lower. Caveats (data ceiling, not code): sectors
are not reconstructed point-in-time, and delisted-name price coverage is
incomplete (yfinance). Toggle via Strategy(point_in_time=...); reconstruction
lives in backtests/common/sp500.py (sp500_members_asof / load_sp500_changes).
Verdict: FAIL against the criteria below — de-biased CAGR is below SPY+3% and alpha is ~0. The original "pass" was an artifact of the biased universe.
Pass/fail criteria
- Pass: CAGR >= SPY + 3%, Sharpe > SPY's
- Marginal: CAGR within ±1% of SPY but Sharpe > SPY's (drawdown- worsening trade)
- Fail: CAGR < SPY, OR max drawdown > 60%