The Projection Space#

The by-policy projection of the WholeLife_JP_S model.

The Space is parameterized by point_id, so Projection[1] is an ItemSpace projecting model point 1:

>>> Projection[1].result_cf()          # the worked example's anchor cell
>>> Projection.point_id = 5            # or switch the default

t is the 0-based policy-month index: t = 0 is the first policy month, month t runs from time t to time t + 1, the frame is range(proj_len()) with proj_len() = 12 (omega_age() - age_at_entry()) + 1, so the last index is proj_len() - 1. The contractual policy year is the 1-based label policy_year(t) = 1 + t // 12, derived and never indexed by, and duration(t) = t // 12 is the count of completed policy years.

Values carry a second index, and it is still the anniversary in years: d = 0 proj_years() with d = 0 at issue. pol_val_pp(), cv_pp(), surr_charge_pp(), reserve_pp(), loan_pp() and their companions are values at a 年単位の契約応当日 and not flows of a period, and none of their numbers moved when ``t`` became a month. The month t opens inside the policy year running from anniversary duration(t) to duration(t) + 1 and is settled net of the loan balance at the first of those.

There is no maturity date and no 満期保険金; the horizon is the terminal age of the mortality table, every remaining life dies in the terminal policy year, and nothing is paid there but the death benefit. There are no tail states. The frame stops in the first month of that terminal year, which is the + 1 in proj_len(): the table’s rate at omega is 1 and so is its monthly equivalent, so the cohort clears there and the eleven months after it would be rows of zeros.

The monthly grid: what moved and what did not

The contract is quoted in years and valued at anniversaries, so the monthly step is finer than the guarantees rather than finer than the product. Three things therefore stayed annual on purpose, and four moved.

Annual, because the contract is. The policy value constructionepv_death(), annuity_due(), prem_net_level_pp(), prosp_val_pp(), reserve_pp() — is built from annual actuarial functions and calibrated to one carrier’s published annual surrender-value run, so re-deriving it monthly would move a number that was fitted rather than assumed. The loan balances compound once a year because the 約款 states a 年利 capitalised at the 契約応当日. And the APL continuation test is the question the insurer asks when a premium goes unpaid, which happens once a year; its cohort index s is accordingly a policy year and not a month.

Monthly, because the experience is. Mortality and ordinary surrender are rates per unit time and are taken to the month on the effective convention r_m = 1 - (1 - r)^(1/12), so twelve of them compound back to the annual rate exactly and survivorship at the anniversaries is identical to the annual-grid model’s. The premium, being 年払, now falls in one month out of twelve instead of being smeared across a year — which is what a 年払 contract actually looks like. Maintenance expense is a twelfth of the annual amount each month, inflating once a policy year. And the cliff is one month wide.

One convention is new and one ruling changed. The new convention is pol_val_at_m(), which reads the surrender value between anniversaries by linear interpolation in elapsed months [std] — the 算出方法書 that would state the real rule is unpublished, and the anniversary values it interpolates are untouched. The changed ruling is cv_mult_at_m(): the annual grid had to pay every surrender in policy year m the post-step value, because the step and the grid landed on the same year; here the suppression ends at the month the contract ends it, so eleven months of policy year m move to the pre-step side and the 15% surge moves to the month after the last premium, where the step actually is. That is the largest single difference between the two runs of this product.

Input data

Inputs are external files: plain CSVs living in the model folder’s parent directory, products/whole_life/, read at run time rather than stored inside the model. The model folder therefore holds nothing but formulas — no _data/, no IOSpec, no embedded values — so a diff of the model shows logic changes only, and an input can be edited or swapped without rewriting the model. This follows annuallife.TradLife_A; contrast basiclife.BasicTerm_S, which keeps its inputs inside the model.

Each table has a filename Reference and a reader Cells, both on Data, reached here through the data Reference:

Reference

Cells

File

model_point_file

data.model_point_table()

model_point_table.csv

mort_table_file

data.mort_table()

mort_table.csv

lapse_table_file

data.lapse_table()

lapse_table.csv

Naming

Cells names follow lifelib’s basiclife.BasicTerm_S and savings.CashValue_SE wherever those models have an analogue — pols_* for policy counts, plural nouns for cash flows, *_rate for rates, *_pp for per-policy amounts, claims(t, kind) with an uppercase kind string, pols_if_at(t, timing) for the within-month in-force reads, cv_pp rather than av_pp because this is a cash surrender value and not an account value. The technical notes use compact actuarial symbols instead. The mapping is:

Notes symbol

Cells

Meaning

(none)

model_point()

The selected model point row

x

age_at_entry()

契約年齢 at issue, 満年齢

x + floor(t/12)

age(t)

Attained age in month t

floor(t/12)

duration(t)

Completed policy years

y(t) = 1 + floor(t/12)

policy_year(t)

Contractual policy year

omega

omega_age()

Terminal age of the table

T_y

proj_years()

Policy years, the span of d

T

proj_len()

Number of months projected

m

prem_term(), prem_period()

保険料払込期間; 0 is 終身払

12m

prem_period_months()

払込満了, in policy months

(none)

prem_end()

Last policy year a premium is due

SA

sum_assured(), sum_assured_at(t)

保険金額 at issue, in month t

P

premium_pp()

Annual premium

k

low_cv_rate()

解約払戻金支払割合

q(t)

mort_rate(t)

Mortality incl. 高度障害, annual

q_m(t)

mort_rate_mth(t)

The same, per month

(table q)

mort_rate_at_age(y)

Table rate at attained age y

(none)

mort_rate_base(t)

Table rate in month t, annual

(none)

mort_be_factor()

Multiplier on the table rate

w(t)

lapse_rate(t)

Surrender rate, annual

w_m(t)

lapse_rate_mth(t)

The same, per month

(table w)

lapse_rate_base(t)

Before the dynamic factor

s

lapse_spike()

Cliff surge, the parameter

s(t)

lapse_spike_rate(t)

The surge, in its one month

beta

lapse_beta

Dynamic-surrender slope

w_dyn(t) / w(t)

lapse_dyn_factor(t)

Dynamic-surrender multiplier

cumprem(d)

cum_prem_pp(d)

Premiums paid by anniversary d

cumprem at month u

cum_prem_pp_m(u)

The same, by elapsed month

u(t)

default_rate(t)

Premium-default rate

(none)

apl_active()

Whether any cohort can exist

l(t)

pols_if(t)

In force at the start of month t

(within-month)

pols_if_at(t, timing)

BEF_DECR/BEF_LAPSE/BEF_SPIKE/…

(paying cohort)

pols_if_pay(t)

In force and paying premium

lp(t)

pols_pay_bef_decr(t)

Payers after the default exit

(none)

pols_default(t)

Movers into the APL state

D(t)

pols_death(t)

Expected deaths in month t

S(t)

pols_lapse(t)

Expected surrenders in month t

(ordinary part)

pols_lapse_base(t)

Surrenders before the surge

(cliff part)

pols_lapse_spike(t)

The surge itself

(cumulative)

pols_exit_cum(t)

Every exit to month t

(APL failure)

pols_apl_exit(t)

Exits on APL exhaustion

(loan excess)

pols_loan_exit(t)

Exits on loan excess

i_cv

i_cv

Cash-value basis rate

i_std

i_std

Reference valuation rate

i_L

i_loan

APL / 契約者貸付 rate

alpha

acq_dedn_rate

Acquisition-deduction rate

(none)

disc_factor(), disc_factor_std()

1 / (1 + i)

A(y)

epv_death(y)

Whole-life EPV of 1 at age y

a-double-dot(y, n)

annuity_due(y, n)

n-year annuity-due at age y

A*(y), a*(y, n)

epv_death_std(y), annuity_due_std

The same on i_std

pi

prem_net_level_pp()

Net level premium on i_cv

pi*

prem_net_level_std_pp()

Net level premium on i_std

W(d)

prosp_val_pp(d)

Prospective policy value

SC(d)

