API

LifeSimulator.CashFlowType

Represents cashflows, typically to be computed during a Simulation over an insurance Model.

The present value of future cashflows is estimated from the future cashflows using a model-provided discount rate.

Cashflows may be added with +, which will perform the addition over each respective field.

See also: Simulation, Model

struct CashFlow
  • premiums::Float64

  • investments::Float64

  • claims::Float64

  • expenses::Float64

  • commissions::Float64

  • account_value_changes::Float64

  • net::Float64

  • discounted::Float64

source
LifeSimulator.LapseModelType

Model expressing lapses, e.g. due to payment defaults.

A given subtype L is expected to define either of:

  • monthly_lapse_rate(model::L, time::Month)
  • monthly_lapse_rate(model::L, time::Month, policy::Policy)
  • annual_lapse_rate(model::L, time::Month)
  • annual_lapse_rate(model::L, time::Month, policy::Policy)

Whether to define a 2- or 3-argument method depends on whether the lapse rate as computed by the model is policy-specific. In such a case, in addition of defining 3-argument methods, you must implement rates_are_per_policy(::LapseModel) = true; the default is for it to be false implying that 2-argument methods are required.

abstract type LapseModel
source
LifeSimulator.LifelibBasiclifeType

Term life insurance model replicating the functionality of lifelib's basiclife module.

struct LifelibBasiclife{M<:MortalityModel, L<:LapseModel} <: TermLifeModel
  • mortality::MortalityModel

  • lapse::LapseModel

  • load_premium_rate::Float64

  • acquisition_cost::Float64: One-time cost for new policies.

  • annual_maintenance_cost::Float64: Annual maintenance cost per policy.

  • commission_rate::Float64: Agents selling insurance products get paid a commission, whose value is a percentage of the premium paid during the first year.

  • inflation_rate::Float64: Roughly estimated average for the inflation rate.

  • discounts::Vector{Float64}

source
LifeSimulator.LifelibSavingsType

Universal life model reimplemented from lifelib's savings library.

struct LifelibSavings{M<:MortalityModel, L<:LapseModel} <: UniversalLifeModel
  • mortality::MortalityModel

  • lapse::LapseModel

  • maintenance_fee_rate::Float64

  • commission_rate::Float64

  • insurance_risk_cost::Float64

  • investment_rates::Vector{Float64}

  • acquisition_cost::Float64: One-time cost for new policies.

  • inflation_rate::Float64: Roughly estimated average for the annual inflation rate.

  • annual_maintenance_cost::Float64: Annual maintenance cost per policy.

  • annual_discount_rate::Float64: Estimated average for the future devaluation of cash.

source
LifeSimulator.MortalityModelType

Mortality model.

A given subtype M is expected to define either of:

  • monthly_mortality_rate(model::M, time::Month, policy::Policy)
  • monthly_mortality_rate(model::M, time::Month, age::Year)
  • annual_mortality_rate(model::M, time::Month, policy::Policy)
  • annual_mortality_rate(model::M, time::Month, age::Year)

where, by default, the form with Policy as third argument simply defaults to computing the age at the current time and call a method with age::Year as third argument, defined for convenience.

abstract type MortalityModel
source
LifeSimulator.PolicyType

Policy held with a corresponding account value.

struct Policy
  • sex::Sex

  • age::Dates.Year

  • whole_life::Bool: Whether the policy should last as long as its beneficiary.

  • assured::Float64: Sum assured by the policy.

  • premium::Float64: Premium for the policy.

  • issued_at::Dates.Month: Month (after the start of the simulation) the contract has been issued.

  • term::Dates.Year

  • product::LifeSimulator.Product

  • account_value::Float64

source
LifeSimulator.PolicySetType

Aggregation of a specific type of policy among many policy holders.

The account for universal life models is therefore also unique among all policy holders, amounting to a total of set.policy.account_value * policy_count(set)

struct PolicySet
  • policy::Policy

  • count::Float64

source
LifeSimulator.SimulationType

Simulation parametrized by a particular Model.

The simulation time starts at the current date by default. The simulation is carried out every month, producing events ([SimulationEvents]) corresponding to what happened between two timesteps, i.e. from one month to the other. The simulation is nonetheless stateful, meaning that such events may only be produced once; the next evaluation will return the events for the timestep after that.

See also: next!

mutable struct Simulation{M<:Model}
  • model::Model

  • active_policies::Vector{PolicySet}

  • inactive_policies::Vector{PolicySet}

  • time::Dates.Month: Current simulation time, incremented after every simulation step.

source
LifeSimulator.SimulationEventsType

