Portfolio LayerRisk: Low

Risk Parity

Re-size positions so every asset contributes equal risk — the Bridgewater All Weather playbook

Risk

Low

Holding Period

Matches the wrapped child strategy

Best For

Mixing assets of different vol regimes (FX + commodities + equities)

How it works

An equal-dollar portfolio gives wildly unequal *risk* contributions when asset volatilities differ — the 10% crypto slice ends up dominating daily P&L of a '50/50 stocks and crypto' book. Risk parity scales each position by 1/σ so risk contributions equalize. This is a META-strategy: plug in TSMOM (default), or any other child, and we rewrite its final_size so no single leg swamps the portfolio. Point-in-time EWMA volatility, no look-ahead.

Mathematical Foundation

weight_i = (1 / σ_i) / Σ (1 / σ_j) final_size_i = weight_i · gross_exposure

Signal Generation Logic

  1. 1Collect signals from all wrapped child strategies (default: TSMOM)
  2. 2Group signals by timestamp — each rebalance batch is normalized independently
  3. 3For every signal in a batch, look up the underlying asset's EWMA volatility observed at-or-before the signal timestamp (no look-ahead)
  4. 4Compute inverse-vol weights: w_i = (1/σ_i) / Σ (1/σ_j); pairs/baskets use the first leg as vol proxy
  5. 5Rewrite signal.final_size = w_i · gross_exposure — so the sum of |final_size| across the batch equals gross_exposure
  6. 6Relabel signal.strategy = 'risk_parity' for the backtest ledger

Parameters Explained

wrapped_strategies

Child strategies whose signals get re-sized. Default wraps TSMOM; users can substitute Carry, Pair, any subclass of Strategy.

Default

[TSMOM]
gross_exposure

Total gross |final_size| per rebalance batch. 1.0 means 'target 100% of capital deployed across all legs combined'.

Default

1
vol_halflife

EWMA halflife (bars) for the volatility estimate. Shorter = more responsive to regime change, noisier weights.

Default

30
vol_floor

Minimum annualized vol used in 1/σ. Prevents ultra-low-vol assets from dominating the weighting.

Default

0.02

When It Works

Mixing assets with very different vol regimes — e.g. FX majors (5-8% vol) + commodities (15-25%) + crypto (50-80%). Without risk parity the crypto slice would dominate daily P&L; with it, each asset contributes roughly equally.

When It Fails

When vols change fast (regime shifts), point-in-time vol lags. Also the inverse-vol formula assumes uncorrelated assets — highly correlated legs get over-weighted together. Bridgewater's real All Weather uses correlation-adjusted weights; this MVP doesn't.

Risks & Limitations

  • Not a standalone return source — wrapping a bad child strategy with risk parity gives you a bad risk-parity portfolio
  • Volatility is a lagging indicator; the weighting underweights assets right after they calm down and overweights right after they blow up
  • No correlation adjustment in this MVP — two highly-correlated legs can get nearly double the intended risk
  • Vol floor of 2% is arbitrary; tune for your asset set (crypto might want 20%)

Implementation

Meta-pattern identical to HMMRegimeStrategy: collect → reweight → relabel. Uses `dataclasses.replace` to rewrite the immutable Signal tuple. Underlying vol series resolved via _asset_underlying_series which handles direct, PAIR:, and BASKET: labels. Cache-per-asset avoids recomputing EWMA across batches.

Model parameters

Child Strategy

Default wrapped strategy — swap in backtest API

TSMOM

Gross Exposure

Total |final_size| per rebalance batch

1.0

Vol Halflife

EWMA halflife for inverse-vol weighting

30d

Vol Floor

Minimum annualized vol — prevents 1/σ blow-up

2%

Academic background

Academic Basis

Based on Qian (2005) 'Risk Parity Portfolios' — and the Bridgewater All Weather implementation framework

Backtest this strategy

Run the exact model on your selected assets and date range. See trade-by-trade performance.

Backtest This