Life Insurances#
A life insurance pays a lump-sum benefit at — or shortly after — the death of the
insured. Lactuca provides lt.Ax for death-benefit calculations and lt.nEx for
pure endowments. Both are also importable as standalone functions from lactuca.
Types#
Product |
Pays when |
Method |
Notes |
|---|---|---|---|
Whole-life insurance |
On any death |
|
— |
Term insurance |
On death within \(n\) years |
|
|
Pure endowment |
If \((x)\) survives \(n\) years |
|
no |
Endowment insurance |
First of: death or survival at \(n\) |
|
death + survival components |
Note
lt.Ax(x, n=n) returns only the term (death) insurance \(A^1_{x:\overline{n}|}\) —
the benefit payable on death within \(n\) years. To obtain the full endowment
insurance \(A_{x:\overline{n}|}\) (benefit paid on death or survival at \(n\), whichever
occurs first), add the pure endowment:
A_endowment = lt.Ax(x, n=n) + lt.nEx(x, n=n)
The insurance formula#
The APV of a term life insurance at benefit-payment frequency \(m\) is:
Each term is the present value of the benefit (1 unit) payable at time \(j/m + \delta_m\)
if \((x)\) survives to the start of sub-period \(j\) and then dies within it. The offset
\(\delta_m\) is controlled by config.mortality_placement (see below).
For a whole-life insurance (n=None) the sum extends to the limiting age \(\omega\).
Core parameters#
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
(required) |
Current attained age |
|
|
|
Term in years; |
|
|
|
Benefit payment frequency per year (1, 2, 3, 4, 6, 12, 14, 24, 26, 52, 365) |
|
|
|
Deferment — benefit payable only if death occurs after \(x + d\) |
|
|
|
Elapsed time for reserve calculations |
|
|
table default |
Interest rate |
|
|
|
Benefit growth rate (escalating sum assured) |
Ax is also importable as a functional-style wrapper:
from lactuca import Ax
nEx does not accept d, m, or gr. It accepts ts for reserve calculations.
Mortality placement and payment timing#
config.mortality_placement determines the sub-period timing of the death benefit
(\(\delta_m\) in the formula above). It affects insurances only — annuities and
pure endowments are unaffected.
Setting |
\(\delta_m\) |
Convention |
|---|---|---|
|
\(\tfrac{1}{2m}\) |
Death at mid-period (UDD mid-year) |
|
\(0\) |
Payment immediately on death |
|
\(\tfrac{1}{m}\) |
Traditional end-of-period convention |
from lactuca import config
config.mortality_placement = "mid" # default
config.mortality_placement = "end" # traditional commutation convention
config.mortality_placement = "beginning" # payment immediately on death
config.reset() # restore default ("mid")
For the full reference and interaction with calculation modes, see mortality placement in Calculation Modes.
Equivalence with life annuities#
The whole-life insurance and the annuity-due satisfy the annuity-insurance duality, which follows from the total probability law. At annual frequency (\(m = 1\)) with end-of-year convention:
where \(d = 1 - v = i/(1+i)\) is the annual effective discount rate.
For a finite-term endowment:
Note
The identity is exact for \(m = 1\) and mortality_placement = "end" (traditional
commutation-function convention). With the default "mid" placement, use the
\(m\)-thly discount rate \(d^{(m)} = m(1 - v^{1/m})\) for the corresponding \(m\)-thly
version. Small numerical discrepancies generally arise because the two quantities
are computed by independent engine dispatches.
Commutation function connection#
For integer ages, \(m = 1\), and mortality_placement = "end":
See Commutation Functions for the algebraic derivation. The calculation
engine used by Ax evaluates the defining sum directly — it does not use
commutation functions — so it correctly handles all frequencies, fractional ages,
and piecewise interest rate curves.
Pure endowment#
The pure endowment \({}_{n}E_x\) is the APV of 1 unit payable at time \(n\) if \((x)\) survives:
It is a key building block: the endowment insurance is the term insurance plus the
pure endowment, and the factorisation of deferred annuities uses it explicitly (see
Deferred Life Contingencies). It does not accept d, m, or gr.
Code examples#
Whole-life, term, and endowment insurance#
from lactuca import LifeTable, config
config.decimals.insurances = 6
lt = LifeTable("PASEM2020_Rel_1o", "m", interest_rate=0.03)
# Whole-life insurance: Ax(65)
Ax_wl = lt.Ax(65)
print(Ax_wl)
# 20-year term insurance: A¹_{65:20|}
Ax_term = lt.Ax(65, n=20)
print(Ax_term) # < Ax_wl (deaths after 20 years excluded)
# 20-year pure endowment: 20E65
nEx_20 = lt.nEx(65, n=20)
print(nEx_20)
# 20-year endowment insurance: A_{65:20|} = A¹ + 20E
endowment = round(Ax_term + nEx_20, 6)
print(endowment) # payment is certain; APV < 1 due to discounting
config.reset()
Monthly benefit insurance (m=12)#
from lactuca import LifeTable, config
config.decimals.insurances = 6
lt = LifeTable("PASEM2020_Rel_1o", "m", interest_rate=0.03)
# Annual insurance (default m=1)
Ax_annual = lt.Ax(65)
# Monthly benefit: benefit paid at mid-month of death (default "mid" placement)
Ax_monthly = lt.Ax(65, m=12)
# Monthly benefit is slightly higher: benefit paid sooner (less discounting)
print(Ax_annual < Ax_monthly) # True
config.reset()
Annuity-insurance duality#
from lactuca import LifeTable, config
config.decimals.annuities = 6
config.decimals.insurances = 6
lt = LifeTable("PASEM2020_Rel_1o", "m", interest_rate=0.03)
i = 0.03
d_rate = i / (1 + i) # annual discount rate d = 1 - v
Ax_val = lt.Ax(65) # whole-life insurance (m=1, default "mid" placement)
ax_val = lt.äx(65) # whole-life annuity-due (m=1)
# Check: Ax + d * äx ≈ 1 (near-exact under m=1, with small gap from "mid" placement)
print(round(Ax_val + d_rate * ax_val, 4)) # ≈ 1.0
config.reset()
Deferred insurance#
A deferred insurance pays only if death occurs after the deferment period. See Deferred Life Contingencies for the full treatment:
from lactuca import LifeTable, config
config.decimals.insurances = 6
lt = LifeTable("PASEM2020_Rel_1o", "m", interest_rate=0.03)
# Standard whole-life insurance
Ax = lt.Ax(65)
# 5-year deferred: only deaths after age 70 trigger the benefit
Ax_def = lt.Ax(65, d=5)
print(Ax > Ax_def) # True — deaths in [0, 5) excluded
config.reset()
Prospective reserve at elapsed time ts#
from lactuca import LifeTable, config
config.decimals.insurances = 6
lt = LifeTable("PASEM2020_Rel_1o", "m", interest_rate=0.03)
x, n = 55, 30
# APV at issue (ts=0)
Ax_issue = lt.Ax(x, n=n)
# APV after 10 years: effective age 65, remaining term 20
Ax_ts = lt.Ax(x, n=n, ts=10)
Ax_direct = lt.Ax(65, n=20)
# Both approaches give the same value
print(round(Ax_ts - Ax_direct, 8)) # → 0.0
config.reset()
See also#
Notation and Glossary — actuarial symbols and notation
Life Annuities —
äx,axand the annuity-insurance dualityCommutation Functions — \(M_x/D_x\) formula and commutation function reference
Deferred Life Contingencies — deferment parameter
d: deferred insurances with factorisation proofProspective Reserves and the ts Parameter — net level premium \(P = A_x / \ddot{a}_x\), prospective reserve formula, and the
tsparameterCalculation Modes — mortality placement, discrete vs. continuous modes
Joint-Life Calculations — joint-life insurances
Axy, first-death insuranceInterest Rates —
InterestRateclass and term structures