Source code for actuarialmath.extrarisk
"""Extra Risk - Adjusts force of mortality, age rating or mortality rate
MIT License. Copyright 2022-2023 Terence Lim
"""
from typing import Dict
import math
from actuarialmath import Survival
from actuarialmath import Actuarial
[docs]class ExtraRisk(Actuarial):
"""Adjust mortality by extra risk
Args:
life : contains original survival and mortality rates
extra : amount of extra risk to adjust
risk : adjust by {"ADD_FORCE", "MULTIPLY_FORCE", "ADD_AGE", "MULTIPLY_RATE"}
"""
risks = ["ADD_FORCE", "MULTIPLY_FORCE", "ADD_AGE", "MULTIPLY_RATE"]
def __init__(self,
life: Survival,
risk: str = "",
extra: float = 0.) -> "ExtraRisk":
"""Specify type and amount of mortality adjustment to apply"""
assert not risk or risk in self.risks, "risk must be one of " + str(risks)
assert extra >= 0, "amount of extra risk must be non-negative"
self.life = life
self.extra_ = extra
self.risk_ = risk
[docs] def __getitem__(self, col: str) -> Dict[int, float]:
"""Returns survival function values adjusted by extra risk
Args:
col : {'p', 'q'} for one-year survival or mortality function values
Returns:
dict of age and survival function values adjusted by extract risk
Examples:
>>> life = SULT()
>>> extra = ExtraRisk(life=life, extra=0.05, risk="ADD_FORCE")
>>> select = SelectLife(periods=1).set_select(s=0, age_selected=True,
q=extra['q'])
"""
f = {'q': self.q_x, 'p': self.p_x}[col[0]]
return {x: f(x) for x in range(self.life._MINAGE, self.life._MAXAGE+1)}
[docs] def p_x(self, x: int, s: int = 0) -> float:
"""Return p_[x]+s after adding or multiplying force of mortality
Args:
x : age of selection
s : years after selection
Examples:
>>> life = SULT()
>>> extra = ExtraRisk(life=life, extra=2, risk="MULTIPLY_FORCE")
>>> print(life.p_x(45), extra.p_x(45))
"""
if self.risk_ in ["MULTIPLY_RATE"]:
return 1 - self.q_x(x, s=s)
if self.risk_ in ["ADD_AGE"]:
return self.life.p_x(x + self.extra_, s=s)
p = self.life.p_x(x, s=s)
if self.risk_ in ["MULTIPLY_FORCE"]:
p = p**self.extra_
if self.risk_ in ["ADD_FORCE"]:
p *= math.exp(-self.extra_)
return p
[docs] def q_x(self, x: int, s: int = 0) -> float:
"""Return q_[x]+s after adding age rating or multipliying mortality rate
Args:
x : age of selection
s : years after selection
"""
if self.risk_ in ["ADD_FORCE", "MULTIPLY_FORCE"]:
return 1 - self.p_x(x, s=s)
if self.risk_ in ["ADD_AGE"]:
return self.life.q_x(x + self.extra_, s=s)
if self.risk_ in ["MULTIPLY_RATE"]:
return self.extra_ * self.life.q_x(x, s=s)
if __name__ == "__main__":
from actuarialmath.selectlife import SelectLife
from actuarialmath.sult import SULT
print("SOA Question 5.5: (A) 1699.6")
life = SULT()
extra = ExtraRisk(life=life, extra=0.05, risk="ADD_FORCE")
select = SelectLife(periods=1)\
.set_interest(i=.05)\
.set_select(s=0, age_selected=True, q=extra['q'])\
.set_select(s=1, age_selected=False, a=life['a'])\
.fill_table()
print(100*select['a'][45][0])
print()
print("SOA Question 4.19: (B) 59050")
life = SULT()
extra = ExtraRisk(life=life, extra=0.8, risk="MULTIPLY_RATE")
select = SelectLife(periods=1)\
.set_interest(i=.05)\
.set_select(s=0, age_selected=True, q=extra['q'])\
.set_select(s=1, age_selected=False, q=life['q'])\
.fill_table()
print(100000*select.whole_life_insurance(80, s=0))
print()
print("Other usage examples")
life = SULT()
extra = ExtraRisk(life=life, extra=2, risk="MULTIPLY_FORCE")
print(life.p_x(45), extra.p_x(45))