surr_charge_pp(d)

解約控除

V(d)

pol_val_pp(d)

Ordinary surrender value

V at month u

pol_val_at_m(u)

The same, interpolated [std]

CV(d)

cv_pp(d)

Payable 解約返戻金

CV at month u

cv_at_m(u)

The same, at elapsed month u

k V(d)

cv_pp_susp(d)

Suppressed value at every d

k V at month u

cv_susp_at_m(u)

The same, at elapsed month u

(none)

cv_mult(d)

1 or k, by anniversary

(none)

cv_mult_at_m(u)

1 or k, by elapsed month

(reserve)

reserve_pp(d)

平準純保険料式 reserve

L(d)

loan_pp(d)

Main-cohort balance at d

L(d) by cohort

loan_apl_pp(d, s)

APL balance by entry year s

A(d)

apl_advance_due(d)

Premium advanced at d

(trigger)

apl_fires(d, s)

APL continuation test

CV*(d)

apl_test_val(d)

Value the APL test runs on

CV* at month u

apl_test_val_m(u)

The same, at elapsed month u

(exhaustion)

apl_fail_year(s)

Anniversary the cohort ends at

(exhaustion)

apl_fail_month(s)

The same, as a month

(advances)

apl_advances(s)

Number of advances made

(loan excess)

loan_fail_year(), loan_fail_month()

Where the loan outgrows CV

(none)

pol_loan_year()

Policy year the 契約者貸付 is drawn

(none)

pua_sum_assured()

払済保険金額 after conversion

P lp(t)

premiums(t)

Premium income, once a year

(SA - L)D, (CV - L)S

claims(t, kind)

Benefit outgo by kind

ec D(t)

claim_expenses(t)

Claim expense

E0, e_m(t)

expenses(t)

Acquisition and maintenance

(none)

inflation_factor(t)

Expense inflation factor

c0, c_r

commissions(t)

Commission outgo

(dividend)

dividends(t)

5年ごと利差配当 outgo

CF(t)

net_cf(t)

Net cash flow, income positive

Six names needed care.

The notes write V(d) for the ordinary, unsuppressed surrender value and CV(d) for the amount actually payable. pol_val_pp() is V and cv_pp() is CV, and cv_pp_susp() is the third quantity the notes need at the anniversary d = m: k V(d) at every duration, which is both the value an instant before the step and the value the clawed-back APL cohort keeps for life. All three are one policy value times one multiplier — there is no second reserve run anywhere in this model.

L is one symbol in the notes but two objects here. loan_pp() is the 契約者貸付 balance of the premium-paying cohort; loan_apl_pp() is the automatic premium loan balance of a cohort indexed by the anniversary s it defaulted at. They are kept apart because the APL exhausts at a duration that depends on s, so collapsing the cohorts to an average balance would let early entrants ride on late entrants’ headroom.

Every *_at_m cells is the monthly reading of an annual contractual quantity, and the suffix is the warning: cv_pp(d) is the 解約返戻金 the contract defines at an anniversary, and cv_at_m(u) is what this model pays someone who surrenders between two. They agree wherever the contract has an opinion. Where they differ — cv_mult_at_m() inside the last year of the 保険料払込期間 — the difference is the subject of its own docstring rather than a rounding.

lapse_rate no longer carries the cliff surge. lapse_spike_rate() does, and it is a one-off proportion in one month, not a rate: converting it to a monthly equivalent would spread one decision, taken on a date, over a year in which the thing that provokes it has not yet happened.

expenses is acquisition plus maintenance only. The claim handling expense is claim_expenses(), a separate cells, deducted explicitly in net_cf() and published as its own claim_expenses column in result_cf(), exactly as the notes’ worked-example table prints it. This is the settled meaning across the three libraries, so an expenses column means the same thing in all of them.

mort_be_factor is the cells; mort_adj is the model-point column it reads. The cells name is the library-wide one for the multiplier that turns the shipped valuation table into the projection basis, and the column keeps the spelling it ships with, so a CSV written against an earlier revision still loads.

The 低解約返戻金型 cliff is a step, not a ramp

CV(d) = k V(d) for d < m and CV(d) = V(d) for d >= m, with k = 0.70 where the suppressed form is elected. The transition at the anniversary d = m is a step: the ratio cv_pp(m) / (low_cv_rate() * pol_val_pp(m)) is exactly 1 / k, and anything between is an interpolation the contract does not have. Both quantities exist at d = m and the model publishes both, cv_pp() and cv_pp_susp().

On this grid the step is at the month the contract puts it. A surrender at elapsed month 12m - 1 is still inside the 保険料払込期間 and is paid k V; one at 12 m is not and is paid V. The annual grid could not draw that line — the step and its own step were the same size — so it ruled [std ordering] that the whole of policy year m was paid the post-step value, and put the behavioural surge there too. Here eleven of those twelve months are on the pre-step side and the surge is in the month after the last premium, beside the step that causes it. Nothing about the contract changed; the grid stopped rounding it.

On a 終身払 point (prem_term = 0) the suppressed period runs for life and the step never happens, which is why one shipped model point is written that way: it is the one configuration in which the product’s signature mechanic is absent by construction.

Lapse is a funded event

Where the premium is unpaid and there is a surrender value, the insurer lends the premium against that value and applies it to the premium, and the contract continues. So a premium default is not a lapse: default_rate() moves policies out of the paying cohort into an APL state, and only the failure of the continuation test

apl_test_val(t + 1) >= loan_apl_pp(t, s) + premium_pp() * (1 + i_loan)

terminates them — the value at the anniversary the advanced premium would carry the contract to, against the balance at the anniversary the test is made at. The test runs on the suppressed value, which is the whole point: on the anchor cell a default at s = 1 (policy year 2) buys one advance at k = 0.70 and thirteen at k = 1.00. Running it on V overstates the headroom by more than a decade of in force.

The advance is not cash income. No cash reaches the insurer, so an APL cohort produces no premiums() entry and no renewal commission; a loan asset is created and shows up only as growth in loan_apl_pp() and as a deduction from every later benefit. net_cf() is unchanged by an advance in the month it is made — which, the premium being 年払, is an anniversary month and no other.

The clawback survives the step. A cohort carried through the low period by unrepaid advances has by definition not paid those premiums, so [std] its value stays at k V(d) for ever and never steps up at m. apl_clawback switches that off, and the difference is sixteen years of in force on the anchor cell.

Modules that are off in the base run

Six of the notes’ optional constructions are implemented and switched off, so that the base run reproduces the worked example while the machinery stays visible and testable:

  • Premium default and the APL, default_rate at 0 on the base points and 1% per premium in policy years 1 to m — the anniversary months t = 0, 12, …, 12(m - 1) — on model points 5 and 6, which run it on the suppressed and the ordinary form respectively. It is applied once per premium and never converted to a monthly rate: a default is the failure to pay one premium on one date.

  • 契約者貸付, pol_loan_util at 0, with model point 7 drawing the contractual maximum at the anniversary d = 39, which opens policy year 40, and reaching the loan-excess termination at an anniversary decades later, with the benefit floored at zero. The 9/10-while-paying and 8/10-once-paid-up caps are contractual and always applied.

  • Dynamic surrender on the 払戻率, w_dyn = w min(3, max(1, 1 + beta (CV/cumprem - 1))) with lapse_beta = 2, off unless the model point sets dyn_lapse. Model point 8 turns it on and sets the cliff spike to zero, so the spike is produced endogenously instead of imposed — a cross-check on the 15% [std] choice rather than a replacement for it.

  • The cliff spike itself, lapse_spike, 15% [std] on every point but 8, taken as a one-off in the single month after the last premium. It is a behavioural assumption and nothing in any retrieved document quantifies it; the step in CV that provokes it is contractual, and the two must not be confused.

  • 払済保険 conversion, pua_year, 0 except on model point 4. The contract stops paying premiums, the sum assured is replaced by (CV - L) / A(x + d) on the same single-premium basis, and the suppression switches off for the future — but the conversion is made on the suppressed value, so the resulting 払済保険金額 is permanently smaller.

  • 5年ごと利差配当, dividend_type, none except on model point 9. The composite is 無配当; the participating variant declares a dividend out of investment margin every fifth year — in the last month of it — here as div_spread times five years of the policy value [std], because the declaration basis lives in the unpublished 算出方法書 and no carrier publishes it.

