The ProductBase Space#
Base projection logic for all products
The ProductBase space
serves as the base space for concrete product spaces
defined in the Run space.
This space defines main projection logic that is common for all products.
Projection parameters#
Model point data#
Target model points |
|
Index for model points |
|
Extended model point table |
|
|
The attained age at time t. |
|
The sex of the model points |
The age at entry of the model points |
|
Initial account value per policy |
|
Commission rate |
|
|
Duration of model points at |
|
Duration of model points at |
Initial duration in month |
|
|
Whether GMAB is attached |
|
Whether GMDB is attached |
Whether surrender charge applies |
|
|
Whether the model point is whole life |
Maintenance fee per account value |
|
The policy term of the model points. |
|
Type of premium payment |
|
The sum assured of the model points |
|
ID of surrender charge pattern |
Assumptions#
Base lapse rate |
|
Whether the lapse assumption is dynamic |
|
Dynamic lapse parameters |
|
Dynamic lapse factor |
|
Index keys to retrieve lapse rates for time t |
|
|
Lapse rate |
|
Discount factors. |
|
Discount rate to be applied at time t |
Monthly discount rate |
|
Acquisition expense per policy |
|
Annual maintenance expense per policy |
|
Inflation rate |
|
The inflation factor at time t |
|
The last age of mortality tables |
|
Base mortality rate to be applied at time t |
|
|
Mortality rates for time t |
Index keys to retrieve mortality rates for time t |
|
Monthly mortality rate to be applied at time t |
|
Mortality table IDs |
Policy values#
|
Per policy claim in excess of account value |
|
Claim per policy |
|
Cost of insurance charges per policy |
|
Cost of insurance rate per account value |
|
Premium amount per policy |
Index keys to retrieve surrender charge rates at time t |
|
Surrender charge rate |
Policy decrement#
|
Number of policies in-force |
|
Number of policies in-force |
Initial number of policies in-force |
|
|
Number of lapse |
|
Number of death |
Number of maturing policies |
|
|
Number of new business policies |
Account Value#
|
Investment income on account value |
Investment income on account value per policy |
|
Rate of investment return |
|
|
Account value in-force |
|
Change in account value |
|
Account value per policy |
|
Cash surrender value per policy |
|
Cost of insurance charges |
|
Maintenance fee deducted from account value |
|
Maintenance fee per policy |
Net amount at risk per policy |
|
|
Premium portion put in account value |
Per-policy premium portion put in the account value |
Cashflows#
|
Claims |
|
Account value taken out to pay claim |
|
Claim in excess of account value |
|
Commissions |
|
Expenses |
|
Surrender charge |
|
Net cashflow |
Margin Analysis#
Expense margin |
|
Mortality margin |
Present values#
Present value of change in account value |
|
|
Present value of claims |
|
Present value of claims |
|
Present value of claims |
Present value of commissions |
|
Present value of expenses |
|
Present value of investment income |
|
Present value of maintenance fees |
|
Present value of net cashflows. |
|
Present value of policies in-force |
|
Present value of premiums |
Results and output#
Result table of present value of cashflows |
|
Result table of cashflows |
|
Result table of policy decrement |
|
|
Sample projection result for a specific model point and scenario |
|
Output sample cashflows to Excel |
Validation#
Check account value roll-forward |
|
Check consistency between net cashflow and margins |
|
Check present value summation |
Cells Descriptions#
- proj_len()[source]#
Projection length in months
proj_len()returns how many months the projection for each model point should be carried out for all the model point. Defined as:np.maximum(12 * policy_term() - duration_mth(0) + 1, 0)
Since this model carries out projections for all the model points simultaneously, the projections are actually carried out from 0 to
max_proj_lenfor all the model points.See also
max_proj_len
- model_point()[source]#
Target model points
Returns as a DataFrame the model points to be in the scope of calculation. By default, this Cells returns the entire
model_point_table_ext()without change.model_point_table_ext()is the extended model point table, which extendsmodel_point_tableby joining the columns inproduct_spec_table. Do not directly refer tomodel_point_tablein this formula. To select model points, change this formula so that this Cells returns a DataFrame that contains only the selected model points.Examples
To select only the model point 1:
def model_point(): return model_point_table_ext().loc[1:1]
To select model points whose ages at entry are 40 or greater:
def model_point(): return model_point_table[model_point_table_ext()["age_at_entry"] >= 40]
Note that the shape of the returned DataFrame must be the same as the original DataFrame, i.e.
model_point_table_ext().When selecting only one model point, make sure the returned object is a DataFrame, not a Series, as seen in the example above where
model_point_table_ext().loc[1:1]is specified instead ofmodel_point_table_ext().loc[1].Be careful not to accidentally change the original table held in
model_point_table_ext().See also
- model_point_table_ext()[source]#
Extended model point table
Returns an extended
model_point_tableby joiningproduct_spec_tableon thespec_idcolumn.See also
model_point_tableproduct_spec_table
- sex()[source]#
The sex of the model points
Note
This cells is not used by default.
The
sexcolumn of the DataFrame returned bymodel_point().
- age_at_entry()[source]#
The age at entry of the model points
The
age_at_entrycolumn of the DataFrame returned bymodel_point().
- av_pp_init()[source]#
Initial account value per policy
For existing business at time
0, returns initial per-policy accout value read from theav_pp_initcolumn inmodel_point(). For new business, 0 should be entered in the column.See also
- duration_mth(t)[source]#
Duration of model points at
tin monthsIndicates how many months the policies have been in-force at
t. The initial values at time 0 are read from theduration_mthcolumn inmodel_point_tablethroughmodel_point(). Increments by 1 astincrements. Negative values ofduration_mth()indicate future new business policies. For example, If theduration_mth()is -15 at time 0, the model point is issued att=15.See also
- has_surr_charge()[source]#
Whether surrender charge applies
Trueif surrender charge on account value applies upon lapse,Falseif other wise. By default, the value is read from thehas_surr_chargecolumn inmodel_point().See also
- is_wl()[source]#
Whether the model point is whole life
Trueif the model point is whole life,Falseif other wise. By default, the value is read from theis_wlcolumn inmodel_point(). This attribute is used to determinpolicy_term(). IfTrue,policy_term()is defined asmort_table_last_age()minusage_at_entry(). IfFalse,policy_term()is read frommodel_point().See also
- maint_fee_rate()[source]#
Maintenance fee per account value
The rate of maintenance fee on account value each month. Set to
0.01 / 12by default.See also
- policy_term()[source]#
The policy term of the model points.
The
policy_termcolumn of the DataFrame returned bymodel_point().
Type of premium payment
Returns a string indicating the payment type, which is either
"LEVEL"if level payment, or"SINGLE"if single payment.
- sum_assured()[source]#
The sum assured of the model points
The
sum_assuredcolumn of the DataFrame returned bymodel_point().
- surr_charge_id()[source]#
ID of surrender charge pattern
A string to indicate the ID of the surrender charge pattern. The ID should be one of the column names in
surr_charge_tableifhas_surr_charge()isTrue.See also
surr_charge_table
- base_lapse_rate(t)[source]#
Base lapse rate
By default, the lapse rate assumption is defined by duration as:
max(0.1 - 0.01 * duration(t), 0.02)
See also
- disc_factors(t)[source]#
Discount factors.
Vector of the discount factors as a Numpy array. Used for calculating the present values of cashflows.
See also
- disc_rate_mth(t)[source]#
Monthly discount rate
Nummpy array of monthly discount rates from time 0 to
max_proj_len()- 1 defined as:(1 + disc_rate_ann)**(1/12) - 1
See also
disc_rate_ann()
- inflation_rate()[source]#
Inflation rate
The inflation rate to be applied to the expense assumption. By defualt it is set to
0.01.See also
- base_mort_rate(t)[source]#
Base mortality rate to be applied at time t
Returns a Series of the mortality rates to be applied at time t. The index of the Series is
point_id, copied frommodel_point().See also
mort_table_reindexed()
- claim_pp(t, kind)[source]#
Claim per policy
The claim amount per policy. The second parameter is to indicate the type of the claim, and it takes a string, which is either
"DEATH","LAPSE"or"MATURITY".The death benefit as denoted by
"DEATH", is the greater ofsum_assured()and mid-month account value (av_pp_at(t, "MID_MTH")).The surrender benefit as denoted by
"LAPSE"and the maturity benefit as denoted by"MATURITY"are equal to the mid-month account value.See also
- coi_pp(t)[source]#
Cost of insurance charges per policy
The cost of insurance charges per policy. Defined as the coi charge rate times net amount at risk per policy.
See also
- coi_rate(t)[source]#
Cost of insurance rate per account value
The cost of insuranc rate per account value per month. By default, it is set to 1.1 times the monthly mortality rate.
See also
Premium amount per policy
Single premium amount if
premium_type()is"SINGLE", monthly premium amount ifpremium_type()is"LEVEL".
- surr_charge_rate(t)[source]#
Surrender charge rate
Surrender charge rate to be applied for lapsed policies
See also
surr_charge_max_idx()surr_charge_table_stacked()
- pols_if(t)[source]#
Number of policies in-force
pols_if(t)is an alias forpols_if_at(t, "BEF_MAT").See also
- pols_if_at(t, timing)[source]#
Number of policies in-force
pols_if_at(t, timing)calculates the number of policies in-force at timet. The second parametertimingtakes a string value to indicate the timing of in-force, which is either"BEF_MAT","BEF_NB"or"BEF_DECR".BEF_MAT
The number of policies in-force before maturity after lapse and death. At time 0, the value is read from
pols_if_init(). For time > 0, defined as:pols_if_at(t-1, "BEF_DECR") - pols_lapse(t-1) - pols_death(t-1)
BEF_NB
The number of policies in-force before new business after maturity. Defined as:
pols_if_at(t, "BEF_MAT") - pols_maturity(t)
BEF_DECR
The number of policies in-force before lapse and death after new business. Defined as:
pols_if_at(t, "BEF_NB") + pols_new_biz(t)
- pols_if_init()[source]#
Initial number of policies in-force
Number of in-force policies at time 0 referenced from
pols_if_at(0, "BEF_MAT").
- pols_lapse(t)[source]#
Number of lapse
Number of policies decreased by lapse during
tandt+1.See also
- pols_maturity(t)[source]#
Number of maturing policies
The policy maturity occurs when
duration_mth()equals 12 timespolicy_term(). The amount is equal topols_if_at(t, "BEF_MAT").otherwise
0.
- pols_new_biz(t)[source]#
Number of new business policies
The number of new business policies. The value
duration_mth(0)for the selected model point is read from thepolicy_countcolumn inmodel_point(). If the value is 0 or negative, the model point is new business at t=0 or at t whenduration_mth(t)is 0, and thepols_new_biz(t)is read from thepolicy_countinmodel_point().See also
- inv_income(t)[source]#
Investment income on account value
Investment income earned on account value during each period. For the plicies decreased by lapse and death, half the investment income is credited.
- inv_income_pp(t)[source]#
Investment income on account value per policy
Investment income on account value defined as:
inv_return_mth(t) * av_pp_at(t, "BEF_INV")
See also
- inv_return_mth(t)[source]#
Rate of investment return
Rate of monthly investment return for
scen_idandtread frominv_return_table()See also
inv_return_table()scen_id
- av_at(t, timing)[source]#
Account value in-force
av_at(t, timing)calculates the total amount of account value at timetfor the policies represented by a model point.At each
t, the events that change the account value balance occur in the following order:Maturity
New business and premium payment
Fee deduction
The second parameter
timingtakes a string to indicate the timing of the account value, which is either"BEF_MAT","BEF_NB"or"BEF_FEE".BEF_MAT
The amount of account value before maturity, defined as:
av_pp_at(t, "BEF_PREM") * pols_if_at(t, "BEF_MAT")
BEF_NB
The amount of account value before new business after maturity, defined as:
av_pp_at(t, "BEF_PREM") * pols_if_at(t, "BEF_NB")
BEF_FEE
The amount of account value before lapse and death after new business, defined as:
av_pp_at(t, "BEF_FEE") * pols_if_at(t, "BEF_DECR")
See also
- av_change(t)[source]#
Change in account value
Change in account value during each period, defined as:
av_at(t+1, 'BEF_MAT') - av_at(t, 'BEF_MAT')
See also
- av_pp_at(t, timing)[source]#
Account value per policy
av_at(t, timing)calculates the total amount of account value at timetfor the policies in-force.At each
t, the events that change the account value balance occur in the following order:Premium payment
Fee deduction
Investment income is assumed to be earned throughout each month, so at the middle of the month when death and lapse occur, half the investment income for the month is credited.
The second parameter
timingtakes a string to indicate the timing of the account value, which is either"BEF_PREM","BEF_FEE","BEF_INV"or"MID_MTH".BEF_PREM
Account value before premium payment. At the start of the projection (i.e. when
t=0), the account value is set toav_pp_init().BEF_FEE
Account value after premium payment before fee deduction
BEF_INV
Account value after fee deduction before crediting investemnt return
MID_MTH
Account value at middle of month (
t+0.5) when half the investment retun for the month is credited
- coi(t)[source]#
Cost of insurance charges
The cost of insurance charges deducted from acccount values each period.
See also
- net_amt_at_risk(t)[source]#
Net amount at risk per policy
Return sum assured net of account value per policy.
See also
- prem_to_av(t)[source]#
Premium portion put in account value
The amount of premiums net of loadings, which is put in the accoutn value.
See also
load_prem_rate()
- prem_to_av_pp(t)[source]#
Per-policy premium portion put in the account value
The amount of premium per policy net of loading, which is put in the accoutn value.
See also
load_prem_rate()
- claims(t, kind=None)[source]#
Claims
The claim amount during the period from
ttot+1. The optional second parameter is for indicating the type of the claim, and it takes a string, which is either"DEATH","LAPSE"or"MATURITY", or defaults toNoneto indicate the total of all the types of claims during the period.The death benefit as denoted by
"DEATH"is defined as:claim_pp(t) * pols_death(t)
The surrender benefit as denoted by
"LAPSE"is defined as:claims_from_av(t, "LAPSE") - surr_charge(t)
The maturity benefit as denoted by
"MATURITY"is defined as:claims_from_av(t, "MATURITY")
- claims_from_av(t, kind)[source]#
Account value taken out to pay claim
The part of the claim amount that is paid from account value. The second parameter takes a string indicating the type of the claim, which is either
"DEATH","LAPSE"or"MATURITY".Death benefit is denoted by
"DEATH", is defined as:av_pp_at(t, "MID_MTH") * pols_death(t)
When the account value is greater than the death benefit, the death benefit equates to the account value.
Surrender benefit as denoted by
"LAPSE"is defined as:av_pp_at(t, "MID_MTH") * pols_lapse(t)
As the surrender benefit is defined as account value less surrender charge, when there is no surrender charge the surrender benefit equates to the account value.
Maturity benefit as denoted by
"MATURITY"is defined as:av_pp_at(t, "BEF_PREM") * pols_maturity(t)
By default, the maturity benefit equates to the account value of maturing policies.
- claims_over_av(t, kind)[source]#
Claim in excess of account value
The amount of death benefits in excess of account value.
coi()net of this amount represents mortality margin.See also
margin_mortality()
- commissions(t)[source]#
Commissions
By default, 100% premiums for the first year, 0 otherwise.
See also
premiums()
- expenses(t)[source]#
Expenses
Expenses during the period from
ttot+1defined as the sum of acquisition expenses and maintenance expenses. The acquisition expenses are modeled asexpense_acq()timespols_new_biz(). The maintenance expenses are modeled asexpense_maint()timesinflation_factor()timespols_if_at()before decrement.
- surr_charge(t)[source]#
Surrender charge
Surrender charge rate times account values of lapsed policies
- net_cf(t)[source]#
Net cashflow
Net cashflow for the period from
ttot+1defined as:premiums(t) - claims(t) - expenses(t) - commissions(t)
See also
premiums()
- margin_expense(t)[source]#
Expense margin
Expense margin is defined as the sum of premium loading, surrender charge and maintenance fees net of commissions and expenses.
The sum of the expense margin and mortality margin add up to the net cashflow.
See also
load_prem_rate()
- margin_guarantee(t)[source]#
Mortality margin
Mortality margin is defined
coi()net ofclaims_over_av().The sum of the expense margin and mortality margin add up to the net cashflow.
See also
- pv_claims_from_av(kind=None)[source]#
Present value of claims
See
claims()for the parameterkind.See also
- pv_claims_over_av(kind=None)[source]#
Present value of claims
See
claims()for the parameterkind.See also
- pv_inv_income()[source]#
Present value of investment income
The discounted sum of monthly investment income.
See also
- pv_net_cf()[source]#
Present value of net cashflows.
Defined as:
pv_premiums() + pv_inv_income() - pv_claims() - pv_expenses() - pv_commissions() - pv_av_change()
- pv_pols_if()[source]#
Present value of policies in-force
Note
This cells is not used by default.
The discounted sum of the number of in-force policies at each month. It is used as the annuity factor for calculating
net_premium_pp().
Present value of premiums
See also
premiums()
- result_sample(point_id=1, scen=1)[source]#
Sample projection result for a specific model point and scenario
- check_av_roll_fwd()[source]#
Check account value roll-forward
Returns
Tureifav_at(t+1, "BEF_NB")equates to the following expression for allt, otherwise returnsFalse:av_at(t, "BEF_MAT") + prem_to_av(t) - maint_fee(t) - coi(t) + inv_income(t) - claims_from_av(t, "DEATH") - claims_from_av(t, "LAPSE") - claims_from_av(t, "MATURITY"))
- check_margin()[source]#
Check consistency between net cashflow and margins
Returns
Trueifnet_cf()equates to the sum ofmargin_expense()andmargin_mortality()for allt, otherwise, returnsFalse.See also
margin_mortality()