Recursion#
Using annual values provided we can calculate other values at other ages and durations by applying recursion formulas and other actuarial identities.
Chain rule#
\(_{t+n}p_x =\ _np_x \cdot\ _tp_{x+n}\)
survival probability chain rule
\(_{t+n}E_x =\ _nE_x \cdot\ _tE_{x+n}\)
pure endowment chain rule
Expected future lifetime#
For both complete and curtate future lifetime, we can decompose the formula for the life expectancy of \((x)\) into a temporary life expectancy, plus the probability of surviving till the end of that term times the remaining life expectancy.
\(e_{x} = e_{x:\overline{m|}} +\ _mp_x\ e_{x+m}\)
recursion formula for curtate expectation of lifetime
\(\overset{\circ}{e}_{x} = \overset{\circ}{e}_{x:\overline{m|}} +\ _mp_x\ \overset{\circ}{e}_{x+m}\)
recursion formula for complete expectation of lifetime
\(e_{x:\overline{m+n|}} = e_{x:\overline{m|}} +\ _mp_x\ e_{x:\overline{n|}}\)
recursion formula for limited curtate expectation of lifetime
\(\overset{\circ}{e}_{x:\overline{m+n|}} = \overset{\circ}{e}_{x:\overline{m|}} +\ _mp_x\ \overset{\circ}{e}_{x+m:\overline{n|}}\)
recursion formula for limited complete expectation of lifetime
\(e_{x} = p_x(1 + e_{x+1})\)
special case of a one-year recursion formula for curtate expectaion of lifetime
\(\overset{\circ}{e}_{x} = \overset{\circ}{e}_{x:\overline{1|}} + p_x\ \overset{\circ}{e}_{x+1}\)
special case of a one-year recursion formula for complete expectation of lifetime
\(e_{x:\overline{1|}} = p_x\)
shortcut for one-year limited curtate expectaion of lifetime
Life insurance#
\(A_{x} = v ~ q_x + v ~ p_x ~ A_{x+1} ~\Rightarrow~ A_{x+1} = \dfrac{A_{x} - v ~ q_x}{v ~ p_x}\)
whole life insurance recursion
\(A^{1}_{x:\overline{t|}} = v ~ q_x + v ~ p_x ~ A^{1}_{x+1:\overline{t-1|}} \)
term life insurance recursion
\(A^{1}_{x:\overline{1|}} = v ~ q_x \)
shortcut for one-year term life insurance
\(^{2}A^{1}_{x:\overline{1|}} = v^2 ~ q_x\)
shortcut for second moment of one-year term life insurance
\(A_{x:\overline{0|}} =~ _0E_x = 1\)
endowment insurance at end of term is pure endowment
\(A_{x:\overline{1|}} = q_x ~ v + p_x ~ v = v\)
shortcut for one-year endowment insurance
\(^2A_{x:\overline{1|}} = v^2\)
shortcut for second moment of one-year endowment insurance
\(IA^{1}_{x:\overline{t|}} = v ~ q_x + v ~ p_x ~ (A_{x+1} + IA^{1}_{x+1:\overline{t-1|}})\)
increasing insurance recursion
\(DA^{1}_{x:\overline{t|}} = t ~ v ~ q_x + v ~ p_x ~ (DA^{1}_{x+1:\overline{t-1|}})\)
decreasing insurance recursion
Life annuities#
\(\ddot{a}_{x} = 1 + v ~ p_x ~ \ddot{a}_{x+1} ~\Rightarrow ~\ddot{a}_{x+1} = \dfrac{\ddot{a}_{x} - 1}{v ~ p_x}\)
whole life annuity recursion
\(\ddot{a}_{x:\overline{t|}} = 1 + v ~ p_x ~ \ddot{a}_{x+1:\overline{t-1|}} \)
temporary annuity recursion
\(\ddot{a}_{x:\overline{1|}} = 1\)
shortcut for one-year temporary annuity
Methods#
The Recursion class implements methods to apply recursive, shortcut and actuarial formulas, and traces the steps taken to find the solution.
Caveats:
Not all possible recursion rules and actuarial equations have (yet) been implemented in the present version of the package.
You may set the recursion depth to a larger limit than the default of 3 (with the keyword argument
depthwhen initializing a Recursion class object).But generally, the current implementation may be fragile if the solution is not available within a relatively shallow search.
Notes:
If a colab or jupyter notebook is auto-detected, the steps are displayed in latex format; else as raw text.
These display options can be changed by calling the
blog_optionsstatic method
from actuarialmath import Recursion, ConstantForce, Contract
import describe
describe.methods(Recursion)
class Recursion - Solve by appling recursive, shortcut and actuarial formulas repeatedly
Args:
depth : maximum depth of recursions (default is 3)
verbose : whether to echo recursion steps (True, default)
Notes:
7 types of function values can be loaded for recursion computations:
- 'q' : (deferred) probability (x) dies in t years
- 'p' : probability (x) survives t years
- 'e' : (temporary) expected future lifetime, or moments
- 'A' : deferred, term, endowment or whole life insurance, or moments
- 'IA' : decreasing life insurance of t years
- 'DA' : increasing life insurance of t years
- 'a' : deferred, temporary or whole life annuity of t years, or moments
Methods:
--------
set_q(val, x, s, t, u):
Set mortality rate u|t_q_[x+s] to given value
set_p(val, x, s, t):
Set survival probability t_p_[x+s] to given value
set_e(val, x, s, t, curtate, moment):
Set expected future lifetime e_[x+s]:t to given value
set_E(val, x, s, t, endowment, moment):
Set pure endowment t_E_[x+s] to given value
set_A(val, x, s, t, u, b, moment, endowment, discrete):
Set insurance u|_A_[x+s]:t to given value
set_IA(val, x, s, t, b, discrete):
Set increasing insurance IA_[x+s]:t to given value
set_DA(val, x, s, t, b, discrete):
Set decreasing insurance DA_[x+s]:t to given value
set_a(val, x, s, t, u, b, variance, discrete):
Set annuity u|_a_[x+s]:t to given value
blog_options(latex, notebook):
Static method to change display options for tracing the recursion steps
Examples#
The given values of functions are set by calling the respective “setter” methods set_q, set_p, set_e, set_E, set_A, set_IA, set_DA, or set_a. Then derived function values, at other ages or durations, can be computed – the successful recursion steps taken are displayed if the verbose flag is initiated to True (which is the default value).
AMLCR2 Exercise 2.6
Given \(P_x =0.99\) , \(P_{x+1} = 0.985\), \(_3P_{x+1} = 0.95\), \(q_{x+3} = 0.02\),
Calculate (a) \(P_{x+3}\), (b) \(_2P_x\), (c) \(_2P_{x+1}\), (d) \(_3P_x\), (e) \(_{1|2}q_x\).
from actuarialmath.recursion import Recursion
x = 0
life = Recursion(depth=3).set_interest(i=0.06)\
.set_p(0.99, x=x)\
.set_p(0.985, x=x+1)\
.set_p(0.95, x=x+1, t=3)\
.set_q(0.02, x=x+3)
print(life.p_x(x=x+3), 0.98)
print(life.p_x(x=x, t=2), 0.97515)
print(life.p_x(x=x+1, t=2), 0.96939)
print(life.p_x(x=x, t=3), 0.95969)
print(life.q_x(x=x, t=2, u=1), 0.03031)
0.98 0.98
0.9751500000000001 0.97515
0.9693877551020409 0.96939
0.9596938775510204 0.95969
0.030306122448979567 0.03031
SOA Question 6.40
For a special fully discrete whole life insurance, you are given:
The death benefit is \(1000(1.03)^k\) for death in policy year k, for \(k = 1, 2, 3...\)
\(q_x = 0.05\)
\(i = 0.06\)
\(\ddot{a}_{x+1} = 7.00\)
The annual net premium for this insurance at issue age x is 110
Calculate the annual net premium for this insurance at issue age \(x + 1\).
print("SOA Question 6.40: (C) 116 ")
x = 0
life = Recursion().set_interest(i=0.06).set_a(7, x=x+1).set_q(0.05, x=x)
a = life.whole_life_annuity(x)
A = 110 * a / 1000
print(a, A)
life = Recursion().set_interest(i=0.06).set_A(A, x=x).set_q(0.05, x=x)
A1 = life.whole_life_insurance(x+1)
P = life.gross_premium(A=A1 / 1.03, a=7) * 1000
print(P)
SOA Question 6.40: (C) 116
7.2735849056603765 0.8000943396226414
116.51945397474269
SOA Question 6.10 : (D) 0.91
For a fully discrete 3-year term insurance of 1000 on (x), you are given:
\(p_x\) = 0.975
i = 0.06
The actuarial present value of the death benefit is 152.85
The annual net premium is 56.05
Calculate \(p_{x+2}\).
print("SOA Question 6.10: (D) 0.91")
x = 0
life = Recursion(depth=5).set_interest(i=0.06)\
.set_p(0.975, x=x)\
.set_a(152.85/56.05, x=x, t=3)\
.set_A(152.85, x=x, t=3, b=1000)
p = life.p_x(x=x+2)
print(p)
SOA Question 6.10: (D) 0.91
0.9097382950525702
SOA Question 6.48
For a special fully discrete 5-year deferred 3-year term insurance of 100,000 on (x) you are given:
There are two premium payments, each equal to P . The first is paid at the beginning of the first year and the second is paid at the end of the 5-year deferral period
\(p_x = 0.95\)
\(q_{x + 5} = 0.02\)
\(q_{x + 6} = 0.03\)
\(q_{x + 7} = 0.04\)
\(i = 0.06\)
Calculate P using the equivalence principle.
print("SOA Question 6.48: (A) 3195")
life = Recursion(depth=3).set_interest(i=0.06)
x = 0
life.set_p(0.95, x=x, t=5)
life.set_q(0.02, x=x+5)
life.set_q(0.03, x=x+6)
life.set_q(0.04, x=x+7)
a = 1 + life.E_x(x, t=5)
A = life.deferred_insurance(x, u=5, t=3)
P = life.gross_premium(A=A, a=a, benefit=100000)
print(P)
SOA Question 6.48: (A) 3195
3195.118917658744
SOA Question 6.17
An insurance company sells special fully discrete two-year endowment insurance policies to smokers (S) and non-smokers (NS) age x. You are given:
The death benefit is 100,000; the maturity benefit is 30,000
The level annual premium for non-smoker policies is determined by the equivalence principle
The annual premium for smoker policies is twice the non-smoker annual premium
\(\mu^{NS}_{x+t} = 0.1.\quad t > 0\)
\(q^S_{x+k} = 1.5 q_{x+k}^{NS}\), for \(k = 0, 1\)
\(i = 0.08\)
Calculate the expected present value of the loss at issue random variable on a smoker policy.
print("SOA Question 6.17: (A) -30000")
x = 0
life = ConstantForce(mu=0.1).set_interest(i=0.08)
A = life.endowment_insurance(x, t=2, b=100000, endowment=30000)
a = life.temporary_annuity(x, t=2)
P = life.gross_premium(a=a, A=A)
print(A, a, P)
life1 = Recursion().set_interest(i=0.08)\
.set_q(life.q_x(x, t=1) * 1.5, x=x, t=1)\
.set_q(life.q_x(x+1, t=1) * 1.5, x=x+1, t=1)
contract = Contract(premium=P * 2, benefit=100000, endowment=30000)
L = life1.gross_policy_value(x, t=0, n=2, contract=contract)
print(L)
SOA Question 6.17: (A) -30000
37251.49857703495 1.8378124241073746 20269.478042694158
-30107.42633581115
SOA Question 2.5 : (B) 37.1
You are given the following:
\(e_{40:20} = 18\)
\(e_{60} = 25\)
\(_{20}q_{40} = 0.2\)
\(q_{40} = 0.003\)
Calculate \(e_{41}\).
hints:
solve for \(e_{40}\) from limited lifetime formula
compute \(e_{41}\) using backward recursion
print("SOA Question 2.5: (B) 37.1")
life = Recursion(verbose=True).set_e(25, x=60, curtate=True)\
.set_q(0.2, x=40, t=20)\
.set_q(0.003, x=40)\
.set_e(18, x=40, t=20, curtate=True)
e = life.e_x(41, curtate=True)
print(e)
SOA Question 2.5: (B) 37.1
37.11434302908726