mort_be_factor is the last lever, 1.00 on every point but 9. At 1.00 the base run is a valuation-table run, not a best estimate: 生保標準生命表2018(死亡保険用)carries a roughly-2σ prudential margin and an eight-year improvement allowance already inside it, and no retrieved source sizes either against current insured experience. Claims move proportionately with mort_be_factor; the terminal rate is held at 1 whatever it is set to, because omega_age is the table’s horizon and not an experience assumption.

責任準備金 is not 解約返戻金

reserve_pp() is the 平準純保険料式 policy reserve, on i_std and the same table, and it never produces a cash flow. It exists so that the notes’ identity

reserve_pp(d) - pol_val_pp(d) = surr_charge_pp(d)

can be asserted — which it can only because i_std defaults to i_cv. When the two basis rates differ the ordering can fail outright: with a 標準利率 below the pricing basis the statutory reserve exceeds the cash value by far more than the 解約控除, and in a deep 逆ざや the reserve can exceed even the sum assured. reserve_pp >= pol_val_pp >= cv_pp is not a model invariant and check_reserve_identity() does not assert it.

Sign convention

The notes’ CF(t) is already income positive — premiums less claims, expenses and commission — which is the library-wide sign of net_cf(), so there is no liability_cf companion to publish: one stream, one sign, one name.

Cells Descriptions#

model_point()[source]#

The selected model point as a Series.

sex()[source]#

The sex of the insured, M or F; the two are rated and tabulated separately.

age_at_entry()[source]#

x: the 契約年齢 at issue, 15 to 80.

満年齢 (man-nenrei, attained age) with the fractional year discarded at 契約日; the rating age then increments on each 年単位の契約応当日 rather than on the birthday, so a projection stepped on anniversaries steps it correctly by construction. The mortality table does not share this basis: 生保標準生命表2018(死亡保険用)is built for a 保険年齢 (nearest-birthday) basis, and the table is read here at the 満年齢 attained age with no adjustment [std], because no public mapping between the two exists. The resulting bias understates mortality by up to half a year of age.

sum_assured()[source]#

SA: the 保険金額 at issue, level for life.

One amount pays two benefits — 死亡保険金 on death and 高度障害保険金 on the disability state defined in the 約款’s 別表 — and paying the second extinguishes the contract. They are one decrement on one amount, never two.

prem_term()[source]#

m: the 保険料払込期間 in years as entered, with 0 denoting 終身払.

On a 終身払 contract there is no 払込満了 date, the 低解約払戻期間 runs for life and the cliff never occurs. Use prem_period() for the effective number of years.

prem_period()[source]#

m: the effective 保険料払込期間 in years, proj_years() on a 終身払 contract.

The suppressed period is identical to the premium-paying period, so this is also the anniversary at which cv_pp() steps up where it steps up at all. It stays in years on the monthly grid because the contract states it in years: m is a contractual term, and the month it converts to is 12 m, which is prem_period_months().

prem_period_months()[source]#

12 m: the 保険料払込期間 in policy months — the month 払込満了 falls at.

The instant the 低解約返戻金型 suppression ends and the surrender value steps up by 1 / k. On the annual grid that step had to be smeared over the whole of policy year m; here it is the single month the contract puts it in.

prem_end()[source]#

The last policy year in which a premium is actually due.

prem_period() normally; one year less than pua_year() where a 払済保険 conversion is elected, because the contract stops paying at the conversion.

premium_pp()[source]#

P: the level annual premium per policy, payable in advance in policy years 1 to m.

Level and guaranteed for the whole of 保険料払込期間 with no unilateral repricing right, which puts every year of it inside any defensible contract boundary. On the anchor cell the value is sourced: ¥14,580 a month is published for exactly that cell, and the annual figure is 12 times it [std] — no carrier publishes an annual-mode scale, so the modal discount a real 年払 rate would carry is not applied and the annual premium is slightly overstated. On the other cells it is a [std] scaling of the anchor’s published-premium-to-prem_net_level_pp() ratio, divided by 0.837 on the ordinary form, that being the one carrier’s published ratio between its suppressed and its ordinary scale for one identical cell.

low_cv()[source]#

Whether the 低解約返戻金型 form is elected.

A model point flag rather than a modelling switch: the suppressed and ordinary forms are separately priced products, and the suppression buys a materially cheaper premium in exchange for a 30% haircut on the value during the premium-paying period.

low_cv_rate()[source]#

k: the 解約払戻金支払割合, 0.70 during the 低解約払戻期間 and 1.00 on the ordinary form.

Stated identically at four carriers. It is a multiplier on one common policy value, not a second reserve basis: at duration 40, well past 払込満了, the suppressed and the ordinary product have identical surrender values.

apl_elected()[source]#

Whether the 自動振替貸付 is elected; the default at four of the seven carriers.

Election varies more than any other feature in the source set — opt-out at four, opt-in at one, absent at two — so this is a genuine product variable. The supervisory guideline requires the facility to be at the policyholder’s election with prompt notice, which is why it is a flag with a default and never an unconditional no-lapse rule.

default_rate(t)[source]#

u(t): the premium-default rate in policy month t; 0 in the base run.

A decrement out of the premium-paying cohort into the APL state, not a lapse: a policy does not lapse while the cash value can carry the premium. Zero where the APL is not elected, and zero once no premium is due — the last premium falls at the anniversary opening policy year prem_end().

It is non-zero only in a premium due month, and on the monthly grid that is a statement the model can make. A premium default is the failure to pay a particular premium on a particular date, not a hazard running through the year, so the annual rate is applied once, at the anniversary the premium falls due, and never converted to a monthly equivalent. The annual grid could not tell the two readings apart.

apl_active()[source]#

Whether any policy can ever enter the APL state on this model point.

apl_elected() and a positive default_rate column. It exists to keep apl_entry_years() empty on the eight model points that never default, which is exact — no cohort can be non-empty without it — and which matters on the monthly grid in a way it did not on the annual one: the cohort sums run over the whole frame, so a model point with no APL at all would otherwise pay for twelve times as many empty summands as before.

pol_loan_util()[source]#

The fraction of cv_pp() drawn as a 契約者貸付; 0 in the base run.

There is no public take-up data of any kind, so the level is a [std] model point input. The contractual caps in loan_cap_rate() bind it whatever it is set to.

dividend_type()[source]#

The participation basis: none (the composite) or five_year.

無配当 is the composite default because it is the largest single group in the source set and because a dividend is an insurer-discretionary element rather than a contractual one. five_year is the 5年ごと利差配当 variant, declared out of investment margin every fifth policy year; see dividends().

lapse_spike()[source]#

s: the extra surrender rate applied in policy year m [std], 15% in the base run.

The step in cv_pp() at 払込満了 is contractual; the surge in surrenders at the step is a behavioural assumption and nothing in any retrieved document quantifies it. It is held as its own parameter so that setting it to zero and re-running reads its effect directly, which is the right way to challenge it.

dyn_lapse()[source]#

Whether the dynamic-surrender module is on; off in the base run.

mort_be_factor()[source]#

The multiplier on the table mortality rate; 1.00 in the base run.

1.00 is a choice, not a default: it means the base run is a valuation-table run, not a best estimate. 生保標準生命表2018(死亡保険用)carries a roughly-2σ prudential margin and a built-in eight-year improvement allowance, but no retrieved source sizes either against current insured experience, so no defensible single haircut exists. A production basis would sit below 1.00 and would move claims proportionately.

Read from the model point’s mort_adj column, which keeps that spelling; the cells carries the library-wide name for the factor.