Events that happen as part of a simulation timestep for a Model.

These events are meant to be processed by the user in order to generate quantities of interest that do not involve simulation-related state. This is, for example, how the CashFlow quantities are computed.

mutable struct SimulationEvents
  • time::Dates.Month: Month during which the events started to be simulated. Events occur between time and time + Month(1) - Day(1).

  • lapses::Vector{Pair{PolicySet, Float64}}

  • deaths::Vector{Pair{PolicySet, Float64}}

  • expirations::Vector{PolicySet}

  • claimed::Float64: Amount resulting from expired or lapsed policies or for which the holder has died.

  • starts::Vector{PolicySet}

  • expenses::Float64: Policies which started at the beginning of the month.

  • account_changes::Vector{Pair{PolicySet, LifeSimulator.AccountChanges}}

source
LifeSimulator.TermLifeModelType

Term life model.

Term life contracts start at a given date, and expire at a specified term. Upon death, the policy may be claimed, providing the policy holder with an assured amount.

Premiums must be paid every month, otherwise the contract is cancelled (lapses).

abstract type TermLifeModel <: Model
source
LifeSimulator.UniversalLifeModelType

Universal life model.

The defining property of a universal life model is that the contract between an insurance company and a policy holder involves a client-managed bank account, where the policy holder is responsible for keeping the bank account appropriately filled.

Lapses do not occur in absence of a payment, but rather when the bank account runs out of money while fees or premiums must be paid. It is, for example, for the policy holder to put a lot of money in the bank account and forget about it for a while, as opposed to a regular term life insurance model which requires frequent payments without such buffer.

abstract type UniversalLifeModel <: Model
source
LifeSimulator.estimate_premiumsMethod

Run a first simulation to estimate premiums for each policy, returning policies with the estimated premiums.

Instead of running a full simulation, and producing a SimulationEvents at every step, we manually go through the lapse and mortality stages only to speed it up a bit.

estimate_premiums(
    model::LifelibBasiclife,
    policies,
    n
) -> Any
source
LifeSimulator.monthly_lapse_rateFunction

monthlylapserate(model::LapseModel, time::Month) monthlylapserate(model::LapseModel, time::Month, policy::Policy)

Compute the monthly lapse rate for the given model. Falls back to a renormalization of [annual_lapse_rate] over 1/12 year.

source
LifeSimulator.monthly_mortality_rateFunction
monthly_mortality_rate(model::MortalityModel, time::Month, policy::Policy)
monthly_mortality_rate(model::MortalityModel, time::Month, age::Year)

Compute the monthly mortality rate for the given model. Falls back to a renormalization of annual_mortality_rate over 1/12 year.

source
LifeSimulator.next!Method

Perform a simulation timestep over the LifelibBasiclife model, returning a SimulationEvents.

First, the policies which reached their term are removed, yielding claims and account changes.

Second, the policies which start from the current month are added, yielding expenses (costs for the insurance company).

Then, at the middle of the month, deaths and lapses occur. Finally, the simulation time is incremented.

A callback may be run just before the deaths and lapses occur, as the original basiclife model considers lapses and deaths to be part of the next iteration (i.e., deaths and lapses occur prior to the next step, and not in the current step).

next!(
    sim::Simulation{<:LifelibBasiclife},
    events::SimulationEvents;
    callback
) -> SimulationEvents
source
LifeSimulator.next!Method

Perform a simulation timestep over the LifelibSavings model, returning a SimulationEvents.

First, the policies which reached their term are removed, yielding claims and account changes.

Second, the policies which start from the current month are added, yielding expenses (costs for the insurance company).

Third, all account values are updated, with:

  • A premium amount put into the bank account (minus fees, the load premium rate).
  • Maintenance fees withdrawn from the back account.
  • Insurance costs withdrawn from the back account.
  • Investments realized during the previous month.

Then, at the middle of the month, deaths and lapses occur. Finally, the simulation time is incremented.

next!(
    sim::Simulation{<:LifelibSavings},
    events::SimulationEvents
) -> SimulationEvents
source
LifeSimulator.policies_from_csvFunction

Import policies from CSV files compatible with the lifelib model.

policies_from_csv() -> Vector{PolicySet}
policies_from_csv(file::AbstractString) -> Vector{PolicySet}
source
LifeSimulator.simulateMethod
simulate(f, model, policies, n)

Simulate a set of policies forward in time according to the provided model, for n months.

After every iteration, f(events::SimulationEvents) is called, and may be used for example to compute and keep track of cashflows.

See also: SimulationEvents, CashFlow

simulate(f, model::Model, policies, n::Int64) -> Simulation
source