Value at Risk (VaR) is a statistical measure used to quantify the level of financial risk within a portfolio over a specific time frame. It answers the question: βWhat is the maximum expected loss with a given confidence level over a given time horizon?β
Widely used in trading, risk management, and regulatory frameworks (e.g., Basel III), VaR helps institutions understand the tail risk of their holdings.
1.Formal Definition and Example
Value at Risk (VaR) at confidence level [math] \alpha [/math] (e.g., 95% or 99%) is defined as the threshold loss value L such that:
[math]\large \mathbb{P}(\text{Loss} > L) = 1 – \alpha[/math]
Or, written differently:
[math]\large \text{VaR}_\alpha = \inf \left\{ l \in \mathbb{R} : \mathbb{P}(\text{Loss} \leq l) \geq \alpha \right\}[/math]
Some examples to make it a bit more concrete:
πΉ Example 1 β Conservative Institution
For a 1-day 99% VaR of $5 million, you expect that on 99% of trading days, your portfolio will not lose more than $5 million.
However, in the remaining 1% of days (about 2-3 days per year), the losses could exceed $5 million.
πΉ Example 2 β Moderate Risk Portfolio
For a 10-day 95% VaR of β¬2 million, there is a 95% chance that over any 10-day period, losses will not exceed β¬2 million.
Conversely, there’s a 5% chance (about one 10-day period in 20) that you could lose more than β¬2 million.
πΉ Example 3 β Intraday Trading Desk
For a 1-hour 90% VaR of Β£100,000, you are 90% confident that in any given hour, the desk will not lose more than Β£100,000.
But in 1 out of every 10 hours, losses could exceed Β£100,000.
2. How Traders Like to Vizualize VaR?
traders and risk managers often use VaR summary tables to visualize potential losses across different confidence levels, time horizons, and portfolio segments. Here’s how it’s typically structured:
β Standard VaR Table
Confidence Level | Time Horizon | VaR (USD) |
---|---|---|
95% | 1 Day | $1,200,000 |
99% | 1 Day | $2,300,000 |
95% | 10 Days | $3,800,000 |
99% | 10 Days | $7,200,000 |
- This format lets traders quickly gauge the magnitude of risk at different percentiles.
- The 10-day VaR is often used for regulatory reporting (e.g., Basel rules).
- The square-root-of-time rule is sometimes used to scale 1-day VaR to longer horizons.
β Portfolio Breakdown Table
Desk / Asset Class | 1-Day 95% VaR | 1-Day 99% VaR |
---|---|---|
Equities | $500,000 | $850,000 |
Fixed Income | $300,000 | $620,000 |
FX | $250,000 | $470,000 |
Commodities | $150,000 | $280,000 |
Total | $980,000 | $1,750,000 |
- Often used in daily risk reports.
- May include a correlation adjustment between asset classes (not a simple sum).
β 3. VaR vs. PnL Table (Backtesting)
Date | Actual PnL | 1-Day 99% VaR | Breach? |
---|---|---|---|
2025-06-18 | -$3.5M | $2.8M | β |
2025-06-19 | -$1.2M | $2.8M | β |
2025-06-20 | -$2.9M | $2.8M | β |
- Used for Value at Risk backtesting, checking how often real losses exceed VaR.
- Frequent breaches might indicate model underestimation of tail risk.
3. The Different Ways to Calculate VaR
To calculate Value at Risk (VaR), different methods are used depending on the assumptions you’re willing to make and the data available. Some approaches rely on statistical models, while others lean purely on historical data:
–The Parametric (Variance-Covariance) VaR
Assumes returns are normally distributed and calculates VaR using the portfolioβs mean, standard deviation, and the Z-score of the desired confidence level.
-The Historical Simulation VaR
Uses actual historical returns to simulate potential losses, without assuming any specific return distribution.
-The Monte Carlo Simulation VaR
Generates thousands of possible return scenarios using stochastic models (e.g., Geometric Brownian Motion) to estimate potential losses under a wide range of outcomes.
4. A Zoom on Parametric VaR
The Parametric VaR method assumes that portfolio returns are normally distributed, making it one of the fastest and most widely used VaR models in practice.
The general formula is:
[math]\large \text{VaR}_\alpha = \mu + z_\alpha \cdot \sigma[/math]
Where:
- [math]\mu[/math] = Expected return (often set to 0 for short-term horizons)
- [math]\sigma[/math] = Standard deviation (volatility) of portfolio returns
- [math]z_\alpha[/math] = Z-score for the chosen confidence level (e.g., -1.6449 for 95%, -2.3263 for 99%)
This formula gives you the threshold loss you should not exceed with probability [math]\alpha[/math].
For example, at 99% confidence, Parametric VaR tells you: βThere is only a 1% chance that the portfolio will lose more than VaR in a day.β
Because it’s simple and fast to compute, Parametric VaR is used in real-time risk monitoring, but it can underestimate tail risk when returns deviate from normality (e.g., skew or fat tails).
5. Implement Parametric VaR in C++
Here is a basic implementation, like we did elsewhere for greeks, without using any libraries:
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
#include <stdexcept>
// Compute the mean of returns
double computeMean(const std::vector<double>& returns) {
double sum = std::accumulate(returns.begin(), returns.end(), 0.0);
return sum / returns.size();
}
// Compute standard deviation of returns
double computeStdDev(const std::vector<double>& returns, double mean) {
double accum = 0.0;
for (double r : returns) {
accum += (r - mean) * (r - mean);
}
return std::sqrt(accum / (returns.size() - 1));
}
// Get Z-score for given confidence level
double getZScore(double confidenceLevel) {
if (confidenceLevel == 0.95) return -1.64485;
if (confidenceLevel == 0.99) return -2.32635;
throw std::invalid_argument("Unsupported confidence level");
}
// Compute Parametric VaR
double computeParametricVaR(const std::vector<double>& returns,
double confidenceLevel,
double portfolioValue) {
double mean = computeMean(returns); // often assumed 0 for short-term VaR
double stdDev = computeStdDev(returns, mean);
double z = getZScore(confidenceLevel);
double var = portfolioValue * (mean + z * stdDev);
return std::abs(var); // Loss is a positive number
}
int main() {
std::vector<double> returns = {-0.01, 0.003, 0.0045, -0.002, 0.005}; // Daily returns
double confidenceLevel = 0.99;
double portfolioValue = 1'000'000; // $1M
double var = computeParametricVaR(returns, confidenceLevel, portfolioValue);
std::cout << "1-day 99% Parametric VaR: $" << var << std::endl;
return 0;
}
Let’s compile it:
β build cmake ..
-- Configuring done (0.1s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/clementdaubrenet/var/build
β build make
[ 50%] Building CXX object CMakeFiles/var.dir/var.cpp.o
[100%] Linking CXX executable var
[100%] Built target var
And run it:
β build ./var
1-day 99% Parametric VaR: $14530.1
The 1-day 99% VaR for this portfolio is $14530.1.