pua_year()[source]#

The policy year at which 払済保険 is elected, or 0 for no conversion.

Off on every model point but one. The conversion is made at the anniversary pua_year() - 1, so the earliest meaningful value is 2.

is_paid_up(t)[source]#

Whether the contract is on the 払済保険 basis in policy month t.

The election takes effect from policy year pua_year(), i.e. from the month 12 (pua_year() - 1); the anniversary it is made at is pua_year() - 1.

omega_age()[source]#

omega: the terminal age of the mortality table, the first age at which q = 1.

109 for males and 113 for females on 生保標準生命表2018(死亡保険用). It is a hard model parameter and not a rounding: projecting a whole life contract to 100, a U.S. habit, truncates the liability, and projecting to 120 invents one.

proj_years()[source]#

T_y = omega - x + 1: the number of policy years the contract can run.

The span of the anniversary index d, which stays in years on this grid because every contractual value in the product — the surrender value, the 解約控除, the reserve, the 保険料払込期間 — is defined at an anniversary and quoted by policy year. d therefore runs 0 .. proj_years() and none of its numbers moved when t became a month.

proj_len()[source]#

T: the number of policy months projected, 12 (omega - x) + 1.

The exclusive end of the frame, counted from t = 0: result_cf() covers t = 0, ..., proj_len() - 1 and len(result_cf()) == proj_len(). There is no maturity date, so the horizon is the table’s, not the contract’s.

The + 1 is the terminal month and is the whole of the terminal policy year that this model needs. The table’s rate at omega is 1, so its monthly equivalent 1 - (1 - 1)^(1/12) is also 1: every life still in force at the start of the terminal policy year dies in its first month, and the eleven months after it would be rows of zeros. The frame stops at the month the cohort clears — pols_if(T) is zero, nothing is paid at the horizon but the death benefit, and there are no tail states.

duration(t)[source]#

The number of completed policy years at the start of policy month t, t // 12.

The bridge between the monthly projection index and the annual anniversary index d: month t opens inside policy year duration(t) + 1, which runs from anniversary duration(t) to anniversary duration(t) + 1.

policy_year(t)[source]#

y(t) = 1 + t // 12: the contractual policy year of month t, a 1-based label.

Months t = 0 .. 11 are policy year 1. The label exists because the contract’s own schedules are quoted in policy years — the 保険料払込期間 m, the policy_year column of lapse_table.csv, pua_year and pol_loan_year — and it is derived, never indexed by: every cells of this model is indexed by the 0-based month t or by the anniversary d.

age(t)[source]#

x + floor(t / 12): the attained age during policy month t.

The 契約年齢 holds for the twelve months t = 0 .. 11, and the rating age increments at each 年単位の契約応当日 rather than at the birthday, so stepping it on the anniversary is what the contract does.

mort_rate_at_age(y)[source]#

The shipped table’s mortality rate at attained age y, before mort_be_factor.

Read from mort_table.csv, a [std] construction anchored on quoted rates of 生保標準生命表2018(死亡保険用)rather than a copy of it; see Data. The rate already includes 高度障害, so a projection using it must not add a separate disability decrement. This is the rate the contractual cash-value construction uses, unadjusted: mort_be_factor is a best-estimate lever on the decrement, not a change to the 算出方法書 basis.

mort_rate_base(t)[source]#

The annual table mortality rate in month t, at attained age age(t).

Level across the twelve months of a policy year, because the table is graduated by 整数年齢 and the rating age steps on the anniversary.

mort_rate(t)[source]#

q(t): the annual mortality rate in policy month t, 高度障害 included.

The table rate times mort_be_factor(), capped at 1. At the table’s terminal age the rate is held at 1 whatever mort_be_factor is: omega_age is the horizon of the table and a structural property of the projection, not an experience assumption, and scaling it would leave lives alive past the end of the table.

This is the annual rate the table is stated on and the notes quote; mort_rate_mth() is the decrement actually applied to the month.

mort_rate_mth(t)[source]#

q_m(t): the monthly mortality decrement, 1 - (1 - q(t))^(1/12) [std].

The effective convention, not a nominal q / 12: twelve months of it compound back to the annual rate exactly, so survivorship at the anniversaries is the same as the annual-grid model produced and every difference between the two runs is a timing difference rather than a change of basis.

At the terminal age q = 1 and this is 1 as well, which is why the frame ends in the first month of the terminal policy year: the cohort clears there and cannot be spread over a year that no longer exists.

lapse_rate_base(t)[source]#

The base annual voluntary surrender rate in month t [std].

lapse_table.csv is keyed by the contractual policy_year, a 1-based label, so the lookup goes through policy_year(): period t reads row t + 1. 4% / 3% / 2%, with the last row of lapse_table.csv read for every later year. The shape is reasoned, not fitted: a 低解約返戻金型 owner who surrenders during the low period takes a 30% haircut on a value that is already below cumulative premiums, so early surrender is strongly suppressed. No carrier publishes a lapse curve by duration; the only public benchmark is an amount-weighted, all-product industry 解約・失効率 of 5.6%, used here as a sanity ceiling and nothing more.

cum_prem_pp(d)[source]#

cumprem(d): premiums paid per policy by the anniversary d.

P min(d, prem_end()) — the premiums falling due at times 0 d - 1. An anniversary quantity, like the surrender value it is compared with: the denominator of the 払戻率 the dynamic-surrender module keys off, and the quantity the product is sold on, since the 低解約返戻金型 value crosses 100% of it shortly after 払込満了.

cum_prem_pp_m(u)[source]#

cumprem at elapsed month u: premiums paid per policy by that instant.

The premium is annual and falls at the anniversaries 0, 12, 24, , so the count paid by elapsed month u is ceil(u / 12) capped at prem_end() — and it is a step function of u, not a smooth accrual, because that is what paying once a year is. It agrees with cum_prem_pp() at every anniversary.

lapse_dyn_factor(t)[source]#

The dynamic-surrender multiplier on the lapse rate [std]; 1 in the base run.

min(3, max(1, 1 + beta max(0, CV/cumprem - 1))), read at the end of month t, which is where the surrender is paid. On the monthly grid the ratio is therefore a monthly series rather than an annual one, and the surge it produces on model point 8 builds over the months around 払込満了 instead of arriving in one annual step. The economically natural driver on a savings-shaped contract is the ratio of the value to the premiums paid, and on the anchor cell that ratio crosses 1 exactly at the cliff — so with the module on and lapse_spike at zero the surge at 払込満了 is produced endogenously instead of imposed. There is no public calibration evidence for the form or for beta.

lapse_rate(t)[source]#

w(t): the annual voluntary surrender rate of the policy year containing month t.

The table rate times the dynamic multiplier, capped at 1. A surrender is not a pure decrement here: it pays cv_at_m() net of any loan.

The cliff spike is no longer inside it. On the annual grid the 15% surge at 払込満了 had to be added to this rate, because the year was the finest thing there was; here it is lapse_spike_rate(), a one-off proportion of the survivors of the single month the step happens in. The two are different kinds of quantity — one is a rate per unit time that converts to a month, the other is a decision taken on a date that does not — and keeping them apart is the same ruling this library makes for the renewal decline in Term_JP_S.

lapse_rate_mth(t)[source]#

w_m(t): the monthly ordinary surrender rate, 1 - (1 - w(t))^(1/12) [std].

The same effective convention as mort_rate_mth(), so the twelve months of a policy year compound back to the annual table rate. It excludes the cliff spike, which is lapse_spike_rate().

lapse_spike_rate(t)[source]#

s: the one-off surrender surge at 払込満了 [std], 15% in the base run.

Non-zero in exactly one month of the whole projection — t = prem_period_months(), the first month after the last premium, which is the month the 解約返戻金 steps up by 1 / k. Zero on a 終身払 contract, which has no 払込満了 and therefore no step, and zero once the contract is on the 払済保険 basis.

