The Projection Space#

The by-policy projection of the LTC_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 counts policy months, 0-based: t = 0 is the first policy month and t = proj_len() - 1 the last. Cover is whole of life, so the last month is the last month of the mortality table’s terminal age — 116 for males, 118 for females — and proj_len() = 12 * (omega_age() - issue_age() + 1). There is no maturity and no maturity benefit; what ends the projection is the table, not the contract.

Input data

Inputs are external files: plain CSVs living in the model folder’s parent directory, products/nursing_care/, 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 through modelx’s IOSpec machinery.

The consequence worth knowing: the model is not portable on its own. Copying the LTC_JP_S folder without its parent’s CSVs produces a model that reads and then fails on first evaluation.

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

prevalence_file

data.prevalence_table()

prevalence_table.csv

grade_share_file

data.grade_share_table()

grade_share_table.csv

Naming

Cells names follow lifelib’s basiclife.BasicTerm_S wherever that model has an analogue — pols_* for policy counts, plural nouns for cash flows, *_rate for annual rates with *_rate_mth for their monthly counterparts, *_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. The technical notes use compact actuarial symbols instead. The mapping is:

Notes symbol

Cells

Meaning

t

(the cells argument)

Policy month, 0-based

x

issue_age()

Issue age, 満年齢

age(t)

age(t)

Attained age, x + floor(t/12)

y(t)

policy_year(t)

Policy year, floor(t/12) + 1

(none)

omega_age()

Terminal age of the table

(none)

proj_len()

Number of projected months

(none)

model_point()

The selected model point row

A_L

lump_amount()

介護一時金額

A_N

annuity_amount()

基準介護年金額 per instalment

n_A

annuity_max()

Maximum annuity instalments

G_L, G_N, G_W

grade_lump(), grade_annuity(), grade_waiver()

Benefit and waiver thresholds

s_W, s_L, s_N

grade_share(grade)

Grade shares of the certified

prev(x)

prev_rate(t)

All-grade prevalence

prev’(x)

prev_slope(t)

Its derivative in age

prev_G(x)

prev_grade(t, grade)

Grade-G prevalence

beta, x_mid, prev_ceil

prev_param(name)

Logistic parameters

k

care_mort_mult

Care-state mortality multiple

f_age(x)

f_age(t)

Sub-65 特定疾病 gate

i_W, i_L, i_N

inc_rate_w(t), inc_rate_l(t), inc_rate_n(t)

Annual entry rates

i_W_m, i_L_m, i_N_m

inc_rate_w_mth(t), and so on

Monthly entry rates

(table)

mort_rate_base(t)

Table rate before mort_be_factor

(none)

mort_rate(t)

Best-estimate annual mortality

q_H(t)

mort_rate_mth(t)

Monthly healthy mortality

(none)

mort_rate_care(t)

Annual care-state mortality

q_C(t)

mort_rate_care_mth(t)

Monthly care-state mortality

(table)

lapse_rate(t)

Annual lapse rate

w(t)

lapse_rate_mth(t)

Monthly lapse rate

w_cum(t)

lapse_cum(t)

Cumulative lapse proportion

lam, w_ref

sel_lapse_lambda(), sel_lapse_ref

Anti-selective lapse module

rec_rate

rec_rate(), rec_rate_mth()

Recovery out of the care state

act(t)

pols_act(t)

Active, premium-paying lives

care_w(t)

care_w(t)

Entered G_W: waiver running

care_l(t)

care_l(t)

Entered G_L: lump sum paid

care_n(t)

care_n(t)

Entered G_N: annuity running

pols_if(t)

pols_if(t)

act(t) + care_w(t)

(none)

pols_if_at(t, timing)

BEF_DECR, BEF_LAPSE, AFT_DECR

n_W, n_L, n_N

pols_entry_w(t), and so on

Expected entrants of the month

(none)

pols_death(t)

Deaths of the month

(none)

pols_lapse(t)

Lapses of the month

term(t)

pols_term(t)

Lives extinguished by the cap

S_C(s, t)

care_surv(s, t)

Care-state survival, s to t

ann_count(t)

ann_count(t)

Instalments due in month t

(rider)

pols_entry_dem(t)

認知症一時金特約 first diagnoses

P

premium_mth_pp()

Monthly office premium

P x act(t)

premiums(t)

Premium income

A_L n_L, A_N ann_count

claims(t, kind)

Benefit outgo by kind

ec

claim_expenses(t)

Claim handling expense

e(t), E0

expenses(t)

Maintenance and acquisition

(none)

inflation_factor(t)

Expense inflation factor

c0

comm_init_pp()

Initial commission per policy

c_r

comm_renewal_rate

Renewal commission rate

c0, c_r x premiums

commissions(t)

Commission outgo

net_cf(t)

net_cf(t)

Net cash flow, income positive

Three names needed care.

The notes write act(t) for the active population. It is spelled pols_act() here, because act next to care_w reads as an abbreviation of “actual” rather than as a policy count, and because every other policy-count cells in the library starts pols_. The three care ledgers keep the notes’ own names, since care_w, care_l and care_n are already the right shape.

The notes use i_G for both the annual entry rate and, with an _m subscript, the monthly one. The library convention is that a bare *_rate is annual and *_rate_mth is monthly, so inc_rate_l() is the annual rate and inc_rate_l_mth() the monthly one, matching mort_rate / mort_rate_mth and lapse_rate / lapse_rate_mth exactly.

