Chapter 13 Laboratory — Module 13: The Risk Office¶
Mathematical Foundations of Modern Finance · Part IV · Week 13
Four panels: the coherence-axioms panel, the VaR/ES measure panel, the robustness panel, and the backtesting-audit panel. Reproduces the two-bond (−4, 98) VaR subadditivity violation that convicts VaR, and confirms that expected shortfall is coherent.
Seeds: 20261301–20261304.
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams.update({"figure.figsize": (7, 4.2), "axes.grid": True,
"grid.alpha": 0.3, "font.size": 11})
BRASS, INK = "#B4884A", "#0F1E3D"
import mfmf_engine_ch13 as eng
E1 — The two-bond example that convicts VaR (supports LOS 13.1–13.3)¶
Two defaultable bonds, each defaulting with 4% probability. At the 95% level each standalone VaR is negative (default sits in the 5% tail), but the diversified portfolio's VaR is positive: VaR is not subadditive. Expected shortfall, a tail mean, is.
r1 = eng.E1_var_subadditivity()
print("Value-at-Risk (95%):")
print(f" bond 1: {r1['VaR_bond1']:+.1f} bond 2: {r1['VaR_bond2']:+.1f}")
print(f" sum of standalones: {r1['VaR_sum']:+.1f}")
print(f" portfolio : {r1['VaR_portfolio']:+.1f}")
print(f" VaR violates subadditivity: {r1['VaR_violates_subadditivity']} (book: -4 vs 98)")
print()
print("Expected Shortfall:")
print(f" sum of standalones: {r1['ES96_sum']:.1f}")
print(f" portfolio : {r1['ES96_portfolio']:.1f}")
print(f" ES is subadditive : {r1['ES_is_subadditive']}")
fig, ax = plt.subplots()
ax.bar(["VaR sum", "VaR portfolio"], [r1['VaR_sum'], r1['VaR_portfolio']],
color=[INK, BRASS])
ax.axhline(0, color="grey", lw=1)
ax.set_ylabel("95% VaR"); ax.set_title("E1: portfolio VaR exceeds the sum — subadditivity fails")
plt.tight_layout(); plt.show()
Value-at-Risk (95%): bond 1: -2.0 bond 2: -2.0 sum of standalones: -4.0 portfolio : +98.0 VaR violates subadditivity: True (book: -4 vs 98) Expected Shortfall: sum of standalones: 102.1 portfolio : 100.1 ES is subadditive : True
E2 — VaR and ES across confidence levels (supports LOS 13.2–13.3)¶
Meridian's loss distribution, measured at 95% and 99%. The Rockafellar–Uryasev objective's minimum lands at the ES, and its minimizer is the VaR.
r2 = eng.E2_measure()
for k, v in r2['figures'].items():
print(f"{k:8s}: {v:.1f}")
print(f"Panel reference figures ($M): {r2['panel_targets']}")
losses = np.random.default_rng(1).normal(0, 250, 200000)
ru = eng.rockafellar_uryasev(losses, 0.99)
print(f"\nRockafellar-Uryasev minimizer (VaR): {ru['argmin_z']:.1f}")
print(f"RU minimum value (ES) : {ru['min_value']:.1f}")
print(f"Empirical VaR : {ru['empirical_VaR']:.1f}")
VaR_95 : 411.2 ES_95 : 515.7 VaR_99 : 581.6 ES_99 : 666.3 Panel reference figures ($M): [426, 546, 625, 737]
Rockafellar-Uryasev minimizer (VaR): 578.8 RU minimum value (ES) : 667.0 Empirical VaR : 579.9
E3 — Robustness: ES over an ambiguity box (supports LOS 13.4–13.5)¶
When the loss distribution's parameters are themselves uncertain, sweep ES over a $(\mu, \sigma)$ box. The worst-case ES is the robust risk number — larger than the nominal by a quantifiable premium.
r3 = eng.E3_robustness()
print(f"Nominal 99% ES : {r3['nominal_ES99']:.1f}")
print(f"Worst-case 99% ES : {r3['worst_case_ES99']:.1f}")
print(f"Robustness premium : {r3['robustness_premium']:.1f}")
Nominal 99% ES : 666.3 Worst-case 99% ES : 829.6 Robustness premium : 163.3
E4 — Backtesting and detection power (supports LOS 13.5–13.6)¶
If the model understates true volatility by 15%, how many years does the exception test need to reject it at 95% power? The answer has direct governance implications.
r4 = eng.E4_backtest()
print(f"Model understates volatility by : {r4['understate_pct']:.0f}%")
print(f"Model 99% VaR : {r4['model_VaR']:.3f}")
print(f"Years to reject at 95% power : {r4['years_to_95pct_power']}")
Model understates volatility by : 15% Model 99% VaR : 1.977 Years to reject at 95% power : 1000
Validation checks¶
Every laboratory report must reproduce these; a report whose checks do not pass is returned ungraded.
checks = eng.validation_checks()
for k, v in checks.items():
if k.startswith("_"): continue
print(f"[{'PASS' if v else 'FAIL'}] {k}")
assert checks["ALL_PASS"], "Validation failed — do not submit."
print("\nAll Module validation checks pass.")
[PASS] V1_VaR_violates_subadditivity [PASS] V2_ES_subadditive [PASS] V3_RU_min_is_ES [PASS] V4_robust_ES_exceeds_nominal [PASS] ALL_PASS All Module validation checks pass.