It is not annualized and never converted to a monthly rate. The step in cv_at_m() is contractual and instantaneous; the surge in surrenders at the step is a behavioural response to it, taken by owners who have been waiting for the step, and it is a proportion of the people standing there rather than a hazard running through a year. The annual grid had to spread it over the twelve months of policy year m and pay those surrenders the post-step value, which put the surge a year before the event that causes it; here the surge and the step are in the same month.

Nothing in any retrieved document quantifies it. It is held as its own cells so that setting lapse_spike to zero and re-running reads its effect directly, which is the right way to challenge it — and model point 8 does exactly that, replacing it with the endogenous dynamic-surrender module.

disc_factor()[source]#

v = 1 / (1 + i_cv): the discount factor of the cash-value basis.

i_cv is [std] and derived rather than asserted. The 予定利率, 予定死亡率 and 予定事業費率 live in the filed but unpublished 算出方法書, so the library constructs the policy value in closed form and calibrates it to one carrier’s complete published surrender-value run. The calibrated rate lands below the 予定利率 that carrier disclosed fifteen years earlier, which is informative rather than embarrassing.

disc_factor_std()[source]#

v* = 1 / (1 + i_std): the discount factor of the reference valuation basis.

i_std stands for the 標準利率, whose current numeric value could not be established from any retrieved official document — the 安全率係数 table for the annual case is printed as an omitted table in the retrieved redline. It therefore defaults to i_cv [std], which is what makes the reserve identity exactly testable.

epv_death(y)[source]#

A(y): the expected present value at age y of 1 payable at the end of the year of death.

On i_cv and the shipped table, unadjusted by mort_be_factor. Recursive: A(y) = v [q(y) + (1 - q(y)) A(y + 1)], with A(omega + 1) = 0 and q(omega) = 1, so A(omega) = v and the recursion terminates at the table.

annuity_due(y, n)[source]#

a-double-dot(y, n): the n-year annuity-due of 1 per year at age y, on i_cv.

1 + v p(y) a(y + 1, n - 1), zero for n <= 0. Measured in years of premium, so SA A(x) / a(x, m) is an amount per year.

epv_death_std(y)[source]#

A*(y): epv_death() on the reference valuation rate i_std.

annuity_due_std(y, n)[source]#

a*(y, n): annuity_due() on the reference valuation rate i_std.

prem_net_level_pp()[source]#

pi = SA A(x) / a(x, m): the net level premium of the cash-value construction.

This is not the priced net premium and must not be read as one. On the anchor cell it comes out above the gross premium, which would be a negative expense loading and no real product carries one: the construction uses the valuation table’s margin-loaded q as a stand-in for the insurer’s unpublished 予定死亡率, and surr_charge_pp() absorbs the difference. It reproduces the contractual value; it is not a pricing model.

prem_net_level_std_pp()[source]#

pi*: the net level premium of the 平準純保険料式 reserve, on i_std.

prosp_val_base_pp(d)[source]#

W(d) on the premium-paying construction, before any 払済保険 conversion.

SA A(x + d) - pi a(x + d, max(m - d, 0)): the prospective net level premium policy value at anniversary d, d = 0 at issue, which is the end of period d - 1 and the start of period d. W(0) = 0 by construction and W(T) = 0 because the table terminates.

pua_sum_assured()[source]#

The 払済保険金額 the contract converts to, or 0 where no conversion is elected.

(CV(p - 1) - L(p - 1)) / A(x + p - 1) at the conversion anniversary d = p - 1, on the insurer’s own single-premium net basis. The conversion is made on the suppressed value, so a 低解約返戻金型 contract converted during the low period carries a permanently smaller paid-up sum assured than the same contract converted after 払込満了.

sum_assured_at(t)[source]#

The sum assured in force in period t: SA, or the 払済保険金額 after conversion.

prosp_val_pp(d)[source]#

W(d): the prospective policy value at anniversary d, conversion included.

The premium-paying construction until the 払済保険 election, then the single-premium value pua_sum_assured() A(x + d) of the reduced paid-up contract. The change of basis at the conversion anniversary pua_year() - 1 is a contractual re-basing, not a roll-forward step, and check_pol_val_roll_fwd() excludes the one period that rolls into it for exactly that reason.

surr_charge_base_pp(d)[source]#

SC(d) on the premium-paying construction: the 解約控除 grading to zero at m.

alpha SA max(0, m - d) / m [std], an initial deduction of 0.90% of the sum assured grading linearly to nothing at 払込満了, the anniversary d = m. On a 終身払 contract the grading has no end date, so the deduction is held flat at alpha SA for life — the limit of the same formula as m goes to infinity.

surr_charge_pp(d)[source]#

SC(d): the 解約控除 embedded in the surrender value at anniversary d.

Zero once the contract is on the 払済保険 basis: the deduction was taken at the conversion, and the paid-up contract is a single-premium contract with none left to take.

pol_val_pp(d)[source]#

V(d): the ordinary, unsuppressed surrender value at anniversary d.

max(0, W(d) - SC(d)). The floor is not decoration: W - SC is negative in principle at d = 0, the issue instant, and none of this model’s amounts may produce a negative payment. This is the one policy value from which the suppressed value, the 払済保険 conversion amount, the 契約者貸付 limit and the APL headroom are all derived.

pol_val_base_pp(d)[source]#

V(d) on the premium-paying construction, before any 払済保険 conversion.

Needed by pua_sum_assured(), which values the conversion on the pre-conversion surrender value and would otherwise be circular.

cv_mult(d)[source]#

The 解約払戻金支払割合 applying at anniversary d: k before the step, 1 after it.

k for d < m and 1 for d >= m, and the transition is a step. A surrender occurring in policy year m — period m - 1 — is paid at anniversary m on the full value [std ordering]; the suppressed value applies to anniversaries 1 to m - 1. Always 1 on the ordinary form and from the anniversary the contract is paid up at, and always k on a 終身払 contract, where the suppressed period runs for life. The paid-up test is written on the anniversary rather than through is_paid_up(), which is indexed by the period: the suppression switches off from anniversary pua_year(), the conversion itself being made at pua_year() - 1 on the suppressed value.

cv_base_pp(d)[source]#

CV(d) on the premium-paying construction, before any 払済保険 conversion.

cv_pp(d)[source]#

CV(d): the 解約返戻金 actually payable at anniversary d, per policy.

cv_mult(d) V(d). Everything derived from the surrender value is suppressed with it — the 払済保険金額, the 契約者貸付 limit and the APL headroom are all computed off this number rather than off V.

pol_val_at_m(u)[source]#

V at elapsed month u: the ordinary surrender value between anniversaries [std].

V(d) at every anniversary — u = 12 d reproduces pol_val_pp() exactly — and linear in the elapsed months between two anniversaries:

V(u) = (1 - f) V(d) + f V(d + 1),   d = u // 12,  f = (u mod 12) / 12

The within-year rule is the one thing the monthly grid needs that the annual grid did not, and it is a [std]: the 算出方法書 that would state it is a 基礎書類 filed with the 金融庁 and is not published, so no source settles whether a real carrier grades its 解約返戻金 linearly in elapsed months, on a 経過月数 table of its own, or on the retrospective value. Linear interpolation is the market’s ordinary convention for a value quoted by policy year and is the least assuming of the three.

What it deliberately does not touch is the calibration. i_cv was derived by fitting this construction to one carrier’s complete published surrender-value run, which is an annual table; the anniversary values are unchanged here, so the fit is the same fit and the interpolation adds a convention rather than moving a number.

cv_mult_at_m(u)[source]#

The 解約払戻金支払割合 applying at elapsed month u: k before 払込満了, 1 from it.

The monthly statement of cv_mult(), and it is where the monthly grid changes an answer rather than merely refining one. The annual grid had to rule that a surrender anywhere in policy year m was paid at anniversary m on the full value — a [std ordering] forced by the step and the grid landing on the same year. Here the suppression ends at the month the contract ends it, u = 12 m: a surrender at elapsed month 12m - 1 is inside the 保険料払込期間 and is paid k V, and one at 12 m is not and is paid V. Eleven months of policy year m move from the post-step to the pre-step side, and on the anchor cell that is the largest single difference between the two grids.

