Portfolio LabKnowledgeSign inCreate account

Scenario methodology: how Portfolio Lab runs stress tests

Advanced10 min read · updated 27 October 2026 · 9 sources

The Scenarios tab on the Risk page is a stress test for today's portfolio: it calculates what a shock to equities, interest rates, the dollar, crude oil, gold or credit spreads would do, how historical crises carry over to this portfolio and which move in a factor would trigger a given loss. It is based on a linear factor model estimated from monthly returns. This page describes what the code in core/scenarios.py actually calculates.

Data and factors

The basis is the same data as on the rest of the Risk page: monthly returns of completed months in the base currency from the settings, for all positions over their common period, at the target weights of the selected portfolio (positive weights only, scaled to 100%). Positions with a short history are extended by their proxy from the grid. In addition, there are seven factors as monthly series that the app already uses elsewhere. The code loads each series individually over its full available history, so that one short factor does not cut off the others.

FactorMonthly valueSeries
Global equitiesreturn in %asset class Equities world (developed markets)
Euro rateschange in percentage pointsyield on ten-year German Bunds at month-end, earlier the monthly average
US rateschange in percentage pointsyield on ten-year US Treasuries at month-end, earlier the monthly average
US dollarreturn in %US dollar exchange rate in the base currency at month-end
Crude oilreturn in %asset class WTI crude oil (future)
Goldreturn in %asset class Gold
Creditexcess return in %USD corporate bonds (investment grade) minus US Treasuries 10y

The asset class returns are calculated in the base currency. With the US dollar as base currency (the default), the dollar factor is dropped. In another base currency such as the euro, Global equities also includes exchange rate movements, and the regression separates out the dollar through its own factor; for the credit factor, the exchange rates then cancel out except for a small cross term, because both asset classes are quoted in the same currency. If a series is missing when the data is retrieved, the page calculates without this factor and names it in a note. The interest rate series come from central bank statistics; where only monthly averages are available, they fill in only the period before the month-end values begin.

Deliberately left out of the model are euro credit spreads (the euro corporate bond series only starts in 2009), the slope of the yield curve, other currencies such as the pound, yen or Swiss franc, volatility and inflation. For these risks, either there is no long monthly series in the app, or they would overload the model at 60 months. You can recognize positions that depend mainly on them by their low R².

Regression per position

For each position, the code estimates a least squares regression of the monthly returns on all selected factors with an intercept, over the last 36, 60 or 120 common months or the entire common history; the default is 60 months, as on the rest of the page. At least 36 months are required, and at least three times as many months as there are coefficients. With all seven factors, that makes 24, so the minimum stays at 36. A factor whose series ends before the last month or is too short within the period is dropped, with a note.

rᵢₜ = αᵢ + Σₖ βᵢₖ fₖₜ + εᵢₜ R²ᵢ = 1 − SSEᵢ / SSTᵢ, residual volatility = √(SSEᵢ / (T − K − 1)) × √12 β_p,k = Σᵢ wᵢ βᵢₖ
rᵢₜ
monthly return of position i in month t
fₖₜ
value of factor k: return or change in interest rates in percentage points
βᵢₖ
beta: return per unit of the factor, for interest rates per percentage point
T, K
number of months and of factors
wᵢ
target weight of the position

The portfolio betas are the weighted sum of the betas. They match exactly a regression of the portfolio return, whose R² the page also shows. For each beta there is a t-statistic based on the classical standard errors. If the factors explain less than 50% of the variation of a position or of the portfolio, a note appears: in that case, every scenario captures only part of the risk. Closely related factors such as equities and credit, or euro and dollar interest rates, share the effect between them (multicollinearity). Individual betas then fluctuate strongly, but their sum in the scenario is well determined. If you want more stable betas, choose fewer factors.

Hypothetical scenarios

A scenario consists of shocks to one or more factors, such as equities −30% or euro rates +2 percentage points. For the remaining factors, there are two modes. Isolated, they stay at zero. With correlations (default), they take their conditional expectation, as proposed by Kupiec (1998) for stress tests: for jointly normally distributed factors with zero mean, this is the move you would expect on average if the shocked factors take exactly the specified values. The covariance matrix Σ is the sample covariance of the factors over the regression period.

