# Value at Risk (VaR)

> How to calculate Value at Risk (VaR) on trial data: the loss at a stated exceedance probability on the EP curve, taken as an observed trial loss, with code.

Source: https://reinsurance.dev/toolkit/metrics/value-at-risk/

[Expected loss (EL)](https://reinsurance.dev/toolkit/metrics/expected-loss/) cannot distinguish a portfolio with steady losses from one with catastrophic losses. **[Value at Risk (VaR)](https://reinsurance.dev/glossary/#var-value-at-risk)** addresses this by putting a number on the **tail**: the extreme right end of the loss distribution, where the rare but severe outcomes are. VaR at confidence $\alpha$ is the loss at exceedance probability $(1-\alpha)$ on the [exceedance probability (EP) curve](https://reinsurance.dev/toolkit/distributions/): the loss reached or exceeded in only $(1-\alpha)$ of trials. At $\alpha = 0.90$, that is the 1-in-10 loss.

Unless a figure says otherwise, the numbers on this page follow the [assumptions of the Metrics overview](https://reinsurance.dev/toolkit/metrics/): the aggregate exceedance probability (AEP) basis, results at 100%, and the [20-trial demo tier](https://reinsurance.dev/toolkit/trials/#demo-scale). The [overview](https://reinsurance.dev/toolkit/metrics/#confidence-exceedance-and-return-periods) also fixes what $\alpha$ means.

## Definition and implementation

### Formal definition

For $N$ equiprobable trials sorted in descending order, the $r$-th largest loss has exceedance probability $r/N$. VaR at confidence $\alpha$ is the loss at exceedance probability $(1-\alpha)$:

$$
\text{VaR}_\alpha = L_{(k)} \quad \text{where } k = \lfloor (1-\alpha) \cdot N \rfloor
$$

where $L_{(r)}$ denotes the $r$-th largest loss. The top $k$ trials, those at or above VaR, form the tail used for [Tail Value at Risk (TVaR)](https://reinsurance.dev/toolkit/metrics/tail-value-at-risk/).

**This site's convention:** VaR is always an observed trial loss, the $k$-th largest, never a value interpolated between two ranks. Interpolating quantile definitions exist and are the default in most statistics libraries; they return a loss no trial produced. The formula leaves one more case open. When $(1-\alpha) \cdot N < 1$, which means $\alpha$ above $1 - 1/N$ and on 20 trials every quote past 1-in-20, $k = 0$: no trial sits in the tail, the trial set cannot resolve that return period, and the quote does not exist. The code returns `NaN` rather than substituting the maximum, and the [demo-scale report](https://reinsurance.dev/toolkit/trials/#demo-scale) prints the absence in words.

For continuous distributions, VaR is equivalent to the $\alpha$-quantile of the cumulative distribution function: $\inf\{x : P(L \leq x) \geq \alpha\}$. For discrete trial sets, different quantile conventions can differ by one rank position. This site uses the EP curve convention throughout: the descending-sorted losses already form an EP curve, and VaR is the loss at a single position on it.

### Business interpretation

VaR tells you: "This loss is reached or exceeded in only $(1-\alpha)$ of trials." Regulators use VaR to set minimum capital requirements: Solvency II requires capital to cover the 1-in-200 year loss ($\text{VaR}_{0.995}$).[^solvency2]

### What this means in code

Python (`python/caldera_re/var.py`, runnable on the web page):

```python
from caldera_re.aep import aep
from caldera_re.data import cedents
from caldera_re.utils import ep_index

def var(curve, alpha):
    """Compute VaR at confidence level alpha from an EP curve.

    The EP curve is sorted descending by loss (rank 1 = largest).
    VaR at alpha is the k-th largest loss, where k = ep_index(N, alpha)
    is the number of tail trials. In 0-based indexing: losses[k-1].

    VaR is always an observed trial loss -- no interpolation between
    ranks. k = 0 (alpha above 1 - 1/N) means no trial sits in the tail:
    the trial set cannot resolve that return period and the quote does
    not exist. NaN keeps that visible; falling through to losses[-1]
    would silently report the *smallest* loss.
    """
    N = len(curve)
    k = ep_index(N, alpha)
    if k < 1:
        return float('nan')
    return curve.iloc[k - 1]['loss']

if __name__ == '__main__':
    curve = aep(cedents.suncoast)

    for alpha in [0.80, 0.90, 0.95]:
        v = var(curve, alpha)
        ep = 1 - alpha
        rp = 1 / ep
        print(f"VaR({alpha:.0%}) = {v:.1f}M")
        print(f"  Reached or exceeded in {ep:.0%} of trials "
              f"(1-in-{rp:.0f} return period)")
        print()
```

:::tip[Key Insight]
VaR tells you the threshold but nothing about what happens beyond it. VaR(90%) = \$489.1M marks the boundary of the worst 10% of trials, but it does not say how severe those exceedances actually are. This is VaR's fundamental limitation, and the reason banking capital rules moved from value at risk to expected shortfall and the Swiss Solvency Test measures capital that way.[^es-shift]
:::

*[Interactive figure: Caldera metrics chart. See the web page: https://reinsurance.dev/toolkit/metrics/value-at-risk/]*

:::note[In Practice]
Throughout this chapter, we use $\alpha = 0.90$, the 1-in-10 year loss. This is appropriate for a 20-trial dataset where $k = \lfloor 20 \times 0.10 \rfloor = 2$ tail trials, enough to illustrate the concepts. In production, regulatory frameworks target much longer return periods: Solvency II uses the 1-in-200 year VaR ($\alpha = 0.995$),[^solvency2] the Swiss Solvency Test uses TVaR at the 1-in-100 return period ($\alpha = 0.99$).[^sst] At those levels the trial count determines whether the quote exists at all: $k = \lfloor (1-\alpha) \cdot N \rfloor$, so a 1-in-200 quote needs 200 trials before $k$ reaches one, and the [10,000 to 1,000,000+ trials](https://reinsurance.dev/toolkit/trials/#demo-scale) of production practice put 50 to 5,000 trials in that tail. The demo data ships a [1,000-trial tier](https://reinsurance.dev/toolkit/trials/#demo-scale) for exactly this contrast: there, the 1-in-100 quote exists and is based on ten trials, the 1-in-200 on five.
:::

VaR reads one rank and ignores the ranks above it; [TVaR](https://reinsurance.dev/toolkit/metrics/tail-value-at-risk/) averages them.

[^solvency2]: EIOPA, ["Calculation of the Solvency Capital Requirement"](https://www.eiopa.europa.eu/rulebook/solvency-ii-single-rulebook/article-2188_en), Solvency II Single Rulebook (Directive 2009/138/EC, Article 101). The Solvency Capital Requirement "shall correspond to the Value-at-Risk of the basic own funds of an insurance or reinsurance undertaking subject to a confidence level of 99,5 % over a one-year period."

[^es-shift]: Basel Committee on Banking Supervision, ["Fundamental review of the trading book: A revised market risk framework"](https://www.bis.org/publ/bcbs265.htm), consultative document, October 2013: "The proposals involve a shift in the measure of risk from value-at-risk to expected shortfall so as to better capture 'tail risk' …" The final standard, ["Minimum capital requirements for market risk"](https://www.bis.org/bcbs/publ/d457.htm), January 2019, carries the shift through: its internal models approach "relies upon the use of expected shortfall models". Both are banking rules, and insurance regimes are split: the Swiss Solvency Test has measured capital with expected shortfall since 2006, while Solvency II calibrates to VaR and the IAIS adopted its [Insurance Capital Standard](https://www.iais.org/uploads/2024/12/ICS-Level-1-and-Level-2-texts.pdf) in December 2024 on a one-year 99.5% VaR.

[^sst]: Federal Office of Private Insurance, ["Technical document on the Swiss Solvency Test"](https://www.finma.ch/finmaarchiv/bpv/download/e/sst_techdok_061002_e_wo_li_20070118.pdf), 2006, §2.4. The SST's risk measure is the expected shortfall, which the document treats as synonymous with tail value at risk, and target capital "at a certainty level of 99%" is the average of the 1% largest one-year reductions in risk-bearing capital, plus a market value margin.