cv_at_m(u)[source]#

CV at elapsed month u: the 解約返戻金 actually payable, per policy.

cv_mult_at_m(u) pol_val_at_m(u). This is what a surrender in month t is paid, read at u = t + 1 because the surrender falls at the end of the month. It agrees with cv_pp() at every anniversary except inside the 保険料払込期間’s last year, where the two disagree by design — see cv_mult_at_m().

cv_susp_at_m(u)[source]#

k V at elapsed month u: the suppressed value between anniversaries.

The monthly companion of cv_pp_susp(), and the value a clawed-back APL cohort is settled on when it surrenders between anniversaries.

cv_pp_susp(d)[source]#

k V(d): the suppressed value at every anniversary, step or no step.

Two things at once, and the notes need both. It is the value an instant before the step at d = m — the published pre-step figure — against which cv_pp() an instant after must stand in the exact ratio 1 / k. And it is the value a clawed-back APL cohort keeps for life, because a cohort carried through the low period by unrepaid advances has not paid the low-period premiums and the suppressed basis therefore continues to apply after the period ends.

reserve_pp(d)[source]#

The 平準純保険料式 policy reserve at anniversary d — a reference quantity only.

Accumulated net level premium with no Zillmer adjustment, on i_std and the same table, which is what 平成8年大蔵省告示第48号 prescribes for a level-premium 終身保険 with a fixed 予定利率. It never produces a cash flow. It exists so that reserve_pp - pol_val_pp = surr_charge_pp can be asserted, and that identity holds only because i_std defaults to i_cv; reserve_pp >= pol_val_pp >= cv_pp is not an invariant and is not asserted anywhere.

loan_cap_rate(d)[source]#

The contractual 契約者貸付 limit at anniversary d: 9/10 while paying, 8/10 once 払込済.

Stated identically at three carriers, with the existing balance deducted first. It binds pol_loan_util() whatever that is set to. Indexed by the anniversary, like the loan balance and the value it is a fraction of: a 契約者貸付 is drawn at an anniversary and the 約款 compounds it once a year.

pol_loan_year()[source]#

The policy year at which the 契約者貸付 is drawn, or 0 for no drawdown.

A model point column rather than a fixed Reference, because when the loan is taken decides whether the contract survives it: a small early draw is outgrown by the value, while a draw of the contractual maximum late in the run compounds at i_loan against a value growing at i_cv and reaches the loan-excess termination.

pol_loan_draw(d)[source]#

The 契約者貸付 drawn at anniversary d; zero in the base run.

A single drawdown at the anniversary opening policy year pol_loan_year()d = pol_loan_year() - 1 [std] — of the elected fraction of the value there, capped by loan_cap_rate(). There is no public take-up data of any kind, so both the timing and the level are standardizations; a revolving facility would be another input table.

loan_pp(d)[source]#

L(d): the 契約者貸付 principal and interest of the paying cohort at anniversary d.

L(d + 1) = (L(d) + draw(d)) (1 + i_L), compound, with interest capitalised into principal, and L(0) = 0. Identically zero in the base run, where every benefit is therefore gross.

It stays an annual quantity on the monthly grid, and that is the contract’s own convention, not an approximation. The 約款 states the loan rate as a 年利 and capitalises it at the 年単位の契約応当日, so the balance genuinely does not move between anniversaries. A benefit falling in month t is settled net of loan_pp read at duration(t), the anniversary that opened the policy year — which is the balance actually outstanding.

loan_fail_year()[source]#

The anniversary d at which the loan outgrows the value, or proj_years().

The 約款’s loan-excess termination: where loan and interest exceed the surrender value the insurer notifies for a top-up and, unpaid, the contract lapses. The balance at anniversary d is tested against the value at that same instant — the amount actually available to settle it — and the notice-and-top-up period is not modelled [std]. proj_years(), one past the last anniversary, is the never-reached sentinel; a zero balance cannot exceed a non-negative value, so the base run never reaches it. The termination takes effect in the month 12 d, which is loan_fail_month().

The test stays annual because both sides of it are: the balance moves once a year and the notice it triggers is served at the anniversary.

loan_fail_month()[source]#

The policy month the loan-excess termination takes effect in, 12 loan_fail_year().

proj_len() where it never happens, so that a comparison against t is safe over the whole frame.

apl_advance_due(d)[source]#

A(d): the premium the APL would advance at anniversary d, zero once none is due.

Once d + 1 > prem_end() no premium is due, so the balance rolls up on interest alone against a value that is still growing — which is why exhaustion after 払込満了 takes decades rather than years. Indexed by the anniversary the premium falls at, because an annual premium falls at an anniversary and nowhere else.

apl_test_val(d)[source]#

CV*(d): the surrender value the APL continuation test is run against, at anniversary d.

The value computed as if the premium had been paid: the test made at anniversary d reads apl_test_val(d + 1), the value at the anniversary the advanced premium would carry the contract to [std]. With the clawback on — the correct treatment, since a cohort carried by advances has not paid its low-period premiums — that is the suppressed value at every duration; with it off the value steps up at m like any other. Running the test on V instead of on k V overstates the headroom by more than a decade of in force.

apl_test_val_m(u)[source]#

CV* at elapsed month u: the same quantity between anniversaries.

What an APL cohort surrendering mid-year is settled on. It is the test value and not cv_at_m() because the clawback applies to the settlement for the same reason it applies to the test: a cohort carried through the low period by unrepaid advances has not paid those premiums, so the suppressed basis continues to apply to it.

apl_fires(d, s)[source]#

Whether the APL continuation test passes at anniversary d for the cohort entering at s.

CV*(d + 1) >= L(d, s) + P (1 + i_L) while a premium is due, and CV*(d + 1) >= L(d, s) once none is — the value at the next anniversary against the balance at this one. Stated the same way at three carriers. In the first policy year the value cannot carry a premium on either form, so a default at s = 0 terminates at once.

Both indices are anniversaries, and they stay anniversaries on the monthly grid. An APL advance settles a premium, a premium falls once a year, and the test is what the insurer runs when it does; there is no monthly version of the question. s is accordingly the policy year the cohort defaulted in — the 0-based anniversary d = s, month 12 s — and not the month.

loan_apl_pp(d, s)[source]#

L(d, s): the APL balance at anniversary d of the cohort entering at anniversary s.

L(d + 1, s) = (L(d, s) + A(d)) (1 + i_L), with the advance made only where the test fired. Indexed by the entry anniversary and not collapsed to a cohort average: the APL exhausts at a duration that depends on when the loan started, so an average balance would let early entrants ride on late entrants’ headroom and would move the termination by decades.

Annual like loan_pp() and for the same contractual reason — 年利, capitalised at the 契約応当日 — so a benefit in month t is settled net of loan_apl_pp read at duration(t).

apl_fail_year(s)[source]#

The anniversary d at which the APL cohort entering at anniversary s exhausts.

proj_years() where it never does, one past the last anniversary. The cohort leaves at the start of the policy year that anniversary opens — the month apl_fail_month() — and the policyholder may claim the surrender value net of the loan, floored at zero because the loan can exceed the value.

apl_fail_month(s)[source]#

The policy month the APL cohort entering at anniversary s terminates in.

12 apl_fail_year(s), or proj_len() where the cohort never exhausts, so that a comparison against t is safe over the whole frame.

apl_advances(s)[source]#

The number of premium advances the APL makes for the cohort entering at anniversary s.

The single most instructive number the module produces: on the anchor cell a default at s = 1 — policy year 2 — buys one advance on the suppressed form and thirteen on the ordinary one, from the same default at the same duration on the same underlying policy value.

pols_default(t)[source]#

Policies moving out of the paying cohort into the APL state at the start of month t.

