In this series of posts, we explore how to calculate various capital requirements that make up the Solvency Capital Requirement (SCR) according to Solvency II regulations.
In this post, we focus on longevity risk. We'll build a simple actuarial model for an annuity product using Python's cashflower package. Our goal is to calculate and compare liabilities under two scenarios: a base scenario (normal longevity assumptions) and a stressed scenario (decreased mortality rates, implying increased longevity).
Longevity stress is applied to products like annuities, where insurers incur greater liabilities when people live longer than expected. Products benefiting from increased mortality (e.g., term life insurance) are excluded from longevity risk calculations and instead considered under mortality risk.
By the end of this article, you'll have a practical understanding of how longevity risk is evaluated under Solvency II.
List of content:
1. Regulation
Article 186 of the Delegated Act of Solvency II states:
"The capital requirement for longevity risk shall be equal to the loss in basic own funds resulting from an instantaneous permanent decrease of 20% in the mortality rates assumed in the calculation of technical provisions."
In simpler terms, insurers must assess how much their financial position (own funds) would deteriorate if mortality rates permanently dropped by 20%, causing policyholders to live longer than expected.
2. Input
We'll illustrate the calculation using an annuity product example. The inputs are detailed below, including policy data, mortality assumptions, and financial assumptions.
2.1 Model points
We have three annuitants in our example:
- Annuitant 1: Male, age 65, monthly annuity of €1,000
- Annuitant 2: Female, age 70, monthly annuity of €1,500
- Annuitant 3: Male, age 75, monthly annuity of €1,200
# input.py
import pandas as pd
from cashflower import ModelPointSet, Runplan
policy = ModelPointSet(data=pd.DataFrame({
"monthly_annuity": [1_000, 1_500, 1_200],
"sex": ["M", "F", "M"],
"age": [65, 70, 75]
}))
2.2 Mortality data
Mortality data is obtained from the official EU data portal (data.europa.eu), filtered specifically for Austria (AT) to ensure region-specific accuracy.
assumption = dict()
assumption["mortality"] = pd.read_csv("./input/mortality_data.csv")
2.3 Other assumptions
We simplify the model by assuming a constant (instead of varying) monthly interest rate of 0.4%.
assumption["interest_rate"] = 0.004
2.4 Runplan
Two scenarios are defined:
- Version 1: Base scenario with standard mortality rates
- Version 2: Stressed scenario with mortality rates decreased by 20%
runplan = Runplan(data=pd.DataFrame({
"version": [1, 2],
"mortality_stress": [1, 0.8]
}))
3. Model
Below is the actuarial model with variables described briefly:
age(t)
@variable()
def age(t):
if t == 0:
return policy.get("age")
elif t % 12 == 0:
return age(t-1) + 1
else:
return age(t-1)
Tracks the annuitant's age over time.
mortality_rate(t)
@variable()
def mortality_rate(t):
df = assumption["mortality"]
age_t = f"Y{int(age(t))}" if age(t) < 85 else "Y_GE85"
base_rate = df.loc[(df["sex"] == policy.get("sex")) & (df["age"] == age_t), "OBS_VALUE"].values[0]
return base_rate * runplan.get("mortality_stress")
Probability of death at a specific age, adjusted by the mortality stress factor.
survival_rate(t)
@variable()
def survival_rate(t):
if t == 0:
return 1
return survival_rate(t-1) * (1 - mortality_rate(t))
Probability of survival up to each month.
expected_annuity_payment(t)
@variable()
def expected_annuity_payment(t):
return survival_rate(t) * policy.get("monthly_annuity")
Expected annuity payment considering survival probability.
liabilities(t)
@variable()
def liabilities(t):
if t == settings["T_MAX_CALCULATION"]:
return expected_annuity_payment(t)
return expected_annuity_payment(t) + liabilities(t+1) / (1 + assumption["interest_rate"]) ** (1/12)
Present value of expected future annuity payments.
4. Run and results
Run the two scenarios:
4.1 Base scenario
python run.py --version 1
Result: €169,925
4.2 Stressed scenario
python run.py --version 2
Result: €198,888
Liabilities increase in the stressed scenario due to improved longevity.
4.3 Capital requirement
Capital requirement calculation:
- BEL in base scenario: €169,925
- BEL in stressed scenario: €198,888
- Difference: €198,888 - €169,925 = €28,963
Thus, the capital requirement for longevity risk is €28,963, contributing to the total SCR.
This concludes our practical example of longevity risk calculation under Solvency II.