term(t) is spelled pols_term(). It is a policy count, not a term of the contract, and the bare word in a life model reads as the policy term — which this product does not have, being whole of life.

The three-state chain, and why the ledgers are nested rather than disjoint

Healthy, in care, dead, with the care state absorbing in the base run. The three care ledgers are cumulative first-entry counters riding on one survival ledger, not three disjoint compartments:

care_n(t) <= care_l(t) <= care_w(t) <= pols_if(t) at every t

so they must never be added together. check_nesting() asserts the ordering. pols_entry_w() is drawn from pols_act() alone, because a life already certified at G_W cannot enter it again; pols_entry_l() and pols_entry_n() are drawn from everyone in force who has not yet reached that grade, which includes lives already in a lower care grade, because progression up the ladder is the dominant route into the higher grades rather than direct entry from health.

Only care_w() is a component of pols_if(). pols_if(t) = pols_act(t) + care_w(t) is the definition, and check_pols_roll_fwd() closes it against the month’s decrements: deaths of the active population at q_H, deaths of the care population at q_C, lapses of the active population only, and the benefit-driven termination.

Premium rides on pols_act, and lapse applies to pols_act

Two of the notes’ pitfalls, and they are the same fact seen twice. The waiver fires at G_W = 要介護1, one grade below the lump sum and two below the annuity, so there is a real band of lives for whom the contract has stopped collecting premium and has not yet paid anything. Charging premium to the whole in-force block overstates lifetime premium income by about 5.9% on the anchor cell — the 5.5% the waiver takes out of the in-force-weighted total, read against the smaller correct base. And with the premium waived and no 解約返戻金 to surrender for, a life on waiver has nothing to lapse: applying lapse to pols_if() rather than to pols_act() destroys the annuity liability it took thirty years to build. The whole_life 自動振替貸付 machinery must not be inherited here — there is no surrender value to lend against, so a missed premium lapses the contract outright.

認定率 is a prevalence, and the conversion has two terms

What the government publishes is a point-in-time count of certified persons, not a flow of new certifications. Multiplying it — or its 要介護2以上 share — by a benefit amount as if it were an annual claim frequency is the single commonest error in a Japanese nursing-care model. In an illness-death model with no recovery the conversion is an identity rather than an approximation:

i_G(x) = prev_G’(x) / (1 - prev_G(x)) + prev_G(x) (mu_C(x) - mu_H(x))

and the second term is not a refinement. A rising prevalence understates incidence because the certified population is simultaneously being drained by its own excess mortality. Dropping it — which is what happens if the care-state mortality multiple is set to 1 “because there is no impaired-life table” — cuts lifetime lump-sum claims on the anchor cell by about 31%. inc_rate() carries both terms and prev_slope() is the analytic derivative of the logistic, not a difference quotient.

The dimensional check that catches the error: prev and prev_G are dimensionless proportions of a population, beta carries units of 1/year, and both terms of the identity are therefore rates per year and can be added. A version of the formula that adds a prevalence to a rate is the commonest way to get this wrong.

The step in incidence at exactly age 65 belongs there

Below 65 the public limb fires only where the care state arises from one of the 16 特定疾病, and the company-basis limb that partly fills the hole is restricted to lives 満65歳未満. f_age() is the resulting gate: 0.20 below 65 with the company-basis limb on, 0.05 with it off, 1.00 at 65 and over. Entry into 要介護2以上 jumps about 6.1x between age 64 and age 65 on the shipped basis. A smooth curve through 65 misprices every issue age in the lower half of the 40-79 issue range, which is most of it.

The annuity ledger, in advance, capped, and computed as a partial product

Instalments fall on the annual anniversaries of the 介護年金支払基準日, so the cohort entering in month s is paid in months s, s+12, ..., s+12(n_A - 1) while it survives. The j = 0 term of ann_count() is pols_entry_n() itself: payment in advance, on the entry date. Deferring the first instalment by a year removes roughly a tenth of the annuity liability and misdates all of it.

care_surv() is computed as a partial product over the months from s to t, never as a ratio of cumulative products: the care-state mortality rate reaches 1 at the terminal age, so a cumulative product underflows to zero and the ratio form divides by zero exactly where the tail of this liability lives.

The cap binds, unlike every limit on the medical chassis: on the anchor cell entrants take about 4.6 instalments on average and about 15% of them reach the tenth. pols_term() is the cohort taking its last permitted instalment; it is removed from care_n, care_l, care_w and hence from pols_if, which is the retroactive extinction of the contract expressed on a monthly grid.

Modules that are off in the base run