pols_if_pay(t) u(t), and non-zero only in a premium due month, because default_rate() is. Zero in the base run, and zero in the month a loan-excess termination takes the whole paying cohort.

pols_pay_bef_decr(t)[source]#

The paying cohort exposed to the month-t decrements, after defaults and loan exit.

pols_if_pay(t)[source]#

The premium-paying cohort in force at the start of policy month t.

pols_if_pay(0) = 1 and pols_if_pay(t + 1) = pols_pay_bef_decr(t)(1 - q_m)(1 - w_m)(1 - s), the monthly decrements plus the one-off cliff spike in the month it fires. Equal to pols_if() in the base run, where no policy ever enters the APL state.

pols_apl_in(t, s)[source]#

The APL cohort entering at anniversary s, carried into month t before its test.

pols_default(12 s) in the entry month, then decremented monthly by mortality and voluntary surrender like any other in-force policy, and zero from the month after the cohort exhausts. The cohort index s is the entry anniversary and t the month: the population moves every month, the loan and its test move once a year.

pols_if_apl(t, s)[source]#

The APL cohort of entry anniversary s exposed to the month-t decrements.

The carried amount, or zero in and after the month the cohort exhausts: an exhausted cohort leaves at the start of that month and does not experience its deaths or surrenders.

pols_apl_exit_at(t, s)[source]#

The APL cohort of entry anniversary s terminating at the start of month t.

apl_entry_years(t)[source]#

The entry anniversaries of every APL cohort that can be in force in month t.

0 min(duration(t), prem_end() - 1): no cohort can enter before the first anniversary, and none after the last anniversary a premium is due, prem_end() - 1. Empty where apl_active() is False, which is exact — no cohort can be non-empty there — and keeps eight of the ten model points from summing over an entry list twelve times longer than the annual grid’s.

pols_apl_carried(t)[source]#

The APL cohorts carried into month t from an earlier entry anniversary.

Kept apart from the entrants of month t, which are still inside pols_if_pay() at the start of the month and would otherwise be counted twice. A cohort entering at anniversary s enters in month 12 s, so the cohorts carried in are those with 12 s < t.

pols_apl(t)[source]#

The APL cohorts exposed to the month-t decrements, summed over entry anniversaries.

pols_apl_exit(t)[source]#

Policies terminating at the start of month t because the APL exhausted.

pols_loan_exit(t)[source]#

Policies terminating at the start of month t on loan-excess; zero in the base run.

pols_if(t)[source]#

l(t): the number of policies in force at the start of policy month t.

The premium-paying cohort plus every APL cohort carried in from an earlier month. This is the weight on every cash flow of the same result_cf() row. It is 1 in the first month, t = 0, on a single-policy model point and 0 at proj_len(), one past the frame, because the table terminates and every remaining life dies in the final month.

pols_if_at(t, timing)[source]#

The number of policies in force at a point inside policy month t.

"BEF_DECR"

l(t), the start of the month, before anything happens; the same number as pols_if() and the weight on that month’s cash flows.

"BEF_LAPSE"

after the APL and loan-excess terminations and after deaths, before surrenders — the notes’ processing order is death before lapse [std order], so this is the population surrenders are taken from.

"BEF_SPIKE"

after ordinary surrender, before the one-off cliff surge. Equal to "AFT_DECR" in every month but the one 払込満了 falls in.

"AFT_DECR"

l(t+1), the end-of-month state, and zero at proj_len() - 1 because the table’s terminal rate is 1 and nobody survives the final month.

pols_death(t)[source]#

D(t): expected death and 高度障害 claims in month t, at the end of the month.

One decrement covering both benefits at one amount: the shipped table already includes 高度障害 inside the death rate, so adding a separate disability decrement would double-count. The リビング・ニーズ rider is an acceleration that reduces the sum assured by what it pays, so it is not an addition either and its incidence is zero in the base run [std].

pols_lapse_base(t)[source]#

The ordinary voluntary surrenders at the end of month t, before the cliff surge.

Taken from the survivors of mortality — death before lapse [std order].

pols_lapse_spike(t)[source]#

The cliff surge: surrenders taken at 払込満了 by owners who waited for the step.

Non-zero in one month of the whole projection, and zero on every contract that has no 払込満了. It is published beside pols_lapse_base() rather than folded into it because it is the thing the product is about, and on the annual grid it could not be seen apart from a year of ordinary surrender.

pols_lapse(t)[source]#

S(t): total expected voluntary surrenders at the end of month t.

Ordinary surrenders plus the cliff surge, both paid on the surrender value at the end of the month — cv_at_m(t + 1) — net of any loan. The surge falls in the month after the last premium, which is where the value steps up, so it is paid on the post-step value while the eleven months before it are paid on the suppressed one.

premiums(t)[source]#

Premium income at the start of policy month t, an inflow.

The premium is annual (年払), so it falls in one month out of twelve — the anniversary months t = 0, 12, 24, — and is zero in the other eleven. That is the single most visible change the monthly grid makes to this product’s statement: the stream is a sawtooth of one large inflow a year against maintenance expense every month, which is what a 年払 contract actually looks like and what the annual grid could not show.

Carried on pols_pay_bef_decr(), never on the APL cohorts: an APL advance is not cash income. No cash reaches the insurer, a loan asset is created instead, and booking the advanced premium as income while also netting the loan off the later claim would count it twice. net_cf is unchanged by an advance in the month it is made. Zero once policy_year(t) > prem_end(); nothing else about the contract stops there.

claims(t, kind=None)[source]#

Benefit outgo in period t, by kind; the total when kind is omitted.

"DEATH"

the 死亡保険金 / 高度障害保険金 paid at the end of the period of death, (SA - L) D(t) floored at zero, cohort by cohort because each APL cohort carries its own balance.

"LAPSE"

the 解約返戻金 paid on voluntary surrender, (CV(t + 1) - L) S(t) floored at zero — the value at the end of the month, interpolated between anniversaries by cv_at_m()plus the residual value paid where an APL cohort exhausts or a loan outgrows the value, which is settled at the start of the month it happens in, on the anniversary that opens it, net of the balance that broke the test. Both the ordinary surrenders and the 払込満了 cliff surge are in this line and both are paid the same way.

Every one of these is floored at zero: a loan can outgrow both the surrender value and, given long enough, the sum assured, and none of them may produce a negative payment.

claim_expenses(t)[source]#

ec D(t): the claim handling expense on the month’s death claims [std].

¥20,000 per claim, uninflated. No carrier publishes an expense basis of any kind — the 予定事業費率 is named in the 保険契約者保護機構 boilerplate and never quantified — so every expense level in this model is a standardization. Published as its own claim_expenses column in result_cf() and deducted explicitly in net_cf(); it is not inside expenses().

inflation_factor(t)[source]#

The expense inflation factor in month t: (1 + pi)^(y(t) - 1), 1 in year 1 [std].

Annual steps inside the monthly grid: maintenance inflates once a policy year, at the anniversary, not once a month. A 1.0% p.a. assumption is an annual observation and compounding it monthly would assert a within-year expense profile no source supports.

1.0% p.a. is deliberately below the 3% a UK or U.S. model would carry: over an eighty-year whole-life horizon 1% compounds to 2.19 and 3% to 10.33, so importing a Western inflation assumption here produces a different product rather than a stressed one. There is no published Japanese expense basis to anchor either figure.

expenses(t)[source]#

E0 and e_m(t) in month t: acquisition and maintenance only [std].

¥50,000 per policy at issue — the acquisition charge falls in the first row of the frame — then ¥8,000 per policy per year taken as 8,000 / 12 a month and inflating at 1% a year, both at the start of the month. The claim handling expense is not here: it is claim_expenses(), deducted separately in net_cf() and published in its own result_cf() column, which is how the notes’ worked-example table prints it too. Maintenance continues for life, not to 払込満了: that is the structural point of this product, a contract on which premiums stop after m years and obligations do not — and on the monthly grid that point is visible every month rather than once a year. There is no separate surrender expense; it is folded into maintenance [std].

