Interactive exploration of reverse stress testing with a portfolio of European call options, grid search over price and volatility scenarios, and Black-Scholes pricing
// Standard normal CDF (Abramowitz & Stegun approximation)normalCDF = x => {const a1 =0.254829592, a2 =-0.284496736, a3 =1.421413741const a4 =-1.453152027, a5 =1.061405429, p =0.3275911const sign = x <0?-1:1const z =Math.abs(x) /Math.sqrt(2)const t =1.0/ (1.0+ p * z)const y =1- (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t *Math.exp(-z * z)return0.5* (1+ sign * y)}
fmt = (x, d) => x ===undefined||isNaN(x) ?"N/A": x.toFixed(d)
// Black-Scholes European call pricebsCall = (S, K, T, r, sigma) => {if (T <=0) returnMath.max(0, S - K)if (sigma <=0) returnMath.max(0, S - K *Math.exp(-r * T))const d1 = (Math.log(S / K) + (r + sigma * sigma /2) * T) / (sigma *Math.sqrt(T))const d2 = d1 - sigma *Math.sqrt(T)return S *normalCDF(d1) - K *Math.exp(-r * T) *normalCDF(d2)}
Reverse Stress Testing
Instead of asking “What is the loss under scenario X?”, reverse stress testing asks “What scenarios produce the greatest losses?”(Hull 2023, sec. 16.1.6). This is done by searching over possible market conditions to find the worst case for a given portfolio.
Consider a portfolio of four European call options (inspired by Hull (2023), Example 16.1). Positive positions are long (bought), negative positions are short (written):
Position (000s)
Strike
Life (years)
+200
48
1.00
−100
58
1.25
−80
42
0.75
−60
53
0.50
Given bounds on the asset price and volatility, a grid search finds the combination that maximizes losses. The Black-Scholes formula prices each option:
\[
C = S\,N(d_1) - K\,e^{-rT}\,N(d_2)
\]
where \(d_1 = \frac{\ln(S/K) + (r + \sigma^2/2)T}{\sigma\sqrt{T}}\) and \(d_2 = d_1 - \sigma\sqrt{T}\).
Note
Plausibility matters. Not all worst-case scenarios are plausible. For example, a simultaneous drop in asset price and volatility is unusual (volatility typically rises when prices fall). Analysts should assess whether the worst case found by the search is realistic and, if not, impose tighter bounds and search again.
Tip
How to experiment
With the default bounds, the worst case may involve an extreme drop in volatility combined with a price decline. Try narrowing the volatility lower bound (e.g., from 10% to 20%) to eliminate implausible scenarios and see how the worst case changes. Also try adjusting the asset price to see how the portfolio’s risk profile shifts.
html`<p style="color:#666;font-size:0.85rem;">P&L vs asset price at worst-case volatility σ* = ${fmt(rsGridData.worstVol*100,1)}%. Red dot marks the worst case.</p>`
html`<p style="color:#666;font-size:0.85rem;">P&L vs volatility at worst-case asset price S* = ${fmt(rsGridData.worstS,1)}. Red dot marks the worst case.</p>`
References
Hull, John. 2023. Risk Management and Financial Institutions. 6th ed. John Wiley & Sons.