Four of the notes’ optional constructions are implemented and switched off on the anchor cell, so that the base run reproduces the worked example while the machinery stays visible and testable. Each is exercised by a shipped model point.

  • The state-tested annuity and its recovery decrement. Under annuity_test = "state" an instalment additionally requires the care state to persist, so the annuity cohort carries (1 - rec_rate_mth()) alongside (1 - q_C) and care_n() loses recoveries — which lets a recovered life re-enter and start again from instalment 1 on a new 介護年金支払基準日, because pols_entry_n() draws from pols_if - care_n. The switch is a no-op unless ``rec_rate`` is moved off zero, which is why the two must be tested together; model point 5 carries the switch and the notes’ suggested 5% p.a. placeholder together. Recovery is deliberately scoped to the annuity: the lump sum, once paid, cannot be unpaid, and the waiver ledger is left alone [std scope]. The known limit of that scoping: rec_rate is the rate of falling below G_N = 要介護3, not of returning to health, so a recovered life keeps its 保険料払込免除 for the rest of the contract and never resumes premium. For the modelled step that is right, G_W = 要介護1 being two grades lower; recovery below G_W is not modelled at all, because no source publishes a between-grade transition matrix. Premium income under that switch is a lower bound. See rec_rate().

  • Anti-selective lapse. inc_eff = inc_rate x [1 + lam max(0, w_cum - w_ref)] with lam = 0 on every point but 8. Healthy lives lapse first, so the persisting block is progressively impaired on the incidence basis rather than on mortality — which is the opposite direction from a death-benefit product, and the reason the loading sits on inc_rate_mth().

  • The 認知症一時金特約. dementia_rider is false on every point but 6. There is no published dementia incidence basis in any retrieved source, so the rider’s incidence is a [std] placeholder: dementia_share of the entry rate into the lump-sum grade, after a dementia_wait_mths 認知症診断責任開始期. The MCI limb and the dementia limb are both once-only and the composite pays both to any life reaching dementia, so they are carried as one event at the dementia date paying (1 + mci_fraction) x dementia_amount [std] — which gets the amount right and dates the 10% MCI limb late.

  • The 1-year 不担保期間 of the simplified-underwriting design, waiting_1y, true only on point 7. A state arising inside the 不担保期間 is excluded for good rather than deferred, so the waiting period zeroes the entry rates rather than the claims.

Note what the waiting period is not. “180日” names two different mechanisms in this market and a model must not implement one of them twice: a 不担保期間 or a 認知症診断責任開始期 means cover has not started, while the 180-day (90-day for dementia) test inside the company-basis trigger means the care state must have persisted. The composite has the second and not the first on the care benefits, and the composite’s claim date is the month the trigger is met, not the month it is notified — a certification takes effect retroactively to the application date, so a notification-dated projection is up to a month late.

Sign convention, and the zeros that are product facts

The notes’ net_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 outgo-positive liability_cf companion to publish: one stream, one sign, one name.

claims(t, "LAPSE") exists and returns zero, and result_cf() carries the zero column, because there is no 解約返戻金 at any duration and the notes list a non-zero lapse row as a pitfall imported from products that have one. A column of zeros states the product fact where a missing column would only hide it. There is deliberately no claims_death and no cv_pp: the contract pays nothing on death and has no surrender value, and inventing either would misstate the liability in a direction the notes name.

Cells Descriptions#

model_point()[source]#

The selected model point as a Series.

policy_id()[source]#

The policy identifier of the selected model point.

issue_age()[source]#

x: the 契約年齢, the attained age at the 契約日 with the fraction discarded.

満年齢 (man-nenrei), incremented at each 年単位の契約応当日, which is the basis every carrier in the composite states [S1]. The shipped table is built for a 保険年齢方式 (nearest-birthday) basis, so reading it at 満年齢 understates the valuation age by about half a year; the base run accepts the offset [std], exactly as the third-sector chassis does.

sex()[source]#

The sex (M / F) of the insured, a rating factor and a mortality table key.

lump_amount()[source]#

A_L: the 介護一時金額, paid once per contract on first entry into grade_lump.

Paying it does not terminate the contract [S1] [S4] [S7] [S12].

annuity_amount()[source]#

A_N: the 基準介護年金額, one annual 介護年金 instalment [S1] [S7] [S8] [S10].

grade_lump()[source]#

G_L: the certification grade at or above which the lump sum is paid.

要介護2以上 on the composite, the modal single threshold across the seven carriers and the one whose public base rate is best evidenced [std].

grade_annuity()[source]#

G_N: the certification grade at or above which the 介護年金 starts.

要介護3以上 on the composite, one grade above the lump sum, which is the tiering three carriers use [std].

grade_waiver()[source]#

G_W: the certification grade at or above which 保険料払込免除 starts.

要介護1以上 on the composite — the lowest observed threshold, and strictly below both benefit thresholds [S1] [S8] [std]. That ordering is the product fact the model has to get right: it creates a band of lives paying nothing and receiving nothing.

annuity_max()[source]#

n_A: the maximum number of 介護年金 instalments before the contract is extinguished.

Ten on the composite: simultaneously one carrier’s hard cap [S1] and one of another’s published terms [S7], so the cap is evidenced from both sides [std].

annuity_test()[source]#

The annuity metering basis: survival or state.

survival

each instalment needs only that the insured be alive on the payment date, and recovery does not stop it — four carriers against one [S4] [S7] [S10] [S12], which is what the composite takes [std].

state

the instalment additionally requires the care state to persist, and a life that re-qualifies after a lapse of the state gets a new 介護年金支払基準日 and starts again from instalment 1 [S1] [S2]. This is the only consumer of rec_rate().

company_limb()[source]#

True where the 約款-defined company-basis trigger limb is written [S1] [S2].

A dependency state persisting 180 days (90 where dementia-defined), with the insured 満65歳未満 at diagnosis. It is not modelled as a separate decrement — its only effect here is on f_age(), because it is what partly backfills the sub-65 restriction on the public limb.

