Value at Risk (VaR) Explained: Methods, Examples and Limitations

Value at Risk (VaR) is the loss quantile of a portfolio's return distribution over a given horizon at a given confidence level — and it is simultaneously the most deployed and most criticized number in risk management. A "1-day 95% VaR of \$10,000" is the 5th-percentile loss: it is exceeded on roughly 1 day in 20, says nothing about how much you lose when it is exceeded, and is not even a coherent risk measure. This guide treats Value at Risk as an estimated quantile with real estimation error, covers the three standard methods and their tail assumptions, the square-root-of-time scaling and why it breaks, formal backtesting of the model (Kupiec and Christoffersen), and the non-subadditivity that pushed regulators toward expected shortfall.

What VaR is, precisely

VaR at confidence alpha over horizon h is defined on the loss L = -return:

VaR_alpha = the smallest L such that P(loss <= L) >= alpha

It is a quantile estimator, and like all quantile estimators of the tail it has high variance — you are estimating a point that, by construction, few observations inform. At 99% with 250 trading days, only about 2-3 observations sit beyond the threshold, so the estimate swings wildly year to year. Quoting VaR without an acknowledgment of this estimation error is a category error.

Method 1: Historical simulation

Use the empirical distribution directly — no parametric assumption:

import numpy as np

def historical_var(returns, alpha=0.95):
    return -np.quantile(returns, 1 - alpha)   # as a positive loss fraction

Assumption-free is its virtue and its weakness: the estimate cannot exceed the worst loss already in the window, so a calm sample produces a dangerously small VaR, and the estimate jumps discontinuously as extreme observations roll in and out of the lookback. Filtered historical simulation improves it: standardize each historical return by its conditional volatility (from an EWMA or GARCH model), take the quantile of the standardized residuals, then rescale by current volatility. This preserves the empirical tail shape while making VaR responsive to the current volatility regime — the single most important practical upgrade to historical VaR.

Method 2: Parametric (variance-covariance)

Assume a distribution and compute the quantile in closed form. The Gaussian version:

VaR_alpha = (z_alpha * sigma - mu) * portfolio_value

with z_alpha = 1.645 (95%) or 2.326 (99%). It needs only two moments and scales to large books via a covariance matrix, but normality systematically understates tail risk: empirically, daily equity returns have excess kurtosis of 5-30, so 4+ sigma moves occur orders of magnitude more often than a normal model allows. Two fixes without leaving the parametric world:

  • Student-t. Fit the degrees of freedom (often 3-6 for daily returns) and use the

t quantile. This directly fattens the tail.

  • Cornish-Fisher expansion. Adjust the normal quantile for sample skewness S and

excess kurtosis K:

z_cf = z + (z^2 - 1)/6 * S + (z^3 - 3z)/24 * K - (2z^3 - 5z)/36 * S^2

Cornish-Fisher gives a fat-tailed, skew-aware VaR from three moments and is a cheap, common upgrade over plain Gaussian VaR.

import numpy as np
from scipy import stats

def parametric_var(returns, alpha=0.95, method="cornish_fisher"):
    mu, sigma = returns.mean(), returns.std(ddof=1)
    if method == "gaussian":
        z = stats.norm.ppf(alpha)
    elif method == "student_t":
        nu, loc, scale = stats.t.fit(returns)
        return -(loc + scale * stats.t.ppf(1 - alpha, nu))
    else:  # cornish_fisher
        S = stats.skew(returns)
        K = stats.kurtosis(returns, fisher=True)
        z = stats.norm.ppf(alpha)
        z = (z + (z**2 - 1)/6*S + (z**3 - 3*z)/24*K
             - (2*z**3 - 5*z)/36*S**2)
    return -(mu - z*sigma)

Method 3: Monte Carlo

Simulate return paths from a chosen model and read the loss quantile. Its value is flexibility — fat-tailed marginals, nonlinear instruments (options), correlated assets via a covariance matrix or copula, and explicit scenario stress (see Monte Carlo simulation). Its trap is that output quality equals input model quality: a Gaussian Monte Carlo has exactly the same tail blindness as Gaussian parametric VaR. Monte Carlo does not add tail realism for free; it only propagates whatever distribution you assume.

Estimation error: a VaR is a confidence interval

For an empirical quantile estimator, the asymptotic standard error at probability p = 1 - alpha with density f at the quantile and sample size n is:

SE(quantile) ≈ sqrt( p * (1 - p) / n ) / f(VaR)

The f(VaR) in the denominator is small in the tail, so the standard error is large and grows as alpha rises. Concretely, a 99% historical VaR on one year of daily data can have a confidence interval spanning ±30% of the point estimate. Report VaR as a range, and prefer 95-97.5% over 99% for historical methods unless you have years of data or are using EVT.

