Experimental API
These interfaces belong to LifeContingencies.Experimental and may change in minor releases. The model-building guide explains the data flow and payment phases; the LTC example adds duration and benefit memory.
LifeContingencies.Experimental — Module
LifeContingencies.ExperimentalA finite-state engine for contingent payments: a model supplies one-step transition rows over a time grid, a contract is a NamedTuple of payment components, and the engine projects expected cash flows forward (project), values them from a starting distribution (present_values), or values them backward by state (policy_values).
These interfaces are experimental and may change in minor releases.
Model interface
LifeContingencies.Experimental.Interval — Type
Interval(start, stop)One step of a time grid, from start to stop in curve time. Models receive it in transitions, and transition payments receive it in their amount function.
LifeContingencies.Experimental.transitions — Function
transitions(model, interval::Interval, state)The one-step row of model from state over interval: an iterable of next_state => probability pairs. The engine reads each row once, so it may be an iterator that can be read only once. Every state of a model must have the same type.
Probabilities must be nonnegative, and they must sum to one up to rounding: within eight units in the last place of their type for each entry. The engine checks each row it uses and throws an ArgumentError for one that fails; it never rescales a row. Compute a complement such as 1 - p - q with care, or clamp it at zero, since rounding can make it negative.
Define a method for each model type. It must be pure: the engine may call it more than once with the same arguments. A model that supports only some intervals, such as whole months, should throw an ArgumentError for the others.
LifeContingencies.Experimental.states — Function
states(model)Optional: every state of model. policy_values uses them as its default roots.
When they are a tuple, the engine also indexes states by their place in it, comparing states rather than hashing them, which is faster for a model with a few states. A row that reaches a state outside the tuple then throws an ArgumentError.
Payment components
A contract is a named tuple of these components. The canonical empty contract is (;).
LifeContingencies.Experimental.StatePayment — Type
StatePayment(f)A payment at each grid time t to anyone in state, of amount f(t, state).
LifeContingencies.Experimental.TransitionPayment — Type
TransitionPayment(f)A payment on each one-step transition from → to over interval, of amount f(interval, from, to), paid at interval.stop. Self-transitions (from == to) are included, which is how accrual over a period is expressed.
LifeContingencies.Experimental.CertainPayment — Type
CertainPayment(times, amounts)Payments of amounts at times, independent of state. They are valued directly by discounting, so they need no occupancy and never take a terminal value.
Projection, valuation and conditioning
LifeContingencies.Experimental.project — Function
project(contract, model; grid, initial, history=false, numbertype=Float64)Project contract's expected cash flows over grid, starting from the distribution initial (state => probability pairs; use [state => 1.0] for a known state) at grid[1]. Returns a Projection.
Reachable states are discovered from initial by following transitions. Each row is validated as it is used. numbertype is the number type for occupancy and amounts, for example BigFloat or a dual-number type.
LifeContingencies.Experimental.present_values — Function
present_values(contract, model, curve; grid, initial, numbertype=Float64)The expected present value at grid[1] of each of contract's components, starting from the distribution initial (state => probability pairs) at grid[1]. Returns a NamedTuple keyed by component name.
The values include the payments scheduled at grid[1], so they equal Σᵢ πᵢ V⁻ᵢ from policy_values with terminal = 0. They are discounted with discount(curve, grid[1], t), and certain components are valued directly, as in policy_values. One forward pass computes them without storing cash flows or values by state. numbertype is the number type for occupancy and values.
LifeContingencies.Experimental.policy_values — Function
policy_values(contract, model, curve; grid, terminal, roots=states(model), history=false, numbertype=Float64)Value contract by state at grid[1], discounting on curve with interval factors discount(curve, tₖ, tₖ₊₁). Returns a PolicyValues for each state in roots.
Payment phases:
- Transition payments for the interval ending at
tare settled att. b(t)is every payment scheduled att: state payments for the occupied state, plus certain payments.V⁻(t)is the value beforeb(t), andV⁺(t) = V⁻(t) - b(t).- State and transition components follow
V⁻ₖ(i) = bₖ(i) + v(tₖ, tₖ₊₁) Σⱼ Pₖ(i,j) (rₖ(i,j) + V⁻ₖ₊₁(j)), withV⁻ₙ(i) = bₙ(i) + terminal(i)at the final grid date. Heretₖ = grid[k],v(s,t) = discount(curve, s, t), andrₖ(i,j)is the transition payment. State components haverₖ = 0; transition components havebₖ = 0. - Certain components are valued directly at every date:
Σ_{τ ≥ t} v(t,τ) aτbefore the payments attandΣ_{τ > t}after. They are the same in every state.
terminal supplies V⁺ at the last grid time for each state or transition component: a NamedTuple of functions of the state, keyed by component name. terminal = 0 sets every one to zero. Certain components never take a terminal value. A terminal value of zero is justified only by maturity, termination, or a deliberate truncation.
roots defaults to states(model) and must be passed when states isn't defined for model. With history = true, values are also kept for every state reachable from the roots at every grid time.
LifeContingencies.Experimental.condition — Function
condition(distribution, event)Restrict distribution (state => probability pairs) to the states where event(state) is true, and renormalize. Throws a DomainError when the event has probability zero.
Results
LifeContingencies.Experimental.Projection — Type
ProjectionThe result of project.
cashflows: aNamedTuplewith a vector ofFinanceCore.Cashflows for each component. State payments are dated at every grid time, transition payments at every grid time after the first, and certain payments at their own times from the first grid time on.final: occupancy at the last grid time, as aDictof state to probability.history: occupancy at every grid time when requested, otherwisenothing.
LifeContingencies.Experimental.PolicyValues — Type
PolicyValuesThe result of policy_values.
before: for each root state, aNamedTupleof component values at the first grid time, before the payments scheduled then (V⁻).after: the same values after those payments (V⁺).history: when requested, oneDictper grid time from each reachable state to(before = ..., after = ...); otherwisenothing.
Index
LifeContingencies.Experimental.CertainPaymentLifeContingencies.Experimental.IntervalLifeContingencies.Experimental.PolicyValuesLifeContingencies.Experimental.ProjectionLifeContingencies.Experimental.StatePaymentLifeContingencies.Experimental.TransitionPaymentLifeContingencies.Experimental.conditionLifeContingencies.Experimental.policy_valuesLifeContingencies.Experimental.present_valuesLifeContingencies.Experimental.projectLifeContingencies.Experimental.statesLifeContingencies.Experimental.transitions