dementia_rider()[source]#

True where the 認知症一時金特約 is attached. Off on the anchor cell.

dementia_amount()[source]#

The 認知症診断一時金 amount of the rider, paid once per contract [S4] [S5] [S7].

mci_fraction()[source]#

The 軽度認知障害 (MCI) limb as a fraction of dementia_amount().

10% at both carriers that publish one [S7] [S13] — one of the few genuinely market-wide parameters in this product. See the Space docstring for why the two limbs are carried as one event.

waiting_1y()[source]#

True where the 1-year 不担保期間 of the simplified-underwriting design applies.

Off on the composite, which is fully underwritten [S1] [S7] [S11]; carried as a model point flag because it is the explicit price of three-question simplified underwriting at one carrier [S7].

waiting_mths()[source]#

The 不担保期間 in months: 12 where waiting_1y(), otherwise 0.

A state arising inside the 不担保期間 is excluded for good rather than deferred, so this zeroes the entry rates in inc_rate_mth() rather than the claims [std].

sel_lapse_lambda()[source]#

lam: the anti-selective lapse loading on incidence, zero in the base run.

A model point column rather than a Space Reference, so that one shipped point can exercise the module while the rest of the table stays on the notes’ base basis. No Japanese selective-lapse evidence was retrieved; the level is a [std] placeholder identical to the third-sector chassis’s.

rec_rate()[source]#

The annual rate of falling below the annuity grade G_N; zero in the base run.

Not a recovery-to-health rate. It is applied to care_n() alone, so a life that recovers leaves the annuity ledger and may re-qualify on a new 介護年金支払基準日, but keeps its 保険料払込免除 for the rest of the contract: it stays in care_w(), never re-enters pols_act(), never resumes premium and is never again exposed to lapse.

For the step modelled that is right — G_W = 要介護1 is two grades below G_N = 要介護3, so a 要介護3 -> 要介護2 downgrade stops a state-tested annuity and leaves the waiver running [S1] [S2] [S8]. Recovery below G_W, which would end the waiver and restore the premium, is not modelled: no retrieved source publishes a transition matrix between grades and one rate cannot carry two thresholds, so the model implements the threshold it can evidence and names the other as a gap [std scope]. Under annuity_test = "state" with a non-zero rate, premium income is therefore a lower bound and the waived band an upper bound: pols_act() is bit-identical to the rec_rate = 0 run while care_n() is materially smaller. The only route by which recovery reaches care_w() is the ten-payment cap, which it moves upward — a recovered life takes no tenth instalment, so pols_term() extinguishes fewer contracts.

The care state is absorbing in the base run. That is forced by the sources and it is a real simplification, not a harmless one — the statute provides for the grade to move up or down at 要介護更新認定 [R1] and a carrier’s own FAQ addresses recovery [S3] — so it is carried as a named input set to zero rather than omitted.

Consumed only by the state annuity test: on the composite’s survival-tested annuity a recovery does not stop payment [S7] and a paid lump sum cannot be unpaid [S1], so recovery has nothing to act on. Returning zero on the survival test is what makes that explicit.

rec_rate_mth()[source]#

The monthly recovery rate, 1 - (1 - rec_rate())^(1/12) [std].

premium_mth_pp()[source]#

P: the level monthly office premium per policy, a model point input.

Not a computed quantity. No carrier publishes 予定発生率, 予定利率 or 予定死亡率 for this product, the regulator confirms there is nothing standard to publish for 第三分野 business [R10], and the 算出方法書 is a 基礎書類 filed with the 金融庁 and is not public [REG-R2]. The anchor cell’s ¥11,500 is the rounded sum of two published specimen rates at male 60, 月払, 終身/終身払 [S6] [S8] [std].

prem_mode()[source]#

The 払込回数: monthly on the composite, which is why the grid is monthly [S1].

prem_period_type()[source]#

The 保険料払込期間 as a category: 終身払 (whole of life) on every carrier here.

Named *_type because it returns a category and not a duration: the library-wide prem_period is a number of the model’s own grid units, and this product has no such number — 終身払 runs to the terminal age of the table, which is what proj_len() computes. The model point column keeps the name prem_period.

omega_age()[source]#

The terminal age of the mortality table for this life’s sex.

Read from the shipped table rather than hard-coded: 116 for males and 118 for females on 第三分野標準生命表2018 [REG-R18] [REG-R20], and whatever a replacement table carries after that. The table’s last row for a sex has mort_rate = 1.

proj_len()[source]#

The number of projected policy months, 12 (omega_age() - issue_age() + 1).

684 for the anchor cell. Cover and premiums are both whole of life [S1] [S4] [S7] [S8] [S10] [S11], so nothing but the table ends the projection: there is no maturity, no maturity benefit and no renewal.

age(t)[source]#

age(t): the attained 満年齢 in policy month t, x + floor(t / 12).

policy_year(t)[source]#

y(t): the policy year of month t, floor(t / 12) + 1, 1-based.

mort_rate_base(t)[source]#

The mortality table rate at age(t), before mort_be_factor.

A [std] construction in the shape of 第三分野標準生命表2018 — quoted anchors joined by a log-linear graduation — rather than a copy of it; see Data.

mort_rate(t)[source]#

The best-estimate annual mortality of a healthy life at age(t).

