Value at Risk: How Banks Measure Their Worst Days¶
Every morning at every major bank on the planet, a risk report lands on a managing director’s desk. Near the top, in bold, sits a single number. It might say something like “1-day 99% VaR: $47 million.” That number is supposed to represent the maximum expected loss for that day, under normal market conditions, with 99% confidence. If tomorrow’s loss exceeds $47 million, something unusual happened.
This number is Value at Risk, usually abbreviated VaR. It is the single most important risk metric in modern finance. Regulators require it. Boards receive it. Traders are constrained by it. Capital is allocated based on it. And, crucially, it fails at exactly the moments when risk is most interesting.
VaR is simultaneously indispensable and deeply flawed. It reduces the extraordinarily complex question of “what could go wrong” into a single number that executives can glance at while drinking coffee. That is its genius and its curse. In this article, we decode what VaR actually measures, how to calculate it three different ways, where it fails, and why the industry moved to Expected Shortfall as a partial fix.
VaR is the metric that makes everyone feel informed and everyone slightly dishonest about it. Nobody trusts it completely. Nobody can imagine operating without it.
What Is Value at Risk?¶
Value at Risk answers a specific question: given my current portfolio and some assumptions about market behavior, what is the maximum loss I could experience over a given time horizon with a given confidence level?
A VaR statement has three components:
- Time horizon: 1 day, 10 days, 1 month
- Confidence level: 95%, 99%, 99.9%
- Loss amount: in dollars, euros, or as a percentage of portfolio value
So “1-day 99% VaR of $47 million” means: we expect to lose less than $47 million tomorrow with 99% probability. Put another way, we expect losses to exceed $47 million on roughly 1 day out of 100.
Formal Definition¶
If L is the loss distribution and alpha is the confidence level (e.g., 0.99 for 99%):
VaR_alpha = inf{l : P(L > l) <= 1 - alpha}
Translation: VaR at alpha confidence is the smallest loss l such that the probability of exceeding l is at most (1 - alpha). In plain English, VaR is the alpha-th percentile of the loss distribution.
Why This Matters¶
Without VaR, risk is described verbally: “we have significant exposure to tech stocks and some interest rate risk.” That is useless for decision-making. With VaR, you can say: “our 1-day 99% VaR is $47 million.” Now you can allocate capital, compare desks, set limits, and measure changes over time.
Key Insight: VaR is fundamentally a statement about normal market conditions. It tells you the boundary of the 99% of “usual” days. It tells you nothing about the 1% of days when things go seriously wrong. Those are the days that actually matter.
VaR is like a seatbelt that stays tight when you are driving normally and snaps the instant you hit a wall. Very useful for daily commutes. Terrible for crashes.
The Three Methods of Calculating VaR¶
There are three standard approaches: historical, parametric (variance-covariance), and Monte Carlo simulation. Each makes different assumptions and has different strengths.
Example Portfolio¶
Throughout this article, we use a simple portfolio:
- $1,000,000 invested in AAPL
- $500,000 invested in MSFT
- $500,000 invested in GOOGL
- Total: $2,000,000 notional
We want the 1-day 99% VaR.
Method 1: Historical Simulation VaR¶
The simplest and most intuitive method. Pull historical returns, apply them to the current portfolio, look at the loss distribution.
The Algorithm¶
- Pull N days of historical returns (say, 500 days)
- For each day, compute what the portfolio would have lost (or gained) if today’s portfolio had experienced that day’s returns
- Sort the resulting losses
- The VaR is the value at the alpha percentile
Python Implementation¶
import numpy as np
import pandas as pd
import yfinance as yf
# Download 2 years of historical data
tickers = ["AAPL", "MSFT", "GOOGL"]
prices = yf.download(tickers, start="2024-04-01", end="2026-04-01")["Close"]
# Daily returns
returns = prices.pct_change().dropna()
# Portfolio weights (current dollar exposures)
positions = pd.Series({"AAPL": 1_000_000, "MSFT": 500_000, "GOOGL": 500_000})
total = positions.sum()
# Portfolio daily returns (dollar P&L)
portfolio_pnl = (returns * positions).sum(axis=1)
# Historical VaR at 99% confidence
var_99 = -np.percentile(portfolio_pnl, 1)
print(f"1-day 99% Historical VaR: ${var_99:,.0f}")
Typical output:
1-day 99% Historical VaR: $82,450
Pros¶
- No distributional assumptions
- Captures fat tails, skew, and correlations exactly as they appear in the data
- Easy to explain to non-technical stakeholders
Cons¶
- Requires enough historical data (500+ days recommended)
- Treats every historical day equally (even 2 years ago)
- Cannot simulate extreme scenarios that are not in the data
- Silent about the “day after the worst day” problem
Historical VaR assumes the future looks like the past. That assumption has ended more risk managers’ careers than any other single sentence.
Method 2: Parametric (Variance-Covariance) VaR¶
Assumes portfolio returns are normally distributed. This lets you compute VaR from just mean and standard deviation using a simple formula.
The Formula¶
Under the normality assumption:
VaR_alpha = portfolio_value * (mu - z_alpha * sigma)
Where:
- mu = portfolio expected return
- sigma = portfolio standard deviation
- z_alpha = critical value from the standard normal distribution
- 95% confidence: z = 1.645
- 99% confidence: z = 2.326
- 99.9% confidence: z = 3.090
Usually we assume mu = 0 for short horizons (the daily expected return is tiny relative to volatility).
Python Implementation¶
# Portfolio weights (fractions)
weights = positions / total
# Mean and covariance of returns
mean_returns = returns.mean()
cov_matrix = returns.cov()
# Portfolio mean and std
portfolio_mean = (weights * mean_returns).sum()
portfolio_std = np.sqrt(weights @ cov_matrix @ weights)
# Scale to dollar amounts
z_99 = 2.326
var_99_parametric = total * (z_99 * portfolio_std - portfolio_mean)
print(f"1-day 99% Parametric VaR: ${var_99_parametric:,.0f}")
Typical output:
1-day 99% Parametric VaR: $63,280
Notice this is lower than the historical VaR. That is because the normal distribution underestimates tail risk. Real returns have fatter tails than the bell curve implies.
Pros¶
- Fast to compute
- Works with just mean, variance, and correlations
- Easy to extend to multi-asset portfolios
- Captures correlations analytically
Cons¶
- Normality assumption is wrong. Full stop.
- Underestimates tail risk systematically
- Cannot capture skew or kurtosis
- Breaks down for options and non-linear positions
Key Insight: Parametric VaR is the 1970s version of VaR. Every modern risk desk knows its limitations. The normal distribution fails where it matters most: in the tails. Real financial returns exhibit “fat tails” where extreme events are far more common than normality predicts. Nassim Taleb built an entire career pointing this out.
The normal distribution is a polite lie we tell ourselves about financial returns. It’s the statistical equivalent of “I’ll just have one drink.”
Method 3: Monte Carlo VaR¶
Instead of using historical data, simulate thousands of scenarios from an assumed model. Then apply the simulated returns to the portfolio and compute VaR from the simulated loss distribution.
The Algorithm¶
- Specify a model for asset returns (often multivariate normal with estimated mean and covariance)
- Simulate 10,000+ scenarios
- For each scenario, compute the portfolio P&L
- Sort and take the alpha percentile
Python Implementation¶
n_simulations = 10_000
# Generate random returns from multivariate normal
# Shape: (n_simulations, n_assets)
simulated_returns = np.random.multivariate_normal(
mean_returns.values,
cov_matrix.values,
size=n_simulations
)
# Compute simulated P&L for each scenario
simulated_pnl = (simulated_returns * positions.values).sum(axis=1)
# Monte Carlo VaR at 99%
var_99_mc = -np.percentile(simulated_pnl, 1)
print(f"1-day 99% Monte Carlo VaR: ${var_99_mc:,.0f}")
Typical output:
1-day 99% Monte Carlo VaR: $63,150
This is close to parametric VaR because we used the same underlying assumption (multivariate normal).
The Power of Monte Carlo¶
The real advantage is flexibility. You can:
- Replace the multivariate normal with any distribution (t-distribution for fat tails)
- Include stochastic volatility models
- Capture option payoffs exactly (no linear approximation)
- Handle path-dependent positions
# Monte Carlo with fat tails (Student's t distribution, 4 degrees of freedom)
from scipy.stats import t
df = 4 # degrees of freedom (lower = fatter tails)
# Simulate t-distributed returns with same mean and cov structure
# Cholesky decomposition for correlated draws
L = np.linalg.cholesky(cov_matrix.values)
uncorrelated = t.rvs(df, size=(n_simulations, len(tickers)))
correlated_returns = uncorrelated @ L.T + mean_returns.values
simulated_pnl_fat = (correlated_returns * positions.values).sum(axis=1)
var_99_fat = -np.percentile(simulated_pnl_fat, 1)
print(f"1-day 99% Fat-Tail Monte Carlo VaR: ${var_99_fat:,.0f}")
With fat tails, VaR typically comes out 30-50% higher.
Pros¶
- Flexible distributional assumptions
- Handles non-linear instruments (options)
- Can incorporate complex scenarios
- Produces full loss distribution, not just the VaR point
Cons¶
- Requires more computation
- Sensitive to the assumed model
- “Garbage in, garbage out”: a bad model gives bad VaR
Comparing the Three Methods¶
For our example portfolio:
| Method | VaR Estimate | Assumption |
|---|---|---|
| Historical | $82,450 | Future like the past |
| Parametric | $63,280 | Returns are normal |
| Monte Carlo (normal) | $63,150 | Returns are normal, simulated |
| Monte Carlo (fat tails) | $95,620 | Returns are t-distributed |
Notice parametric and normal Monte Carlo agree because they make the same assumption. Historical and fat-tail Monte Carlo are higher because they capture more of the real tail behavior.
Three methods. Three different answers. Each telling a partial truth. Welcome to risk management.
What Happens on the Bad Day: Expected Shortfall¶
VaR tells you the threshold. It does not tell you how bad things get when you cross it.
Example: Suppose VaR is $10 million. If your typical breach is $10.5 million, life is fine. If your typical breach is $100 million, you are in serious trouble. VaR cannot distinguish these cases.
Expected Shortfall (ES), also called CVaR (Conditional VaR), fills this gap. It is the expected loss given that the loss exceeds VaR:
ES_alpha = E[L | L >= VaR_alpha]
Python Implementation¶
# Historical Expected Shortfall
threshold = np.percentile(portfolio_pnl, 1)
tail_losses = portfolio_pnl[portfolio_pnl <= threshold]
es_99 = -tail_losses.mean()
print(f"1-day 99% Expected Shortfall: ${es_99:,.0f}")
Expected Shortfall is always greater than or equal to VaR. The ratio ES/VaR is a measure of tail severity.
Why ES Matters¶
- Coherent risk measure: ES satisfies mathematical properties that VaR violates (like sub-additivity, meaning diversification always helps)
- Basel III replaced VaR with ES for market risk capital in 2019
- Better for tail-heavy portfolios (credit, options, structured products)
- Forces risk managers to think about “how bad can it get” not just “where’s the line”
Key Insight: In 2013, the Basel Committee officially replaced VaR with Expected Shortfall at the 97.5% level as the basis for market risk capital. This was a massive shift. The reason: VaR’s silence about tail severity became indefensible after 2008. ES was not perfect either, but it was a step toward honesty.
Expected Shortfall is VaR after therapy. It still has issues, but at least it talks about its problems.
Time Scaling: From 1 Day to 10 Days¶
Regulators often require 10-day VaR. Calculating it directly requires 10-day returns, which reduces your data by a factor of 10. Instead, the Basel rule scales 1-day VaR:
VaR_10day ≈ VaR_1day * sqrt(10)
This is the square root of time rule, valid under the assumption of independent, identically distributed returns.
var_10day = var_99 * np.sqrt(10)
print(f"10-day 99% VaR: ${var_10day:,.0f}")
# About 3.16x the 1-day VaR
Caveat: The square root rule breaks when returns are autocorrelated (as they often are in crisis periods), or when volatility is clustering. It systematically underestimates VaR in stressed markets.
Backtesting: Does Your VaR Actually Work?¶
A 99% 1-day VaR should be exceeded roughly 1 day out of 100, or about 2.5 days per year. If your VaR is breached 10 times in a year, something is wrong.
The Basel “Traffic Light”¶
| Breaches per 250 days | Zone | Action |
|---|---|---|
| 0-4 | Green | Normal |
| 5-9 | Yellow | Increased scrutiny |
| 10+ | Red | Multiplier penalty |
Banks with VaR models in the red zone face higher capital requirements. This is one of the few risk metrics where the regulator literally checks your math.
Backtesting Code¶
# Expanding window backtest
def backtest_var(returns, portfolio_value, confidence=0.99, window=250):
breaches = 0
for i in range(window, len(returns)):
historical = returns.iloc[i-window:i]
var_threshold = -np.percentile(historical * portfolio_value, (1-confidence)*100)
actual_loss = -returns.iloc[i] * portfolio_value
if actual_loss > var_threshold:
breaches += 1
total_days = len(returns) - window
breach_rate = breaches / total_days
expected_rate = 1 - confidence
print(f"Breaches: {breaches} out of {total_days} days")
print(f"Breach rate: {breach_rate:.4%} (expected {expected_rate:.2%})")
The Dark Side of VaR¶
1. Procyclicality¶
VaR is based on recent data. When markets are calm, VaR is low, risk limits allow big positions, everyone takes on more risk. When markets get volatile, VaR spikes, limits force liquidation, which amplifies the volatility. VaR creates a feedback loop that makes booms bigger and busts deeper.
2. Window Effects¶
Use 250 days of data? The 2008 financial crisis fell out of the window in 2009, and suddenly bank VaR models showed much lower risk. They had not actually become safer; the data just moved on.
3. Model Risk¶
VaR depends on distributional assumptions, correlation estimates, and historical data. All of these can be wrong, and usually are wrong in the most expensive moments.
4. Games and Optimization¶
Traders learn the model. They find trades that show low VaR but high actual risk. Structured products are practically designed for this: sell disaster insurance in small chunks that show up in VaR as essentially nothing, until the disaster actually happens.
5. The Tail Ignorance Problem¶
A 99% VaR ignores what happens in the worst 1% of days. But the worst 1% of days is where crises live. A bank with a 1% chance of losing $10 billion has the same VaR as a bank with a 1% chance of losing $100 billion. They are very different banks.
The 2008 Smoking Gun¶
In the second quarter of 2007, Goldman Sachs reported daily VaR of about $90 million. By late 2008, they had lost $1.2 billion in a single day. VaR had not just been wrong. It had been wrong by more than 10x in the wrong direction, on the days that mattered most.
Key Insight: Every major financial crisis has been preceded by VaR models that looked fine. This is not because the models are stupid. It is because VaR is a backward-looking statistical measure that cannot anticipate regime change. When the world changes, VaR is always the last to notice.
VaR is like looking in the rearview mirror while driving. Fine on a straight road. Lethal on a windy one.
Beyond VaR: The Modern Risk Stack¶
Sophisticated risk desks use multiple measures together:
- VaR: Market risk summary (normal conditions)
- Expected Shortfall: Tail severity
- Stressed VaR: VaR computed using data from the worst periods
- Scenario Analysis: Specific “what if” stress tests (rates +200bps, oil crashes 50%)
- Reverse Stress Tests: What scenario would break us?
- Liquidity-Adjusted VaR: Accounts for how long it takes to exit positions
- Jump Diffusion Models: Explicitly model market discontinuities
No single number captures risk. The modern approach is a dashboard of complementary measures.
Common Pitfalls¶
Using 99% VaR as if it were 100%. VaR does not tell you what happens in the worst 1% of days. It is literally silent about them. Pairing with Expected Shortfall or stress tests is essential.
Trusting the square root of time rule. It assumes independent returns. Crises have autocorrelation. 10-day VaR calculated from 1-day VaR underestimates real 10-day risk during stressed periods.
Using too short a historical window. 250 days gives you about 1 tail event (at 99%). That is not enough for a reliable estimate. 500-1000 days is better. 10 years includes regime changes.
Ignoring non-linear instruments. Options, structured products, and credit derivatives have non-linear payoffs. Parametric VaR breaks entirely on these. Use Monte Carlo or full revaluation.
Confusing model risk with market risk. VaR is a model estimate. The number is not reality. Always report confidence intervals on VaR itself.
Decision-making on a single number. Management that only sees the VaR number never understands what the tail looks like. Risk reports should always include ES and stress scenarios alongside VaR.
Wrapping Up¶
Value at Risk is the backbone of modern market risk management. It gives executives, regulators, and boards a single number that summarizes portfolio risk under normal conditions. It is calculated billions of times per day across global financial institutions. And it is, by construction, silent about exactly the conditions that keep people up at night.
The three methods (historical, parametric, Monte Carlo) each tell part of the story. Expected Shortfall fills some of the gaps VaR leaves. Stress tests and scenario analyses fill the rest. No single number captures risk, and no sophisticated risk manager relies on one.
Understanding VaR means understanding both its mechanics and its failure modes. Use it to compare desks, set limits, and track changes over time. Do not use it to decide whether the world is safe. For that, you need judgment, stress tests, and a healthy paranoia about the 1% of days VaR refuses to discuss.
VaR tells you how much you can lose on a normal day. The whole point of risk management is to prepare for the abnormal ones. Do not confuse a progress report with a survival plan.
Cheat Sheet¶
Key Questions & Answers¶
What does Value at Risk measure?¶
VaR is the maximum expected loss over a given time horizon at a given confidence level, assuming normal market conditions. A “1-day 99% VaR of $10 million” means we expect to lose less than $10 million tomorrow with 99% probability, or equivalently, we expect losses to exceed $10 million on about 1 day in 100.
What is the difference between VaR and Expected Shortfall?¶
VaR is the threshold loss at the confidence level. Expected Shortfall is the average loss given that the threshold is breached. VaR tells you where the line is; ES tells you how bad things get when you cross it. Basel III replaced VaR with ES for market risk capital in 2019.
Which VaR method should I use?¶
Historical simulation for most portfolios (no distribution assumption, captures real tail behavior). Parametric VaR when you need speed and approximations are acceptable. Monte Carlo when you have non-linear instruments (options) or need specific distributional assumptions. In practice, most banks use all three and triangulate.
Why do regulators still use VaR despite its flaws?¶
Because it provides a standardized, comparable, auditable risk number across institutions. It is imperfect but transparent. The alternative is either no common measure or something even more complex. The regulatory response has been to pair VaR with Expected Shortfall, stress tests, and capital buffers rather than abandon it.
Key Concepts at a Glance¶
| Concept | Summary |
|---|---|
| VaR | Maximum expected loss at confidence level alpha over time horizon T |
| 1-day 99% VaR | Loss threshold exceeded on 1% of days |
| Historical VaR | Uses actual historical returns, no distribution assumption |
| Parametric VaR | Assumes normal distribution: VaR = z_alpha * sigma * value |
| Monte Carlo VaR | Simulates scenarios from a specified return model |
| Confidence levels | z(95%)=1.645, z(99%)=2.326, z(99.9%)=3.090 |
| Expected Shortfall | Average loss given loss exceeds VaR |
| Square root of time | VaR_T ≈ VaR_1 * sqrt(T), only valid under iid assumption |
| Backtesting | Compare VaR predictions to realized losses |
| Basel traffic light | 0-4 breaches: green; 5-9: yellow; 10+: red |
| Procyclicality | VaR grows in crises, forcing deleveraging that amplifies crises |
| Fat tails | Real returns have more extreme events than normal distribution predicts |
| Stressed VaR | VaR using data from worst historical periods |
| Coherent risk measure | Mathematical properties VaR violates but ES satisfies |
Sources & Further Reading¶
- Jorion, P., Value at Risk: The New Benchmark for Managing Financial Risk, McGraw-Hill
- Hull, J.C., Risk Management and Financial Institutions, Wiley
- Artzner, P., Delbaen, F., Eber, J-M., & Heath, D. (1999), Coherent Measures of Risk, Mathematical Finance
- Acerbi, C. & Tasche, D. (2002), On the Coherence of Expected Shortfall, Journal of Banking & Finance
- Basel Committee, Fundamental Review of the Trading Book
- RiskMetrics (1996), Technical Document
- Taleb, N.N., The Black Swan, Random House
- Federal Reserve, Principles for the Management of Credit Risk
- Investopedia, Value at Risk (VaR)
- Rockafellar, R.T. & Uryasev, S. (2002), Conditional Value-at-Risk for General Loss Distributions, Journal of Banking & Finance