Scaling across horizons and why sqrt-time fails

The square-root-of-time rule VaR(h) ≈ VaR(1) * sqrt(h) assumes IID returns with zero autocorrelation and constant volatility. Both fail in practice:

  • Autocorrelation. With lag-1 autocorrelation rho, the variance of the h-period

sum scales by roughly h + 2sum_{k=1}^{h-1}(h-k)rho^k instead of h. Positive autocorrelation (trending) makes sqrt-time understate multi-day VaR; mean reversion overstates it.

  • Volatility clustering. Vol is forecastable and time-varying, so a constant-sigma

scaling is wrong precisely during the stressed periods VaR is meant to protect against.

Treat scaled multi-day VaR as a rough guide, and for regulatory horizons prefer directly simulating the h-day distribution.

Backtesting the VaR model (and you must)

A VaR model is only credible if its breach rate matches its confidence level. Two standard tests:

  • Kupiec proportion-of-failures (POF) test. A likelihood-ratio test that the

observed breach frequency equals 1 - alpha. Too many breaches means the model understates risk; too few means it wastes capital.

  • Christoffersen independence test. Breaches must be independent over time, not

clustered. Clustered breaches (several in a row during a stress) signal that the model fails to update for volatility regimes — the classic failure of unconditional historical VaR.

import numpy as np
from scipy import stats

def kupiec_pof(breaches, alpha=0.99):
    x = int(np.sum(breaches)); n = len(breaches)
    p = 1 - alpha; pi = x / n if n else 0.0
    if pi in (0.0, 1.0):
        return np.nan
    lr = -2 * (np.log((1-p)**(n-x) * p**x)
               - np.log((1-pi)**(n-x) * pi**x))
    return lr, 1 - stats.chi2.cdf(lr, df=1)   # statistic, p-value

Regulators require this breach-counting exercise; you should run it on any internal VaR model before trusting it.

The structural flaws: tail blindness and non-subadditivity

VaR reports the threshold, never the average loss beyond it. Two books with an identical 95% VaR can have a 10% versus a 40% expected tail loss; VaR cannot distinguish them. Worse, VaR is not subadditive: there exist portfolios A and B where VaR(A+B) > VaR(A) + VaR(B), violating the principle that diversification should never increase risk. This happens with skewed or discrete payoffs (credit, deep-OTM options) and makes VaR unsound for risk aggregation across desks.

MeasureReportsCoherent?Sees tail shape?
VolatilityTwo-sided dispersionn/aNo
VaRThreshold lossNoNo
CVaR / ESMean loss beyond VaRYesYes

Conditional VaR (CVaR / expected shortfall) averages the losses beyond VaR, is coherent (subadditive), and describes the tail rather than its edge:

def cvar(returns, alpha=0.95):
    var = -np.quantile(returns, 1 - alpha)
    tail = returns[returns <= -var]
    return -tail.mean() if len(tail) else var

The Basel Fundamental Review of the Trading Book moved bank capital from 99% VaR to 97.5% expected shortfall for exactly these reasons. See conditional VaR explained for the full treatment, including coherent CVaR optimization, and extreme value theory for modeling the tail beyond the data.

How VaR is gamed

  • Sample selection. Computing historical VaR over a deliberately calm lookback.
  • Tail stuffing. Selling far-OTM options earns premium while keeping losses just

inside the VaR threshold most of the time — VaR looks small until the tail event, which is exactly what VaR cannot see.

  • Frequency and marking. Monthly marks or smoothed valuations suppress measured

volatility and the quantile.

  • Confidence-level shopping. Quoting whichever of 95%/99% flatters the book.

Honest limitations and use in trading

VaR assumes you can liquidate at marked prices; in a crash, the act of liquidating moves the market against you, so realized losses exceed any static VaR. It is a single-period, distribution-level snapshot that ignores the path — pair it with maximum drawdown for path risk and volatility measurement for the input. In practice: set position limits on VaR and CVaR, report both at 95% and 97.5%, run explicit historical stress scenarios (2008, 2020, rate shocks) alongside the statistical estimate, recalibrate volatility and correlation inputs continuously, and never present VaR as a worst case — it is a threshold, not a ceiling. For sizing, combine it with the Kelly criterion and broader risk management.

Conclusion

Value at Risk compresses a loss distribution into one comparable quantile, which made it ubiquitous — but it is a high-variance tail estimate, blind to losses beyond the threshold, fragile under sqrt-time scaling, and not coherent for aggregation. Use a fat-tailed or filtered-historical method, report the estimation interval, backtest the breach rate with Kupiec and Christoffersen, and always pair it with CVaR, stress testing, and a clear-eyed respect for fat tails. No single number captures every way a portfolio can lose money.

#value at risk #VaR #risk management #tail risk #quant finance