mort_be_factor x q_third_sector(age, sex), capped at 1. The table is a valuation table whose margin runs the wrong way for a best estimate on a living-benefit product: it is graduated from a national life table rather than insured experience, it excludes 高度障害, and its risk-theory adjustment is bounded 70% below and 85% above the unadjusted rate [R9] [REG-R20]. mort_be_factor = 1.25 is the reciprocal of 0.80, a round value inside that sourced band — it unwinds the table’s stated margin and nothing more [std] — and is identical to the third-sector chassis’s, because it is the same table read for the same reason.

mort_rate_mth(t)[source]#

q_H(t): monthly healthy mortality, 1 - (1 - mort_rate(t))^(1/12) [std].

mort_rate_care(t)[source]#

The annual mortality of a life in the care state at age(t).

k x mort_rate(t) with k = care_mort_mult = 2.75, capped at 1. No impaired-life table for the 要介護 state exists in any retrieved source, so the multiple is anchored on two sourced numbers instead: 平均余命 at age 75 on 第23回完全生命表 is 12.54 years for a male [R13] [REG-R24], and the only quantified duration of care in any retrieved source is a household survey’s average of 55.0 months [R14]. On a constant-force approximation life expectancy is the reciprocal of the force, so 12.54 / 4.583 = 2.74, rounded to 2.75 [std]. Both inputs are biased and the biases are named rather than netted; there is no observed range.

On the shipped table k x mort_rate first exceeds 1 at male age 105 and female age 111, so the cap binds from there, where the surviving block is negligible [std].

k is not only a post-onset assumption: it is also the second term of the incidence identity in inc_rate(), and dropping it cuts lifetime lump-sum claims on the anchor cell by about 31%. That coupling is the least obvious property of this model.

mort_rate_care_mth(t)[source]#

q_C(t): monthly care-state mortality, from mort_rate_care() [std].

lapse_rate(t)[source]#

The annual lapse rate in the policy year of month t, from lapse_table.csv.

The policy year is capped at the last year in the table, which carries the terminal rate — a whole-of-life projection would otherwise run off the end of it. The only published industry-wide persistency figure in Japan is a 5.6% p.a. 解約・失効率 on 個人保険 measured on opening in-force sum assured [REG-R31], and no Japanese durational curve is public, so the shape is a [std] standardization anchored to that single number.

lapse_rate_mth(t)[source]#

w(t): the monthly lapse rate, 1 - (1 - lapse_rate(t))^(1/12) [std].

Applied to pols_act() only — see the Space docstring.

lapse_cum(t)[source]#

w_cum(t): the proportion of the original cohort lapsed before month t.

A proportion of the original cohort, not a running total of lapse_rate(), and it drives a loading on incidence rather than on mortality — see sel_lapse_factor().

sel_lapse_factor(t)[source]#

The anti-selective lapse loading on incidence; 1.0 in the base run.

1 + lam max(0, w_cum(t) - w_ref) with w_ref = sel_lapse_ref = 0.20 and lam = sel_lapse_lambda() [std]. Healthy lives lapse first, so the persisting block is progressively impaired on the incidence basis — the opposite direction from a death-benefit product, where the same mechanism loads mortality. No Japanese selective-lapse evidence was retrieved.

prev_param(name)[source]#

One parameter of the certification prevalence logistic, from the input table.

prev_ceil, prev_beta and prev_x_mid are the fitted [std] parameters; the file also carries the two sourced 認定率 anchors they were pinned to, 4.3% at ages 65-74 and 31.1% at 75 and over [R4] [R5] [REG-R30].

grade_share(grade)[source]#

s_G: the share of all certified persons at grade or above.

0.715 at 要介護1以上, 0.508 at 要介護2以上 and 0.340 at 要介護3以上, from the published grade composition [R4] [REG-R30]. Holding the shares constant across ages is a standardization with a known direction of error: severity composition worsens with age, so the model understates 要介護3以上 prevalence at old ages and overstates it at young ones. The published composition is a single all-ages figure, so no observed range exists [std].

prev_rate(t)[source]#

prev(x): the all-grade certification prevalence at age(t).

A logistic in attained age [std], prev_ceil / (1 + exp(-beta (x - x_mid))), pinned to the two sourced 認定率 at representative ages 70 and 82 [R4] [R5] [REG-R30]. Only two age-banded rates were retrieved; the five-year-band rates that a finer basis wants sit in an unfetched e-Stat release of the same statistic [REG-R33].

Read the fitted tail as an upper bound on the gradient: because prev is convex over the 75+ band, pinning at the population mean age assigns the band average to too young an age and therefore overstates beta.

Nothing above age 82 is sourced, and that is where the claims are. The logistic has three parameters and two anchors, so one degree of freedom is unidentified — and the free one, prev_ceil = 0.95 [std], is the one that sets the tail. prev(90) = 0.662 and prev(100) = 0.894 are extrapolations, not fitted values, and 40.2% of the anchor cell’s lifetime benefit outgo (74.7% at issue age 79) falls at attained age 83 or over. That makes the tail a first-order model risk rather than a detail of the fit; technical-notes.md carries the sensitivity and the shipped tests pin both rates.

prev_slope(t)[source]#

prev’(x): the derivative of prev_rate() in age, a rate per year.

The analytic derivative of the logistic, beta prev (1 - prev / prev_ceil), not a difference quotient: it is one of the two terms of the incidence identity and a numerical derivative would put noise straight into the claim rate.

