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 as pandas DataFrames and dicts.

  • InputData is referenced by PolicyAttrs and Assumptions, where policy attributes and assumptions are mapped to model points.

  • InputData is also referenced by Economic, where discount rates are calculated.

  • CommTable calculates commutation functions, and defines actuarial notations. They are used by Projection to calculate the premium rate for each model point. Mortality rates are provided through InputData. CommTable takes three parameters, Sex, IntRate and Table (sex, interest rate and mortality table id).

  • Projection carries out the projection by model point. It takes two parameters: idx (mandatory) to identify a model point, and scen_id (optional) to select the economic scenario, defaulting to 1. Policy attributes and assumptions are received from cells in PolicyAttrs and Assumptions, which return their values by model point in 1-D numpy arrays, so the idx parameter 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, BaseProj and PV.

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

InputData

Reads input.xlsx and holds its named ranges as pandas DataFrames and dicts.

Economic

Parametric space holding scenario-dependent economic assumptions; parameter scen_id.

BaseProj

Base space of Projection containing the cells that produce the per-period cashflow projections.

PV

Base space of Projection containing the cells that compute the present values of those cashflows.

Projection

Parametric space whose dynamic ItemSpaces carry out projections for each model point; parameters idx and scen_id.

Assumptions

Holds assumption parameters and rates used by Projection.

PolicyAttrs

Holds policy attributes and policy-level values such as premium and surrender rates used by Projection.

Utilities

Base space of Assumptions and PolicyAttrs providing helper cells.

CommTable

Parametric space providing commutation functions and actuarial notations; parameters Sex, IntRate and Table.

Enums

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:

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

PolicyData

policy_data()

Per-policy attributes for model points

ProductSpecTable

product_spec()

Per-product loading and rate tables

AssumptionTable

assumption()

Lookup table of assumption keys

AsmpByDuration

assumption_tables()

Duration-based mortality / lapse tables

MortalityTables

mortality_tables()

Mortality tables keyed by Sex / Table

Scenarios

scenarios()

Scenario interest-rate paths

LargePolDiscount

discount_rate()

Premium discount by sum-assured band

PremiumWaiverCost

prem_waiver_cost()

Premium-waiver cost lookup

ConstParams

const_params()

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.

pd#

The pandas module.

np#

The numpy module.

ProductID#

The product-type enum, ProductID (TERM term insurance, WL whole life, ENDW endowment).

SexID#

The sex enum, SexID (M male, F female).

RateBasisID#

The rate-basis enum, RateBasisID (PREM premium basis, VAL valuation basis).