A life annuity is a series of payments while a given life survives.
Life annuities play a major role in life insurance. Life insurances are usually purchased by a life annuity of premiums rather than by a single premium. The amount payable at the time of claim may be converted through a settlement option into some form of life annuity for the beneficiary.
Annuities are also central in pension systems as our retirements have a form of an annuity. They also have a role in disability and workers' compensation insurances.
A life annuity may be termporary, that is, limited to a given term of years, or it may be payable for the whole of life. The payments may commence immediately or the annuity may be deferred.
Payments may be due at the beginnings of the payment intervals (annuitites-due) or at the ends of such intervals (annuities-immediate).
There are multiple types of life annuities. We will build simple models in Python using the cashflower package to illustrate their mechanism.
List of content:
Actuarial present value
In our models, we will calculate the actuarial present value of life annuities.
The table below presents the usual actuarial notation for the actuarial present value of life annuities.
Notation | Description |
---|---|
\( a_{x} \) | whole life annuity |
\( \require{enclose} a^{}_{x:} {}^{}_{\enclose{actuarial}{n}} \) | n-year temporary life annuity |
\( {}_{m|} a_{x} \) | m-year deferred whole life annuity |
Common variables
For simplicity, we will use monthly constant mortality and interest rate.
# input.py
import pandas as pd
from cashflower import ModelPointSet
assumption = {
"INTEREST_RATE": 0.005,
"DEATH_PROB": 0.003,
}
In the production actuarial cash flow models:
- mortality rates depend on the age and the sex of the policyholder,
- interest rates are a curve and vary for each future period.
It's also usual that assumptions contain yearly data that must be converted into monthly rates within the model. The examples below are simplified to focus on the calculation of the expected payment.
The common variables of the models, that we will build, are:
- survival_rate,
- expected_payment,
- actuarial_present_value.
The survival_rate and the actuarial_present_value are calculated in the same way for all types of life insurance.
# model.py
from cashflower import variable
from input import assumption, policy
from settings import settings
@variable()
def survival_rate(t):
if t == 0:
return 1
return survival_rate(t-1) * (1 - assumption["DEATH_PROB"])
The survival rate is the probability that the policyholder will survive from the beginning of the projection until the t time.
# model.py
@variable()
def actuarial_present_value(t):
if t == settings["T_MAX_CALCULATION"]:
return expected_payment(t)
return expected_payment(t) + actuarial_present_value(t+1) * 1/(1+assumption["INTEREST_RATE"])
The actuarial present value is the present value of the expected annuity payments. The discount rate is calculated as 1/(1+assumption["INTEREST_RATE"]).
Annuity models
Whole life annuity
Whole life annuity provides a policyholder with a periodic (e.g. monthly) payments as long as the policyholder lives.
# input.py
policy = ModelPointSet(data=pd.DataFrame({
"payment": [1_000]
}))
Policy data contains the value of the monthly payment which is paid to the policyholder.
# model.py
@variable()
def survival_rate(t):
if t == 0:
return 1
return survival_rate(t-1) * (1 - assumption["DEATH_PROB"])
@variable()
def expected_payment(t):
if t == 0:
return 0
return survival_rate(t) * policy.get("payment")
@variable()
def actuarial_present_value(t):
if t == settings["T_MAX_CALCULATION"]:
return expected_payment(t)
return expected_payment(t) + actuarial_present_value(t+1) * 1/(1+assumption["INTEREST_RATE"])
The policyholder will receive a payment as long as they survive.
Temporary life annuity
An n-year temporary life annuity provides a policyholder with a periodic (e.g. monthly) payments for n years.
# input.py
policy = ModelPointSet(data=pd.DataFrame({
"payment": [1_000],
"remaining_term": [36],
}))
Policy data contains the value of the monthly payment and the remaining term of the annuity. Here the remaining term is expressed in months starting the valuation period (rather than the issue date).
# model.py
@variable()
def survival_rate(t):
if t == 0:
return 1
return survival_rate(t-1) * (1 - assumption["DEATH_PROB"])
@variable()
def expected_payment(t):
if t == 0 or t > policy.get("remaining_term"):
return 0
return survival_rate(t) * policy.get("payment")
@variable()
def actuarial_present_value(t):
if t == settings["T_MAX_CALCULATION"]:
return expected_payment(t)
return expected_payment(t) + actuarial_present_value(t+1) * 1/(1+assumption["INTEREST_RATE"])
The policyholder will receive a payment as long as they survive but no longer than n-years.
Deferred whole life annuity
An m-year deferred whole life annuity provides a policyholder with a periodic (e.g. monthly) payments as long as the policyholder lives starting m years after the issue.
# input.py
policy = ModelPointSet(data=pd.DataFrame({
"payment": [1_000],
"deferral": [12],
}))
Policy data contains the value of the monthly payment which is paid to the policyholder and the deferral period. Here the deferral period is expressed in months starting from the valuation period (rather than the issue date).
# model.py
@variable()
def survival_rate(t):
if t == 0:
return 1
return survival_rate(t-1) * (1 - assumption["DEATH_PROB"])
@variable()
def expected_payment(t):
if t <= policy.get("deferral"):
return 0
return survival_rate(t) * policy.get("payment")
@variable()
def actuarial_present_value(t):
if t == settings["T_MAX_CALCULATION"]:
return expected_payment(t)
return expected_payment(t) + actuarial_present_value(t+1) * 1/(1+assumption["INTEREST_RATE"])
The policyholder will receive a payment as long as they survive starting m-years after the issue date.
Thank you for reading this blog post! I hope you found it helpful. Feel free to share your thoughts or ask any questions in the comments section below or on github. Your feedback is important to us. Happy reading!