prev_grade(t, grade)[source]#

prev_G(x): the prevalence of certification at grade or above at age(t).

s_G x prev(x) — a dimensionless proportion of a population, never a rate.

f_age(t)[source]#

f_age(x): the sub-65 特定疾病 gate on the entry rates [std].

Below 65 the public limb fires only where the care state arises from one of the 16 特定疾病 listed in 介護保険法施行令 第2条 [R1] [R3], and the company-basis limb that partly fills the hole is restricted to lives 満65歳未満 [S1] [S4] [S12]. So the gate is 0.20 below 65 with the company limb written and 0.05 without it, 1.00 at 65 and over.

f_sub65 = 0.20 is a standardization with a weak anchor and is named as such: 第2号被保険者 are 1.85% of all certified persons [R4], but the 第2号被保険者 denominator was not retrieved so no rate can be computed, and the factor is set well above 1.85% because the company-basis limb backfills part of the restriction. There is no observed range. The gate produces a step of about 6.1x in incidence between age 64 and age 65, which is a real feature of the product and not an artefact to smooth away.

inc_rate(t, grade)[source]#

i_G(x): the annual rate of first entry into grade or above at age(t).

The two-term prevalence-to-incidence identity, gated below 65:

i_G(x) = f_age(x) [ prev_G’(x) / (1 - prev_G(x))
  • prev_G(x) (mu_C(x) - mu_H(x)) ]

with mu_C - mu_H = (k - 1) mort_rate(x). The second term is not a refinement: a rising prevalence understates incidence because the certified population is being drained by its own excess mortality, and on the anchor basis the mortality term is 5.8% of i_L at age 60 and a much larger share at the ages where claims actually happen.

The conversion rests on a stationary-population assumption [std]: the cross-sectional 認定率 by age is read as the prevalence path a cohort will follow. Certified persons have grown roughly 2.8-fold in the 23 years since the scheme began [R16], so the cross-section is not a cohort path; the assumption is stated rather than hidden.

inc_rate_mth(t, grade)[source]#

The monthly rate of first entry into grade or above, i_G(x) / 12 [std].

Uniform within the policy year, exactly as the third-sector chassis treats its incidence. Loaded by sel_lapse_factor(), which is 1.0 in the base run, and zero inside the 不担保期間 of waiting_mths().

inc_rate_w(t)[source]#

i_W: the annual rate of entry into the waiver grade G_W at age(t).

inc_rate_l(t)[source]#

i_L: the annual rate of entry into the lump-sum grade G_L at age(t).

inc_rate_n(t)[source]#

i_N: the annual rate of entry into the annuity grade G_N at age(t).

inc_rate_w_mth(t)[source]#

i_W_m: the monthly rate of entry into the waiver grade in month t.

inc_rate_l_mth(t)[source]#

i_L_m: the monthly rate of entry into the lump-sum grade in month t.

inc_rate_n_mth(t)[source]#

i_N_m: the monthly rate of entry into the annuity grade in month t.

pols_act(t)[source]#

act(t): the active population at the start of month t.

In force and not yet certified at G_W: the premium-paying and lapse-exposed population. act(0) = 1, then

act(t+1) = ( act(t) - n_W(t) ) (1 - q_H(t)) (1 - w(t))

Care-state lives are not here: they carry mortality only.

care_w(t)[source]#

care_w(t): in force and entered G_W — waiver running, premium zero.

care_w(0) = 0, then

care_w(t+1) = ( care_w(t) + n_W(t) ) (1 - q_C(t)) - term(t)

Lapse is suspended for these lives: with the premium waived and treated as paid on each 払込期月の契約応当日 [S1] [S2] there is no premium to miss, and with no 解約返戻金 there is nothing to surrender for.

rec_rate() does not act on this ledger, under either annuity test. It is the rate of falling below G_N, two grades above G_W, so a life it moves keeps its waiver for life; see rec_rate() for why the second threshold is not modelled and which way that biases premium income.

care_l(t)[source]#

care_l(t): in force and entered G_L — the lump sum has been paid.

A cumulative first-entry counter, not a compartment: it is nested inside care_w(), never added to it.

care_n(t)[source]#

care_n(t): in force and entered G_N — the 介護年金 is in payment.

Carries the recovery decrement under the state annuity test and nothing extra under the survival test, so that a recovered life falls back into the pool pols_entry_n() draws from and can re-qualify on a new 介護年金支払基準日.

pols_if(t)[source]#

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

pols_act(t) + care_w(t): alive, not lapsed and not extinguished by the annuity cap, whether or not the premium is being waived. pols_if(0) = 1. This is the weight on every cash flow of the same result_cf() row. Zero from proj_len() on.

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 any decrement; the same number as pols_if() and the weight on that month’s cash flows.

"BEF_LAPSE"

after care incidence and mortality, before lapse — the notes’ processing order is incidence, then mortality, then lapse [std order] — so this is the population lapses are taken from, plus the care lives that are not exposed to them.

"AFT_DECR"

l(t+1), the end-of-month state, after lapse and after the benefit-driven termination.

pols_entry_w(t)[source]#

n_W(t): expected entrants into G_W in month t, from the active population.

act(t) i_W_m(t). Drawn from pols_act() alone, because a life already certified at G_W cannot enter it again.

