Skip to content

How to Stress Test a Multi-Asset Portfolio

Original question

How can I stress test a multi-asset portfolio against historical financial crises and hypothetical market shocks?
Freeze today's portfolio, specify a joint move in market risk factors, and revalue each position under that move. For historical scenarios, use aligned factor changes from a chosen crisis window. For hypothetical scenarios, define a coherent set of shocks for a plausible event. Report each position's contribution to P&L, and document where the estimate depends on proxies or simplified valuation.

Define a joint shock and decide how to reprice

  1. Record positions, current prices, currency exposures and valuation date. Choose the scenario horizon before selecting the shocks.
  2. Map positions to factors such as equity indices, yield-curve tenors, credit spreads, FX rates and implied volatility. For a historical replay, measure those factor moves over the same dates. For a hypothetical event, specify the directions, magnitudes and economic mechanism linking the moves.
  3. Reprice the positions with their scenario inputs. For an initial screen, a bond's percentage price change is approximately −DrateΔy−DspreadΔs-D_{\mathrm{rate}}\Delta y-D_{\mathrm{spread}}\Delta s, where the durations measure sensitivities to the benchmark yield and spread. Use full revaluation for large or nonlinear moves.
  4. Translate to the reporting currency, add position P&L and rank the contributors. Include cash, collateral and funding effects when the scenario calls for them. Record material factors that could only be approximated.
Consider a 10 million dollar portfolio with 50% equities, 30% government bonds and 20% credit. Government bond rate duration is 7, while credit has rate duration 5 and spread duration 4.
Use a stylised crisis scenario with equities down 25%, benchmark yields down 100 basis points and credit spreads up 200 basis points. The approximate sleeve returns are −25%, +7% and −3%, for a portfolio return of −11.0%. To run a historical replay, replace these stylised values with measured returns and rate and spread changes from one shared crisis window, such as the February to March 2020 sell-off, while keeping today's holdings and risk sensitivities.

Under a hypothetical inflation shock, set equities down 20%, yields up 100 basis points and spreads up 150 basis points. The sleeve returns are −20%, −7% and −11%, producing an approximate 14.3% portfolio loss. The government bond sleeve contributes a gain in the first case and a loss in the second.

Use the actual exposures for the valuation date, then separate rate moves, spread moves and exchange-rate moves by factor. A single bond can respond to all three. If you use duration, show the convention for yield shocks and how you combine the rate and spread components. For options or large shocks, reprice when a linear approximation leaves out important curvature. Show contribution by sleeve and compare its sum with the full portfolio revaluation. A scenario is useful when you can explain where the loss came from.

Revalue the portfolio in Python

import numpy as np value = 10_000_000 weights = np.array([0.50, 0.30, 0.20]) scenarios = { "Stylised crisis": (-0.25, -100, 200), "Inflation shock": (-0.20, 100, 150), } for name, (equity_return, yield_bps, spread_bps) in scenarios.items(): rate_move, spread_move = np.array([yield_bps, spread_bps]) / 10_000 sleeve_returns = np.array([ equity_return, -7 * rate_move, -5 * rate_move - 4 * spread_move, ]) pnl = value * weights * sleeve_returns print(name, np.rint(pnl).astype(int), f"{pnl.sum() / value:.1%}")

Interactive example

See how correlation changes two-asset portfolio risk

Asset A has 15% annual volatility and asset B has 25%. Move the correlation or the long-only weight in A.

Selected portfolio volatility 15.03% · minimum-risk weight in A 80.19%
Portfolio volatility as the weight in asset A changes1520250255075100Weight in asset A (%)Annual volatility (%)
  • Portfolio volatility
  • Selected weight

References and next steps