The TradLife_A Model#
Annual new business projection model of basic traditional life policies.
Overview#
TradLife_A is an annual new business projection model
of basic traditional life policies, covering term, whole life and
endowment products, built with
modelx.
It projects liability cashflows and their present values for policies represented by model points. Projected items include:
Premiums,
Commissions and expenses,
Claims.
Premiums are calculated using commutation functions. Cells for investment income reserves are defined but not implemented.
Computation flow#
Model point data, product specifications, assumptions and economic scenarios are all held in an external Excel workbook, input.xlsx.
The spaces are wired together as shown below, and the computation proceeds as follows.
graph LR
Projection --> Economic
Projection --> Assumptions
Projection --> PolicyAttrs
Projection --> CommTable
Economic --> InputData
Assumptions --> InputData
PolicyAttrs --> InputData
CommTable --> InputData
The data is read into the model from the input file in
InputData, and held there aspandasDataFrames and dicts.InputDatais referenced byPolicyAttrsandAssumptions, where policy attributes and assumptions are mapped to model points.InputDatais also referenced byEconomic, where discount rates are calculated.CommTablecalculates commutation functions, and defines actuarial notations. They are used byProjectionto calculate the premium rate for each model point. Mortality rates are provided throughInputData.CommTabletakes three parameters,Sex,IntRateandTable(sex, interest rate and mortality table id).Projectioncarries out the projection by model point. It takes two parameters:idx(mandatory) to identify a model point, andscen_id(optional) to select the economic scenario, defaulting to 1. Policy attributes and assumptions are received from cells inPolicyAttrsandAssumptions, which return their values by model point in 1-Dnumpyarrays, so theidxparameter indicates the array index, starting from 0.The projection logic is not defined directly in
Projection. Instead, the space inherits all of its logic from two base spaces,BaseProjandPV.
For example, the present value of net cashflows for the first model point is obtained as:
>>> m.Projection[0].pv_net_cf(0)
Model Structure#
In TradLife_A, the following spaces are defined.
Space |
Description |
|---|---|
Reads input.xlsx and holds its named ranges as |
|
Parametric space holding scenario-dependent economic assumptions;
parameter |
|
Base space of |
|
Base space of |
|
Parametric space whose dynamic ItemSpaces carry out projections
for each model point; parameters |
|
Holds assumption parameters and rates used by
|
|
Holds policy attributes and policy-level values such as premium
and surrender rates used by
|
|
Base space of |
|
Parametric space providing commutation functions and actuarial
notations; parameters |
|
Container for the enum types used across the model. |
Enums contains the enum types as child
spaces, and Assumptions contains an
AsmpID child space.
Inheritance#
Projection inherits from
BaseProj and
PV, so projection cells and their
present-value counterparts share the same parameter scope.
%%{init: {"class": {"hideEmptyMembersBox": true}}}%%
classDiagram
BaseProj <|-- Projection
PV <|-- Projection
Assumptions and
PolicyAttrs inherit from
Utilities, which contributes the
pandas_to_array and map_to_policies helpers.
%%{init: {"class": {"hideEmptyMembersBox": true}}}%%
classDiagram
Utilities <|-- Assumptions
Utilities <|-- PolicyAttrs
Cross-space references#
The cells in Projection and its base
spaces resolve a number of References to other spaces:
scen->Economicasmp->Assumptionspol->PolicyAttrscomm_table->CommTable
Economic,
Assumptions and
PolicyAttrs each reference the
InputData space as input_data, while
CommTable references the
mortality_tables() cells defined
in InputData as mortality_tables.
graph LR
Projection -- scen --> Economic
Projection -- asmp --> Assumptions
Projection -- pol --> PolicyAttrs
Projection -- comm_table --> CommTable
Economic -- input_data --> InputData
Assumptions -- input_data --> InputData
PolicyAttrs -- input_data --> InputData
CommTable -- mortality_tables --> InputData
Input File#
TradLife_A reads its data from input.xlsx, which is
located next to the TradLife_A model directory inside the library
folder. The default file name is set by the
input_file_name reference.
The workbook defines the following named ranges, picked up through cells
in InputData:
External named range |
Cells |
Purpose |
|---|---|---|
|
Per-policy attributes for model points |
|
|
Per-product loading and rate tables |
|
|
Lookup table of assumption keys |
|
|
Duration-based mortality / lapse tables |
|
|
Mortality tables keyed by Sex / Table |
|
|
Scenario interest-rate paths |
|
|
Premium discount by sum-assured band |
|
|
Premium-waiver cost lookup |
|
|
Scalar parameters used across the model |
Basic Usage#
Reading the model#
Create your copy of the annuallife library by following the steps on
the Quick Start page. The model is saved as the folder
TradLife_A in the copied folder, with input.xlsx placed next to
it.
To read the model from Spyder with the modelx plug-in, right-click on the empty space in MxExplorer, select Read Model, and choose the TradLife_A folder.
To read the model on an IPython console, use read_model after
changing the current directory to the library folder so the workbook is
discoverable:
>>> import modelx as mx
>>> m = mx.read_model("TradLife_A")
Running results#
Projection results are obtained by calling the cells of an ItemSpace of
Projection with a specific idx (and
optionally scen_id):
>>> m.Projection[0].pv_net_cf(0) # PV of net cashflow at t=0
>>> m.Projection[0].net_cf(5) # Net cashflow at t=5
>>> m.Projection[0].premiums(0) # Premium income at t=0
>>> m.Projection[0].claims(0) # Death claims at t=0
The plot scripts plot_tradlife_a.py and plot_pvcashflows_tradlife_a.py
in the library folder demonstrate how to produce stacked-bar charts of
the cashflow components and their present values.
Exporting the model#
The model can be exported to a pure-Python (nomx) module that does not
depend on modelx. Use the export method on the model object:
>>> m.export("TradLife_A_nomx")
This command exports the model as a Python package named
TradLife_A_nomx in the current directory. You can test the exported
(nomx) model by importing it and accessing its cells:
>>> from TradLife_A_nomx import mx_model
>>> mx_model.Projection[0].pv_net_cf(0)
(Here, mx_model is the nomx model object.)
Global References#
Global references are names that can be referenced from formulas in any
space in the model. The third-party modules
pandas and
numpy are defined here, as are the enum types
defined as child spaces under Enums.
- ProductID#
The product-type enum,
ProductID(TERMterm insurance,WLwhole life,ENDWendowment).
- SexID#
The sex enum,
SexID(Mmale,Ffemale).
- RateBasisID#
The rate-basis enum,
RateBasisID(PREMpremium basis,VALvaluation basis).