pols_entry_l(t)[source]#

n_L(t): expected entrants into G_L in month t.

(pols_if(t) - care_l(t)) i_L_m(t). Drawn from everyone in force who has not yet reached that grade, which includes lives already on waiver: progression up the ladder is the dominant route into the higher grades, not direct entry from health.

pols_entry_n(t)[source]#

n_N(t): expected entrants into G_N in month t, and the annuity cohort of t.

(pols_if(t) - care_n(t)) i_N_m(t). This cohort is paid its first instalment immediately, in the month of entry: see ann_count().

pols_death(t)[source]#

Expected deaths in month t, across both the active and the care populations.

Active lives carry q_H, care lives q_C, both applied after the month’s care incidence. Death pays nothing: the contract terminates with no 死亡保険金 [S1] [S11], which is why there is no claims_death cells anywhere in this model.

pols_lapse(t)[source]#

Lapses at the end of month t, from the survivors of mortality in pols_act.

Pays nothing — there is no 解約返戻金 at any duration [S1] [S2] [S7] [S8] — so this moves pols_if() and nothing else. Lives on waiver are not exposed.

pols_term(t)[source]#

term(t): lives extinguished by taking their last permitted annuity instalment.

The cohort that entered G_N in month t - 12 (n_A - 1) and has survived to t. It is removed from care_n(), care_l(), care_w() and hence from pols_if() — the retroactive extinction of the contract on the tenth instalment [S1], expressed on a monthly grid.

On the anchor cell the cap binds: about 15% of entrants reach the tenth instalment. Do not carry the medical chassis’s intuition across, where the 通算 day ledger never binds on the expectation.

care_surv(s, t)[source]#

S_C(s, t): survival in the care state from month s to month t.

The partial product of (1 - q_C(u)) over u = s ... t-1, times (1 - rec_rate_mth()) per month under the state annuity test. Computed as a partial product and never as a ratio SC(t) / SC(s) of cumulative products: q_C reaches 1 at the terminal age, so a cumulative product underflows to zero and the ratio form divides by zero exactly where the tail of this liability lives.

ann_count(t)[source]#

The expected number of 介護年金 instalments falling due in month t.

Instalments fall on the annual anniversaries of the 介護年金支払基準日, so the cohort entering in month s is paid in months s, s+12, ..., s+12(n_A - 1) while it survives [S1] [S7]:

ann_count(t) = sum over j = 0 … n_A-1 of n_N(t - 12j) S_C(t - 12j, t)

The j = 0 term is pols_entry_n() itself: payment in advance, on the entry date. Deferring the first instalment by a year would remove roughly a tenth of the annuity liability and misdate all of it.

dem_inc_rate_mth(t)[source]#

The monthly rate of a first 器質性認知症 diagnosis under the rider [std].

dementia_share of the entry rate into the lump-sum grade, zero before the dementia_wait_mths 認知症診断責任開始期 [S4] [S5] and zero when the rider is not attached. No published dementia incidence basis appears in any retrieved source, so both the share and the waiting period are placeholders in the shape of such a basis, exactly as the reference libraries treat an unsourced rider incidence. There is no observed range.

care_dem(t)[source]#

In force and already paid the rider’s 認知症 benefit; a first-event counter.

Once only per contract [S4] [S5] [S7] [S13]. Carried on the care-state mortality basis, like the three care ledgers, and held at or below pols_if() so that pols_entry_dem() always draws from a non-negative pool: the rider’s incidence is unrelated to the annuity cohort that drives pols_term(), so the ledger has no other claim on the terminated lives [std].

pols_entry_dem(t)[source]#

Expected first 認知症 diagnoses under the rider in month t.

(pols_if(t) - care_dem(t)) x dem_inc_rate_mth(t). Zero on every model point but 6.

premiums(t)[source]#

Premium income at the start of month t: P x pols_act(t).

Not P x pols_if(t). The waiver fires two grades below the annuity and one below the lump sum, so a band of lives pays nothing and receives nothing; charging premium to the whole in-force block overstates lifetime premium income by about 5.9% on the anchor cell, and at age 85 the band on waiver is about 30% of the block.

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

Benefit outgo at the end of month t, by kind.

"LUMP"

A_L n_L(t): the 介護一時金, once per contract on first entry into G_L. Paying it does not terminate the contract [S1] [S4] [S7] [S12].

"ANNUITY"

A living benefit, paid on survival in the certified care state and stopped by death: A_N ann_count(t), the 介護年金, in advance, capped at n_A instalments. The column name claims_annuity describes the benefit’s form, a stream of instalments, not its contingency; in IncomeTerm_JP_S the same name is a death benefit, so the contingency is stated here rather than inferred from the name. Where the annuity triggers before the lump sum has been paid, the unpaid lump sum is paid together with the first instalment [S1]; on the expectation the nesting of the ledgers already delivers that, since care_n <= care_l.

"DEMENTIA"

the 認知症一時金特約, (1 + mci_fraction) x dementia_amount per first diagnosis. Zero unless the rider is attached; see the Space docstring for why the MCI limb and the dementia limb are carried as one event.

"LAPSE"

identically zero, and published rather than dropped. There is no 解約返戻金 at any duration [S1] [S2] [S7] [S8], so a lapse pays nothing — the zero is the product fact.

With no kind the total of the three benefit limbs.

