Lesson 7 · 30 min
Classic strategies in the library
Momentum, trend, mean reversion, risk parity — the patterns behind 1,800+ Quant Buffet strategies.
Most published quant ideas belong to a small set of families. Quant Buffet encodes them as backtest.templates and as custom code across the library. Recognising the family lets you read any strategy article in a couple of minutes, because you already know its economic story and its characteristic failure mode.
Momentum
Winners keep winning over 3–12 month horizons. Library favorite: dual_momentum (623 strategies).
Quant Buffet templates: abs_momentumdual_momentummomentum_rotation
Watch out: Crash risk when trends reverse sharply (2009, 2020).
Template cheat sheet
| Template | Economic story | Library share |
|---|---|---|
dual_momentum | Own the strongest asset, but sit in cash if the trend is negative | ≈ 35% of catalog |
abs_momentum | Own recent winners equally | ≈ 19% |
momentum_rotation | Rotate into the top-N performers each month | ≈ 14% |
sma_trend | Hold only assets above their long average | ≈ 13% |
equal_weight | Diversify naively and rebalance | ≈ 11% |
mean_reversion | Buy oversold z-scores | ≈ 6% |
vol_target / risk_parity | Size positions by volatility rather than conviction | Rare but important |
Family 1 — Trend following
Origin. Mebane Faber's 2007 paper on tactical asset allocation popularised holding an asset only while it trades above its 10-month (roughly 200-day) average. Why it might work. Investors react to news gradually and institutions de-risk slowly, so declines cluster. Characteristic failure. Choppy, range-bound markets produce whipsaws — the rule sells after a dip and rebuys higher, repeatedly.
from backtest.templates import make_sma_trend
ASSETS = ["SPY", "EFA", "TLT", "GLD", "BIL"]
def make_on_day(prices):
# Rebalances monthly; BIL almost always sits above its own average,
# so it behaves as the defensive sleeve.
return make_sma_trend(prices, ASSETS, {"sma_days": 200})Family 2 — Cross-sectional momentum
Origin. Jegadeesh and Titman (1993) showed that past 3–12 month winners kept outperforming past losers. Why it might work. Underreaction to information, plus flows that chase performance. Characteristic failure. Momentum crashes at violent turning points: in the spring of 2009, as the market bottomed and rebounded, momentum portfolios were positioned in defensive winners and suffered severe losses in weeks.
from backtest.templates import make_momentum_rotation
ASSETS = ["XLK", "XLF", "XLE", "XLV", "XLI", "XLP", "XLU", "XLY", "BIL"]
def make_on_day(prices):
# Hold the 3 strongest sectors, refreshed on each month boundary
return make_momentum_rotation(prices, ASSETS, {"lookback": 126, "top_n": 3})Family 3 — Dual momentum
Origin. Gary Antonacci (2014) combined *relative* strength (which asset is best?) with *absolute* strength (is it beating cash at all?). Why it dominates this library. It answers both questions a real allocator has, in two lines of logic. Characteristic failure. It concentrates hard: the template holds exactly one position at a time, so a single bad month is felt in full.
from backtest.templates import make_dual_momentum
ASSETS = ["SPY", "EFA", "EEM", "TLT", "GLD", "BIL"]
def make_on_day(prices):
# Holds exactly one asset: the strongest risky sleeve, or cash if none is positive
return make_dual_momentum(prices, ASSETS, {"lookback": 252, "cash_symbol": "BIL"})Family 4 — Mean reversion
Origin. De Bondt and Thaler (1985) documented long-horizon reversal; short-horizon versions became a staple of the 2000s. Why it might work. Forced selling and liquidity provision get paid. Characteristic failure. It is short volatility in disguise — it buys falling assets, so a genuine crisis is exactly when it hurts most, and its high turnover (Lesson 5) eats the edge.
from backtest.templates import make_mean_reversion
ASSETS = ["SPY", "QQQ", "IWM", "BIL"]
def make_on_day(prices):
# Buy when the 10-day z-score is stretched to the downside
return make_mean_reversion(
prices, ASSETS, {"lookback": 10, "entry_z": -1.0, "exit_z": 0.0}
)Family 5 — Risk-based allocation
Origin. Bridgewater's All Weather and Harry Browne's Permanent Portfolio; later formalised as risk parity. Why it might work. Equal *dollars* is not equal *risk* — a 60/40 portfolio is roughly 90% equity risk. Sizing by inverse volatility balances contributions instead. Characteristic failure. 2022 again: when every sleeve falls together and rates rise, a levered or duration-heavy risk-parity book has nowhere to hide.
from backtest.templates import make_risk_parity, make_vol_target
ASSETS = ["SPY", "TLT", "GLD", "DBC"]
def make_on_day(prices):
# Inverse-volatility weights from a 63-day window (about one quarter)
# Swap in make_vol_target to scale total exposure to a volatility budget instead.
return make_risk_parity(prices, ASSETS, {"vol_lookback": 63})One table to read any strategy page
| Family | Canonical source | Real-world vehicle | Where it breaks |
|---|---|---|---|
| Trend | Faber (2007) | Managed futures funds | Sideways, whipsaw markets |
| Cross-sectional momentum | Jegadeesh & Titman (1993) | MTUM | Sharp reversals (spring 2009) |
| Time-series momentum | Moskowitz, Ooi & Pedersen (2012) | CTA programmes | Rate-regime shifts |
| Mean reversion | De Bondt & Thaler (1985) | Stat-arb desks | Crises; turnover costs |
| Risk parity | Bridgewater All Weather | RPAR, NTSX | Rising rates, correlated selloffs |
Case study: run this in the IDE right now
Open any dual-momentum strategy, then make exactly these three edits, one at a time, recording Sharpe and max drawdown after each run. This is the whole research loop in five minutes.
- Baseline — run the code unchanged and write down CAGR, Sharpe, and max drawdown.
- Lookback — change
lookbackfrom 252 to 126. A faster signal reacts sooner but whipsaws more, so watch turnover as well as return. - Concentration — swap
make_dual_momentumformake_momentum_rotationwithtop_n: 3. Expect a lower CAGR but a shallower drawdown; you traded upside for stability. - Universe — swap
ASSETSfor theMULTI_ASSETbook. More sleeves usually smooth the curve and dilute the best year. - Stress window — set
startto2007-01-01and judge the strategy only on 2008 and 2022.
Where to go next
- Strategy Library — filter by momentum, mean reversion, or risk parity and read three articles in the same family to see how authors differ.
- API docs — the full reference for
ASSETS,make_on_day,PortfolioEngine, andcompute_metrics. - Platform export — take any strategy to QuantConnect, Backtrader, Zipline, VectorBT, or Freqtrade when you outgrow the lab.
- Backtest Usage in your profile — track how many runs and simulated trades your research has actually produced.
Course complete — you can now
- Explain how daily data flows into `make_on_day`.
- Name the major asset classes, their drivers, and sensible ETF proxies.
- Describe the broker / venue / platform layers and realistic cost models.
- Contrast order types with Quant Buffet's weight-based execution, and estimate turnover cost.
- Interpret Sharpe and drawdown against real benchmarks, and fix the common lab errors.
- Identify all five strategy families, their canonical papers, and their failure modes.