commissions(t)[source]#

Commission outgo in policy month t [std].

90% of the annual premium at issue, then 3% of premium income in policy years 2 to prem_end(). Both levels are standardizations; no Japanese carrier publishes a commission scale. Renewal commission follows the premium actually collected in cash, so it falls in the same anniversary month the premium does and is zero in the eleven months between; an APL cohort produces none [std]; and none is paid after 払込満了 — a projection that keeps charging it there is charging commission on a premium nobody pays.

dividends(t)[source]#

The 5年ごと利差配当 declared at the end of every fifth policy year [std]; 0 in base.

Fires in the last month of every fifth policy year — t = 59, 119, 179, — and is declared on the policy value at the anniversary that closes it, d = policy_year(t). div_spread times div_period years of that value, on the policies surviving mortality. A declaration is an event at a date, so it falls in one month and is not spread; the annual grid put it in a year, which was the same thing said less precisely. The composite is 無配当 and this column is zero on every model point but one. The declaration basis is a 三利源 calculation inside the unpublished 算出方法書 and no carrier publishes it, so both the spread and the once-in-five-years timing are standardizations — the timing is the only part of it that is sourced, from the product name itself.

net_cf(t)[source]#

CF(t): the net cash flow of policy month t, income positive.

Premiums less death and 高度障害 claims, surrender benefits, claim_expenses(), maintenance and acquisition expense, commission and any dividend. The notes’ own sign, which is also the library-wide convention, so there is no outgo-positive liability_cf companion to publish.

The shape to expect is a deep new business strain in the first month, then a sawtooth while the premium runs — one large inflow at each anniversary against maintenance and claims every month — then a single violent negative month at 払込満了 where the surrender value steps up by 1 / k and the surrender surge lands on it, and finally a run-off of claims and expenses against no premium at all. The cliff is the largest single feature of this stream, and on this grid it is one month wide rather than one year. That is the clearest thing the monthly step buys on this product: the annual grid could say the cliff cost a year and could not say what a month of it looked like.

check_pols_roll_fwd_resid(t)[source]#

The in-force roll-forward residual in policy month t; zero everywhere.

l(t) - l(t+1) less deaths, surrenders, APL exhaustions and loan-excess terminations. The last two are zero in the base run and are what makes the identity close when the modules are on: a policy that leaves because its loan outgrew its value has left for a reason that is neither a death nor a surrender.

check_pols_roll_fwd()[source]#

True when the in-force roll-forward closes in every projected month.

The library-wide form of a roll-forward check: no argument, one bool over all t, so one test can call it across every model. check_pols_roll_fwd_resid() gives the signed residual of the month that failed.

pols_exit_cum(t)[source]#

Every exit of every kind from t = 0 to month t inclusive, per policy issued.

A running total, defined recursively rather than re-summed at each t. On the annual grid check_decrement_sum_resid() re-added the whole history on every row, which cost 80 squared additions over a run; twelve times as many rows makes that 144 times as much work, so the cumulative total is carried instead. The quantity is the same one.

check_decrement_sum_resid(t)[source]#

The cumulative-decrement residual at month t; zero everywhere.

l(0) less every exit up to and including month t less l(t+1). At t = T - 1 it is the notes’ statement that the decrements sum to 1: because the table terminates, every policy leaves by one of them and l(T) = 0, so there is no residual population and no tail state anywhere in this model.

check_decrement_sum()[source]#

True when every policy issued leaves by a modelled decrement, in every month.

check_pol_val_roll_fwd_resid(d)[source]#

The policy-value recursion residual across the policy year opening at anniversary d.

(W(d) + pi 1{premium due}) (1 + i_cv) - [q SA + (1 - q) W(d+1)] on the table rate — the roll from one anniversary to the next. It is the retrospective form of the same prospective value and is what catches a mis-set prem_period or a discount factor applied on the wrong side. It is defined as zero for the year that rolls into the 払済保険 conversion anniversary pua_year() - 1, i.e. at d = pua_year() - 2, where the value is re-based by the election rather than rolled forward.

Annual, and it must stay annual. The policy value is constructed from annual actuarial functions on an annual basis and is defined at anniversaries; rolling it monthly would be checking an interpolation convention rather than the construction. The monthly reading of the same value is pol_val_at_m(), which agrees with this one at every anniversary by definition.

check_pol_val_roll_fwd()[source]#

True when the policy value rolls forward on its own basis in every policy year.

check_reserve_identity_resid(d)[source]#

The 責任準備金-to-解約返戻金 residual at anniversary d; zero everywhere.

reserve_pp(d) - pol_val_pp(d) - SC(d), with the deduction floored at the reserve itself because the surrender value cannot go below zero. The whole difference between the two quantities is the 解約控除, which is precisely what 平準純保険料式 forbids the reserve to carry. Zero by definition when the two basis rates differ: the identity is a consequence of i_std = i_cv and is not asserted otherwise, because with a 標準利率 below the pricing basis the reserve exceeds the cash value by far more than the 解約控除.

check_reserve_identity()[source]#

True when the reserve exceeds the surrender value by exactly the 解約控除.

Swept over every anniversary of the run, d = 0 proj_years(), issue and horizon included: this is a statement about a value at a point in time, not about a period.

check_loan_roll_fwd_resid(d)[source]#

The loan roll-forward residual across the policy year opening at anniversary d.

The 契約者貸付 balance and every APL cohort balance, each rolled L(d + 1) = (L(d) + advance) (1 + i_L) and compared with the balance the model actually carries. Identically zero in the base run, where there is no loan at all; non-trivial the moment either module is switched on, which is the point of it.

Annual, like the balances themselves: the 約款 states a 年利 and capitalises it at the 契約応当日, so there is nothing to roll between anniversaries.

check_loan_roll_fwd()[source]#

True when every loan balance accumulates at i_loan in every policy year.

Stops one year short of the end because the residual reads loan_pp(d + 1).

check_net_cf_resid(t)[source]#

The published cash-flow statement’s residual in policy month t; zero everywhere.

net_cf() less the published result_cf() columns of the same row. It closes the loop between the total benefit outgo and the two kinds that make it up, so a third kind added to claims() and left out of its total shows up here rather than silently vanishing from the statement.

check_net_cf()[source]#

True when the net cash flow equals the sum of its published columns, every month.

result_cf()[source]#

Result table of cash flows, indexed by the 0-based policy month t.

The frame runs t = 0 proj_len() - 1, twelve rows to the policy year, and df.groupby(df.index // 12).sum() reads it back as the annual statement. pols_if is the start-of-month count, which is the weight applied to every cash flow on the same row. net_cf carries the notes’ own income-positive sign. expenses is acquisition and maintenance; the claim handling expense is beside it in claim_expenses, as it is in every model in the three libraries. dividends is a column of zeros on the 無配当 composite and is published rather than dropped, because the participating variant is a real product in the source set.

result_pols()[source]#

Result table of policy counts and decrement rates, indexed by the policy month t.

Both the annual rates and the monthly decrements are published: mort_rate and lapse_rate are the annual rates the assumption tables are stated on and the notes quote, mort_rate_mth and lapse_rate_mth the rates actually applied to the month, and lapse_spike_rate the one-off cliff surge, which is neither — it is non-zero in exactly one row of the whole table.

result_val()[source]#

Result table of the policy value, the surrender value and the reserve, by anniversary d.

Indexed by the anniversary, not by the month, because that is what these quantities are: the contractual value construction is annual, defined at the 年単位の契約応当日, and it did not move when the cash flow statement went monthly. The frame is d = 0 proj_years(), issue and horizon included.

cv_pp is the amount payable at the anniversary and cv_pp_susp the suppressed value at every anniversary, so the step at 払込満了 and the value an instant before it read off the same table. reserve_pp is a reference quantity and produces no cash flow. The value a surrender between anniversaries is paid on is cv_at_m(), which interpolates these columns.