claim_expenses(t)[source]#

ec x (n_L(t) + ann_count(t)): the claim-handling expense of month t [std].

¥5,000 per claim event — the lump sum, and each annuity instalment — raised from the third-sector chassis’s ¥3,000 because a care claim requires verification of a municipal certification the insurer does not control, or adjudication of a 180-day persistence test against a 約款 definition the carrier itself says differs from the public standard [S1] [S2], and every annuity instalment carries an annual survival check [S1] [S7]. Uninflated. The rider’s diagnoses are charged the same fee, which leaves the figure identical to the notes’ whenever the rider is off.

inflation_factor(t)[source]#

The expense inflation factor in month t: (1 + pi)^floor(t/12) [std].

1.0% p.a. flat, stepping at each 年単位の契約応当日 rather than monthly.

expenses(t)[source]#

E0 and e(t): acquisition and maintenance expense in month t [std].

¥20,000 acquisition per policy at t = 0, then ¥250 per policy per month inflating at 1.0% p.a. Maintenance is charged on pols_if(), including lives on waiver: the policy is still administered when nobody is paying for it.

The claim-handling expense is not here. It is a separate cells, claim_expenses(), deducted on its own line in net_cf() and published in its own claim_expenses column of result_cf(), which is what expenses means everywhere in this library. technical-notes.md prints the two combined in its worked-example expenses column and in its year-1 total — so the notes’ ¥20,250.09 at t = 0 is expenses(0) + claim_expenses(0), and the notes say so at the table.

comm_init_pp()[source]#

c0: initial commission per policy issued, 1.5 x 12 P [std].

¥207,000 on the anchor cell, paid upfront at t = 0. With the acquisition expense this is what produces the deep new business strain of the worked example’s first row.

commissions(t)[source]#

Commission outgo in month t [std].

The initial commission at t = 0, then 3.0% of premium income from policy year 2 — that is, from t = 12. Both levels are standardizations inherited from the third-sector chassis. Renewal commission rides on premiums(), so it stops when the waiver stops the premium.

net_cf(t)[source]#

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

Premiums less the lump sum, the annuity, the rider, acquisition and maintenance expense, the claim-handling expense — deducted on its own line, because expenses() no longer carries it — and commission. 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 month-0 strain, upfront commission and acquisition expense against a single month’s premium, then thin positive margins for twenty-five years, then a long negative tail: this product prefunds a cost that essentially does not arise until the block is old, which is what makes the lapse assumption, not the incidence basis, the dominant lever.

check_pols_roll_fwd_resid(t)[source]#

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

pols_if(t) - pols_if(t+1) - deaths - lapses - terminations. The three decrements are the only ways a life leaves this contract: there is no maturity, and recovery is scoped to the annuity ledger, so nothing else may move pols_if(). A lapse applied to the care population, or a termination not removed from care_w, shows up here.

check_pols_roll_fwd()[source]#

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

No argument, one bool over all t, the library-wide shape of a check_* cells; check_pols_roll_fwd_resid() gives the signed residual of the month that failed.

check_nesting_resid(t)[source]#

The smallest slack in the ledger ordering at month t; non-negative everywhere.

min(pols_if - care_w, care_w - care_l, care_l - care_n). The three care ledgers are marginal first-entry distributions riding on one survival ledger, so the ordering care_n <= care_l <= care_w <= pols_if is what makes them meaningful — and a negative value here would mean a life had started the annuity before its lump sum was paid, which the contract forbids.

check_nesting()[source]#

True when the three care ledgers stay nested inside the in-force in every month.

The notes’ check_nesting(): it asserts the ordering, never a sum, because the ledgers must never be added together.

check_ann_ledger_resid(t)[source]#

The annuity ledger residual in month t; zero everywhere.

ann_count() less an independent rebuild that scans every month s in the window t - 12 n_A < s <= t and keeps those on an annual anniversary of the entry month, rather than stepping back in twelves. A ledger that paid the first instalment a year late, that ran past the cap, or that used a ratio form of care_surv() would show up here.

check_ann_ledger()[source]#

True when the annuity ledger closes in every projected month.

check_net_cf_resid(t)[source]#

The residual between net_cf() and the published components; zero everywhere.

net_cf less premiums - claims_lump - claims_annuity - claims_dementia - claims_lapse - expenses - claim_expenses - commissions, which are exactly the columns of result_cf(). A cash flow that exists in net_cf but not in the statement, or the reverse, shows up here — and so would a claim expense left folded into expenses and then deducted twice.

check_net_cf()[source]#

True when the cash flow statement re-adds to net_cf() in every month.

result_cf()[source]#

Result table of cash flows, indexed by policy month t.

claims_annuity is a living benefit: the 介護年金 is paid while the insured survives in a certified care state at grade_annuity(), and death stops it. The name describes the benefit’s form, a stream of instalments, and the same name carries a death benefit in IncomeTerm_JP_S, so which contingency it is paid on is stated and not left to the name.

pols_if is the start-of-month count, which is the weight applied to every cash flow on the same row, and pols_act is the part of it that is actually paying premium. net_cf carries the notes’ own income-positive sign. claims_lapse is a column of zeros by product design — there is no surrender value — and is published rather than dropped; see the Space docstring. There is no claims_death column, because the contract pays nothing on death.

result_pols()[source]#

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