C++ for Quants
  • Home
Category:

VaR

Value at Risk
VaR

Value at Risk (VaR): Definition, Equation, and C++ Implementation

by Clement Daubrenet June 24, 2025

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 LevelTime HorizonVaR (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 Class1-Day 95% VaR1-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)

DateActual PnL1-Day 99% VaRBreach?
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.

June 24, 2025 0 comments

@2025 - All Right Reserved.


Back To Top
  • Home