Every risk report ends in a single confident sentence: with 95% probability you won't lose more than X today. It is the most quoted number in finance and, in its most common form, one of the most quietly wrong. Value-at-Risk is not the problem — the assumption smuggled in underneath it is. The parametric, "Gaussian" VaR that most systems compute assumes returns follow a normal distribution: symmetric, thin-tailed, well-behaved. Markets are none of these, and the gap between the bell curve and reality is exactly where blow-ups live.
1. What VaR actually is
Value-at-Risk at confidence c is the loss your portfolio will not exceed with probability c over the horizon. The 95% VaR is the fifth-percentile loss; the 99% VaR, the first-percentile. It compresses an entire loss distribution into one threshold — clean, comparable, and easy to govern against. The only question that matters is how you find that percentile, and there are three honest ways, each seeing the tail differently.
2. Historical VaR — read the tail off the data
The empirical approach makes no distributional assumption at all: sort the realized returns, walk to the c-tail, and read off the loss. If your sample contained a crash, so does your VaR. Its strength is honesty about the shape of the past; its weakness is that it only knows the past — a tail risk that hasn't happened yet is invisible to it.
3. Where the normal curve lies
Parametric Gaussian VaR takes the mean and standard deviation and reads the percentile off a normal distribution: VaR = −(μ + z·σ), with z the standard-normal quantile at 1−c. Convenient — and, for real return series, optimistic. Returns are typically left-skewed (the big moves are disproportionately down) and fat-tailed (extremes arrive far more often than a bell curve permits). A normal fit averages those away and hands you a number that under-states the crash it is supposed to warn you about.
4. Expected Shortfall — the average of the tail
VaR names the threshold and then goes silent about everything past it — a 95% VaR says nothing about whether the worst 5% is a bad day or a catastrophe. Expected Shortfall (also called Conditional VaR) fixes that by averaging the losses beyond the VaR: the mean loss given you are in the tail. It is a coherent risk measure — it respects diversification in a way VaR does not — which is precisely why the Basel framework moved bank capital rules onto it. If you keep one number, keep this one.
5. Cornish-Fisher — put the fat tail back
You do not have to abandon the parametric approach to fix it; you can correct the quantile. The Cornish-Fisher expansion adjusts the normal z-score using the sample's actual skewness S and excess kurtosis K:
z_cf = z + (z²−1)/6·S + (z³−3z)/24·K − (2z³−5z)/36·S²
Feed in a left-skewed, fat-tailed series and z_cf pushes the VaR above the Gaussian figure — the correction that stops normal VaR from pretending the tail is thin. It is the same framework, made honest with two extra moments. We wrote up the intuition for a general audience in "Your VaR Is Lying to You".
6. Computing them
Our open-source orderflow-metrics library ships all four, dependency-free, in TypeScript and Python — including its own inverse-normal function, so there is no statistics library to install:
import { valueAtRisk, expectedShortfall, gaussianValueAtRisk, cornishFisherValueAtRisk } from "orderflow-metrics";
const returns = [0.011,-0.006,0.009,-0.021,0.014,0.004,-0.010,0.017,-0.028,0.008,0.012,-0.007];
valueAtRisk(returns, 0.95); // 0.0241 — historical 95% VaR
expectedShortfall(returns, 0.95); // 0.0280 — average loss beyond the VaR
gaussianValueAtRisk(returns, 0.95); // 0.0226 — the bell-curve figure
cornishFisherValueAtRisk(returns, 0.95); // 0.0255 — skew/kurtosis-adjusted, higher
Notice the ordering: the Gaussian VaR (0.0226) is the smallest, the Cornish-Fisher correction lifts it to 0.0255 once the tail is accounted for, and Expected Shortfall (0.0280) is larger still, because it averages the worst outcomes rather than stopping at the threshold. All are returned as positive loss magnitudes. The Python distribution exposes the same functions (value_at_risk, expected_shortfall, gaussian_value_at_risk, cornish_fisher_value_at_risk). They pair naturally with the downside-risk tools and the wider market-microstructure toolkit — install from our open-source page (npm and PyPI, MIT-licensed).
7. Conclusion
A risk number you cannot audit is a vibe, not a control. Historical VaR reads the tail straight off the data; Expected Shortfall averages what lies beyond it; Cornish-Fisher repairs the Gaussian figure with the skewness and kurtosis the bell curve ignores. Use them together and "you won't lose more than X" stops being a comforting fiction and becomes a statement you can defend. Explore the rest of the toolkit in our quantitative research library, or read the implementation in our open-source metrics.