f_S = s, f_U = Σ_US Σ_SS⁻¹ s ΔV / V = Σₖ β_p,k fₖ = Σᵢ wᵢ Σₖ βᵢₖ fₖ d = √(fᵀ Σ⁻¹ f)
S, U
shocked and remaining factors
s
shocks to the shocked factors
β_p,k fₖ
contribution of factor k; the contributions per factor and per position add up exactly to the impact
d
Mahalanobis distance of the whole factor vector from normal conditions, in monthly standard deviations

Alphas are not included: a shock is a deviation from normal conditions, not a month with the usual return; the code also sets the factor means to zero. Each factor value comes with its z-score fₖ/σₖ in monthly standard deviations, and the scenario as a whole with its Mahalanobis distance. According to Breuer et al. (2009), the conditional expectation is the most plausible of all possible completions of the remaining factors: its Mahalanobis distance is the smallest. Kritzman and Li (2010) use the same distance as a measure of financial turbulence. If you want to model the causes and consequences of a scenario explicitly, you can use Bayesian networks (Rebonato 2010); Portfolio Lab sticks with the simpler conditional expectation.

If a portfolio value is entered, all impacts are also shown as amounts. As a measure of uncertainty, the page shows the portfolio's residual volatility for one month. Five templates set typical shocks: Equity crash (equities −30%), Rate shock (euro rates +2 percentage points), Stagflation (equities −20%, euro rates +1.5 percentage points, crude oil +50%), Dollar weakness (US dollar −10%) and Credit crisis (credit −6%). Shocks of down to −95% are allowed for equities and crude oil, and of up to ±5 percentage points for interest rates.

Historical crises

For each stored crisis window, the code measures the move of each factor from the end of the month before the first month to the end of the last month: returns compounded as Π(1 + fₜ) − 1, interest rate changes summed. These moves act on today's portfolio through today's betas, exactly like a hypothetical scenario that specifies all factors. This means that even a fund without prices from that period can be run through the crisis. If a factor is missing even a single month in the window (crude oil goes back less far as a monthly series than the other factors), its conditional expectation given the available factors is used instead. Windows without any factor series or with months after the last completed month are dropped. Supervisory principles call for scenarios that are severe but plausible (Basel Committee on Banking Supervision 2018). Twelve windows are stored, from Black Monday to the 2025 tariff shock:

CrisisWindowCharacteristics
Black Monday10/1987Market crash in October 1987
Russian crisis08/1998Russian default, near-collapse of the hedge fund LTCM
Dotcom crash04/2000–09/2002Bursting of the tech bubble, bear market until autumn 2002
Financial crisis11/2007–02/2009Mortgage and banking crisis from the 2007 peak to the 2009 trough
Lehman collapse09/2008–10/2008The two sharpest months of the financial crisis
Euro debt crisis05/2011–09/2011Euro area debt crisis and US downgrade
Taper tantrum05/2013–06/2013Jump in bond yields after the Fed hinted at fewer bond purchases
Oil price slump and China08/2015–02/2016Yuan devaluation, falling oil price, growth worries
Late-2018 sell-off10/2018–12/2018Rate hikes and trade dispute in the fourth quarter of 2018
Covid crash02/2020–03/2020Slump at the start of the pandemic
Rate reversal and inflation01/2022–09/2022Inflation surge, equities and bonds fall together
2025 tariff shock03/2025–04/2025US tariffs, market slide and weak US dollar

If all positions have returns for every month of the window, the actual replay is shown alongside: Π(1 + Σ wᵢ rᵢₜ) − 1, reset to the target weights every month as in the risk decomposition, with proxies as in the grid. The difference between model and replay comes from the positions' residual risk, the alphas, compounding over several months (the model applies the betas to the whole move over the window) and the fact that the betas come from today's estimation period. For long windows such as the dotcom crash, it is therefore usually larger.

Reverse stress test

For a chosen factor j, the reverse stress test looks for the shock that moves the portfolio by a specified loss L; the default is 20%, the permitted range 0.5% to 90%. Because the model is linear, there is a closed-form solution. With correlations, the whole factor vector moves in direction c, i.e. per unit of factor j, each remaining factor moves by its regression slope on factor j; isolated, only the factor itself moves.

s = L / (β_pᵀ c), f = s × c with correlations cₖ = Σₖⱼ / Σⱼⱼ (so cⱼ = 1), isolated c = eⱼ
L
target impact, negative for a loss
c
direction of the scenario per unit of factor j
eⱼ
unit vector: only factor j moves

