Put all three side by side on the same underlying book and one fact becomes visible immediately: when the world genuinely looks Normal, all three methods should roughly agree, and that agreement is a standing sanity check you should run on every book, every quarter, for the rest of your career, not a coincidence to celebrate once and forget. The moment they disagree materially, that disagreement is informative, not merely annoying, and it is informative in a specific, diagnosable direction:
- Historical VaR much larger than parametric VaR on the same sample is the classic fingerprint of fat tails and/or skew in the actual data that the Normal assumption cannot see, the historical method is "seeing" a real crash that happened in your sample window, while the parametric method has smoothed it away into a symmetric bell curve.
- Parametric VaR larger than historical VaR typically means your historical sample simply has not yet contained its worst-case day, a dangerous form of false comfort, because it means the assumption-free method's only defence (real, unfiltered history) hasn't been tested by history yet.
- Monte Carlo disagreeing with parametric, when both are built on the identical Normal assumption, is not informative about the market at all, it is either a bug in your simulation code or simply not enough simulated draws, and the fix is more draws or a code review, never a market interpretation.
Advertisement
This is precisely why a serious risk report never ships a single VaR number in isolation, it ships all three, side by side, and treats their spread as a risk signal in its own right, on top of whatever the middle estimate happens to be.
{
"skill": "Scaffolding the repetitive plumbing of a risk pipeline (roll-forward loops, report tables, plotting) without letting an assistant own the actual risk formulas",
"use": "Once you can already derive and hand-verify historical, parametric, and Monte Carlo VaR/ES yourself (the gate this module gives you), use a coding assistant to generate the surrounding boilerplate — a pandas rolling-window loop that recomputes VaR every day over a year of returns, a formatted comparison table of all three methods, or a matplotlib exhibit of VaR versus realized P&L — so you spend your own time on the risk logic, not on loop syntax.",
"tools": ["Coding assistants — Claude Code, GitHub Copilot, Cursor", "Chat assistants for a first-pass code skeleton — Claude, ChatGPT"],
"prompt": "I have a working, hand-verified function `historical_var_es(returns, confidence)` that returns (var, es). Write a pandas-based roll-forward loop that computes a 250-day rolling historical VaR at 99% confidence over a full return series, storing one VaR estimate per day (using only data available up to and including that day — no look-ahead), and return the result as a Series aligned to the original index. Do not change the VaR formula itself.",
"verify": "Read every line before running it — a rolling-window helper is exactly where a look-ahead bug hides (does the window truly end at day t, or does a careless `.rolling()` call include day t+1 through a shift-direction mistake?). Run it and manually check the very first non-NaN output against your own by-hand historical_var_es call on that identical slice. Then check it against the no_lookahead discipline from QD1.03: perturb a single FUTURE return far outside the current window and confirm today's VaR estimate does not change. Never trust an assistant's claim that a loop 'has no look-ahead' — verify it by breaking it on purpose.",
"diy": "You must already be able to compute historical_var_es(returns, confidence) correctly by hand on a small sample (this module's Worked Example 1 and code pack exercise QD2.02-e01) before asking an assistant to wrap it in a loop — otherwise you cannot tell a fluent-looking rolling-window bug from a correct one.",
"market": "US"
}