The page calculates this for all factors and marks as reachable whatever lies within the factor's permitted range. If the portfolio does not react at all in a given direction, there is no solution. A linear reverse stress test only finds the size of the shock along a fixed direction; Glasserman et al. (2015) show how to determine instead the most likely combination of factor moves behind a large loss.

Limitations

  • Linear: the model has no convexity. For large interest rate moves, a bond loses less and gains more than the linear calculation suggests (see Scenario analysis); options, leveraged products and portfolio insurance strategies react quite differently from what their beta implies.
  • Estimation period: betas and correlations come from the selected months. Correlations often rise in crises Longin and Solnik (2001); Kim and Finger (2000) therefore estimate separate correlations for stress periods. Correlations from calm years make scenarios too mild.
  • Signs can flip: whether interest rates fall or rise in an equity crash depends on the period. In years with inflation shocks, equities and interest rates move together differently than in years with growth shocks.
  • Monthly data: the model does not see slumps within a month that recover by the end of the month. Historical windows measure from month-end to month-end.
  • No probability: a scenario states a loss, but not how likely it is Berkowitz (2000). The Mahalanobis distance only ranks scenarios by plausibility; probabilities come from value at risk.
  • Choice of factors: risks outside the seven factors, such as individual stocks, sectors or emerging market currencies, end up in the residual risk. A low R² indicates this.

Frequently asked questions

What does “with correlations” mean?

The factors that are not shocked move as their correlations with the shocked factors in the estimation period would lead you to expect on average: f_U = Σ_US Σ_SS⁻¹ s. In isolated mode, they stay at zero.

Why does the model differ from the actual replay for historical crises?

The model applies today's betas to the factor moves. The positions' residual risk, alphas, compounding over several months and betas that have changed since the crisis explain the difference.

How many months does the regression need?

At least 36 common months, and at least three times as many as there are coefficients. The default is the last 60 months.

Why is the actual replay missing for some crises?

It needs returns for all positions for every month of the window. Funds launched later can be extended with a proxy in the grid; the model calculates even without one.

How is the reverse stress test solved?

Linearly and in closed form: shock = target loss / (portfolio betas times the direction of the scenario). With correlations, the remaining factors move along, by covariance divided by variance per unit.

Literature

  1. Basel Committee on Banking Supervision (2018): Stress testing principles. Bank für Internationalen Zahlungsausgleich, 17.10.2018; abgerufen am 25.10.2026. Source
  2. Berkowitz, Jeremy (2000): A coherent framework for stress testing. The Journal of Risk 2 (2), pp. 5–15. doi:10.21314/jor.2000.021
  3. Breuer, Thomas; Jandačka, Martin; Rheinberger, Klaus; Summer, Martin (2009): How to Find Plausible, Severe, and Useful Stress Scenarios. International Journal of Central Banking 5 (3), pp. 205–224. Source
  4. Glasserman, Paul; Kang, Chulmin; Kang, Wanmo (2015): Stress scenario selection by empirical likelihood. Quantitative Finance 15 (1), pp. 25–41. doi:10.1080/14697688.2014.926019
  5. Kim, Jongwoo; Finger, Christopher (2000): A stress test to incorporate correlation breakdown. The Journal of Risk 2 (3), pp. 5–19. doi:10.21314/jor.2000.026
  6. Kritzman, Mark; Li, Yuanzhen (2010): Skulls, Financial Turbulence, and Risk Management. Financial Analysts Journal 66 (5), pp. 30–41. doi:10.2469/faj.v66.n5.3
  7. Kupiec, Paul H. (1998): Stress Testing in a Value at Risk Framework. The Journal of Derivatives 6 (1), pp. 7–24. doi:10.3905/jod.1998.408008
  8. Longin, François; Solnik, Bruno (2001): Extreme Correlation of International Equity Markets. The Journal of Finance 56 (2), pp. 649–676. doi:10.1111/0022-1082.00340
  9. Rebonato, Riccardo (2010): Coherent Stress Testing: A Bayesian Approach to the Analysis of Financial Stress. Wiley. doi:10.1002/9781118374719

Full bibliography

This page describes how Portfolio Lab calculates; past results are not a forecast. All terms in the glossary.