The Projection Space#
The by-policy projection of the Medical_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 = 3 # or switch the default
t counts policy months, 0-based: t = 0 is the first policy month and
t = proj_len() - 1 the last. Month t is the interval from t to t + 1
months after the 契約日. On the 終身 chassis the horizon is the terminal age of the
mortality table — 116 male, 118 female — and there is no maturity benefit at it; on the
定期 model point flag the horizon is the last ten-year renewal that completes before
age 80.
Input data
Inputs are external files: plain CSVs living in the model folder’s parent directory,
products/medical/, 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
Medical_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 |
incidence_table_file |
data.incidence_table() |
incidence_table.csv |
los_table_file |
data.los_table() |
los_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 companions, *_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 symbols instead.
The mapping is:
Notes symbol |
Cells |
Meaning |
|---|---|---|
(model point row) |
model_point() |
The selected model point |
chassis |
chassis() |
shushin (終身) or teiki (定期) |
x |
issue_age() |
契約年齢, 満年齢 at 契約日 |
age(t) |
age(t) |
Attained 満年齢 in month t |
y(t) |
policy_year(t) |
floor(t/12) + 1 |
(none) |
sex() |
M or F |
D |
daily_amount() |
入院給付金日額, JPY per day |
L1 |
limit_per_hosp() |
Per-hospitalization day limit |
LA |
limit_agg() |
通算 day limit, per limb |
F |
min_days_floor() |
Five-day minimum, 5 or 0 |
P |
premium_mth_pp() |
Monthly office premium |
(none) |
prem_period_type() |
whole_life or to_65 |
(none) |
prem_end_month() |
First month with no premium |
(terminal age) |
omega_age() |
Terminal age of the table |
(final expiry) |
expiry_age() |
定期 flag’s final expiry age |
proj_len |
proj_len() |
Number of projected months |
(table) |
mort_rate_at_age(x) |
第三分野 proxy rate at age x |
(table) |
mort_rate_base(t) |
第三分野 proxy rate at age(t) |
mort_be_factor |
mort_be_factor |
1.25 [std] best-estimate scale |
q(age) |
mort_rate(t) |
Annual best-estimate mortality |
q(t) |
mort_rate_mth(t) |
Monthly mortality in month t |
(table) |
lapse_rate(t) |
Annual lapse rate, policy year |
w(t) |
lapse_rate_mth(t) |
Monthly lapse in month t |
w_cum(t) |
lapse_cum(t) |
Cumulative lapse proportion |
lam |
sel_lapse_lambda |
Anti-selective lapse loading |
w_ref |
sel_lapse_ref |
Its cumulative-lapse threshold |
(none) |
sel_lapse_factor(t) |
Loading on morbidity |
juryoritsu, alos |
inc_rate_base(t) |
受療率 -> incidence [std] |
inc_rate(age) |
inc_rate(t) |
Annual incidence, effective |
i(t) |
inc_rate_mth(t) |
Monthly incidence |
g_j |
los_days(band) |
Stay-length band day values |
pi_j |
los_probs(band) |
Stay-length band probabilities |
Sum pi_j g_j |
d_raw(t) |
Uncapped mean stay |
Sum pi_j min(g_j, L1) |
d_pay_capped(t) |
Paid days after L1 |
d_pay |
d_pay(t) |
Days that consume the ledger |
d_ben |
d_ben(t) |
Benefit days, floor included |
(none) |
d_ben_free(t) |
Days outside the 通算 count |
(none) |
d_ben_ltd(t) |
Days inside the 通算 count |
room_dis, room_acc |
room_dis(t), room_acc(t) |
Days left on each limb |
d_pay_dis, d_pay_acc |
d_pay_dis(t), d_pay_acc(t) |
Paid days after the 通算 cap |
d_ben_dis, d_ben_acc |
d_ben_dis(t), d_ben_acc(t) |
Benefit days after the cap |
A_dis(t) |
agg_days_dis(t) |
疾病 通算 ledger, days |
A_acc(t) |
agg_days_acc(t) |
災害 通算 ledger, days |
s_dis, s_acc |
s_dis, s_acc |
Limb split of incidence [std] |
term(t) |
term_rate(t) |
Benefit-driven termination |
s_ih |
surg_ih_per_hosp |
In-hospital surgeries per stay |
s_op |
surg_op_per_hosp |
Outpatient surgeries per stay |
(switch) |
surg_ih_eff(t) |
In-hospital surgeries payable |
m_ih, m_op |
surg_mult_ih(), surg_mult_op() |
Surgery multiples of D |
f_adv |
adv_freq_mth() |
Monthly 先進医療 frequency |
S_adv |
adv_sev |
Mean 技術料 per 療養 |
pay(t) |
adv_pay_pp(t) |
Reimbursement before top-up |
adv_claim(t) |
adv_claim_pp(t) |
先進医療 claim per policy |
V(t), LV |
adv_paid(t), adv_cap |
先進医療 ledger and its cap |
(rider) |
lump_count(t) |
入院一時金 通算 count ledger |
waived(t) |
waived(t) |
Fraction on 保険料払込免除 |
waiver_inc |
waiver_inc_mth(t) |
Waiver incidence, 0 in base |
l(t) |
pols_if(t) |
In force at the start of t |
l(t)(1-q), l(t+1) |
pols_if_at(t, timing) |
BEF_DECR / BEF_LAPSE / AFT_DECR |
(none) |
pols_death(t) |
Deaths in month t |
(none) |
pols_lapse(t) |
Lapses in month t |
(none) |
pols_term(t) |
Benefit-driven terminations |
(none) |
pols_maturity(t) |
Cover ending at the scheduled end |
(none) |
pols_payer(t) |
Policies actually paying |
(none) |
cv_pp(t) |
解約返戻金, zero under 終身払 |
P l(t)(1 - waived) |
premiums(t) |
Premium income |
claims_hosp(t) |
claims(t, “HOSP”) |
入院給付金 outgo |
claims_surgery(t) |
claims(t, “SURGERY”) |
手術給付金 outgo |
claims_advanced(t) |
claims(t, “ADVANCED”) |
先進医療給付金 outgo |
(rider) |
claims(t, “LUMP”) |
入院一時金 outgo |
(zero) |
claims(t, “LAPSE”) |
Surrender outgo, zero on 終身払 |
claims(t) |
claims(t) |
All benefit outgo |
e(t) |
expense_maint_pp(t) |
Maintenance expense per policy |
ec i(t) |
claim_expenses(t) |
Claim handling expense, separate |
E0, e(t) |
expenses(t) |
Acquisition + maintenance only |
commissions(t) |
commissions(t) |
Commission outgo |
net_cf(t) |
net_cf(t) |
Net cash flow, income positive |
Four names needed care.
The notes write i(t) for the monthly incidence and inc_rate(age) for the annual
one. The library convention is that a bare *_rate is annual and *_rate_mth its
monthly companion, as mort_rate / mort_rate_mth already are, so the two become
inc_rate() and inc_rate_mth() and neither can be mistaken for the other.
d_pay and d_ben are not the same quantity and the difference is the
five-day minimum. The carriers express the floor as an amount, 日額 x 5, not as a
credit of five days, so it enters d_ben() and never d_pay() — and therefore
never the 通算 ledger. check_day_limits() asserts d_ben >= d_pay in every
month; a model that credited the floor to the ledger would let a two-day stay consume
five days of a lifetime limit it never used.
term(t) in the notes is a 0/1 indicator, and a decrement count is a different thing
from a decrement rate. It is spelled term_rate() here, alongside
mort_rate_mth() and lapse_rate_mth(), with the count it produces at
pols_term().
pols_maturity has no symbol in the notes at all. Library-wide it is the count whose
cover ends at the scheduled end of the contract, whether or not anything is paid for
it; any payment would be claims(t, "MATURITY"), and on this product there is none.
The 終身 chassis has no scheduled end: the projection stops where the mortality table
does and everybody has already died, so the cells is zero even in the final month. The
定期 model point flag does have one — its final ten-year renewal — and without a term
for it the in-force roll-forward would appear to lose lives with no cause in that month.
check_pols_roll_fwd() asserts
- pols_if(t) - pols_if(t+1) = pols_death(t) + pols_lapse(t) + pols_term(t)
pols_maturity(t)
in every projected month. It is bookkeeping determined by the notes’ own rules, not an added assumption, and it is not a maturity benefit: the amount paid is nil.
The day-limit machinery
Three limits act in a fixed order, and getting the order wrong is the classic implementation failure on this product.
1 — the per-hospitalization limit ``L1``, applied inside the stay expectation, spell
by spell, before anything else: d_pay_capped = Sum_j pi_j min(g_j, L1). On the anchor
cell’s 35-64 row that is 15.20 days against an uncapped mean of 20.20 — the 60-day cap
removes 24.75% of raw days. Capping the mean instead would give
min(20.20, 60) = 20.20 and silently remove the limit altogether.
2 — the five-day minimum, which is an amount and not days, so it enters
d_ben() only: d_ben_capped = Sum_j pi_j max(F, min(g_j, L1)). With F = 5
the 35-64 row gives 16.10 benefit days against 15.20 paid days.
3 — the aggregate limit ``LA``, per limb, with memory. Two ledgers, because the 通算 limit runs separately on the 疾病 and 災害 limbs, and cover ceases only when both are exhausted. One combined ledger terminates the contract roughly twice as early.
The two ledgers are carried per surviving policy and are never weighted by
pols_if. This is the easiest state-variable error in the product: a ledger multiplied
by the in-force probability measures the block’s consumption rather than the
individual’s, and defers the limit indefinitely.
On the anchor cell’s expectation LA never binds — agg_days_dis grows by about
0.709 days a year at age 40 and about 15.2 at 90 and over, reaching only single-digit
hundreds of days by the terminal age — and the ¥20,000,000 先進医療 cap is never
approached either. That is a property of the expectation, not of the product:
E[min(Sum, LA)] != min(E[Sum], LA), so the deterministic ledger understates the
limit’s bite by ignoring dispersion [std]. The machinery is implemented anyway
because it binds under the 三大疾病無制限 特則 and because a seriatim or stochastic run
needs it. It is not kept for the dependants: neither Cancer_JP_S nor LTC_JP_S
inherits it — each deletes the day-limit machinery outright as a product fact of its own.
Do not delete a ledger because it reads zero.
Modules that are off in the base run
Five 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:
Anti-selective lapse,
inc_eff = inc (1 + lam max(0, w_cum - w_ref))withsel_lapse_lambda = 0. Healthy lives lapse first, so the persisting block is progressively impaired on the morbidity basis rather than the mortality one — the reverse of the term assurance case. No Japanese selective-lapse evidence was retrieved.保険料払込免除 (premium waiver), an absorbing state on the premium-paying population, with incidence zero unless the 特定三疾病保険料払込免除特則 is elected on the model point. The base contractual waiver is disability-triggered and its incidence is zero in every run: 第三分野標準生命表2018 excludes 高度障害, so the incidence cannot be read out of the mortality basis, and no public Japanese 高度障害 incidence table was retrieved. Model point 7 exercises the elected 特則 at the notes’ suggested placeholder
waiver_inc_mult = 0.25xmort_rate.The 三大疾病無制限 特則, which does not merely raise the limits: it takes がん, 心疾患 and 脳血管疾患 days out of the 通算 count entirely and removes
L1for them, deferring the benefit-driven termination. Off on the anchor cell, elected on model point 4. Its one parameter,share_3dis, is [std] and carries no observed range — no cause split of 入院受療率 was extracted in the research pass.入院一時金特約, ¥100,000 per hospitalization with a 通算 count limit of 50, off on the anchor cell and elected on model points 3 and 7.
The age-basis offset. The contract ages on 満年齢 while 第三分野標準生命表2018 is built for 保険年齢方式, so half a year sits between the projection basis and the valuation basis.
age_basis_offset = 0accepts the offset [std]; setting it to 0.5 reads the table atage(t) + 0.5by linear interpolation. The notes require the mismatch be stated rather than silently absorbed, which is what the switch does.
surg_after_limit is a switch too, but it is on in the base run because it
resolves a contradiction between carriers rather than an optional feature: where
surgery is performed during a stay for which 入院給付金 is no longer payable because
L1 is exhausted, one carrier pays at the in-hospital multiple and another pays
nothing at all. The composite pays. With the switch reversed — model point 5 — the
truncated day fraction, 24.75% of in-hospital surgeries on the anchor basis, falls
outside cover. The two positions differ by a quarter of the in-hospital surgery benefit
and are not roundable into each other.
Sign convention
The notes’ net_cf(t) is already income positive — premiums less benefits, less
acquisition and maintenance expense, less claim expense, less commission — which is the
library-wide sign of net_cf(), so unlike
the whole life and payout annuity models there is no liability_cf companion to
publish: one stream, one sign, one name.
Three absences that are product facts
There is no death benefit: the main contract pays nothing on death, so mortality is a
pure liability-releasing decrement and no claims_death exists. There is no
自動振替貸付 and no 契約者貸付: with no surrender value there is nothing to lend
against, so nothing carries a policy through a missed premium and no lapse-suppression
term belongs in the recursion — importing the WholeLife_JP_A machinery here would
suppress lapses that really happen. And there is no surrender value at all under
終身払, at any duration, so claims(t, "LAPSE") is identically zero on the anchor cell
and the zero is published rather than dropped. cv_pp() exists only because the
65歳払済 short-pay variant acquires a small value, 10 x 日額, once the premium-paying
period completes — model point 4 — and that is the single route by which this chassis
ever has one.
Cells Descriptions#
- chassis()[source]#
shushin(終身, whole of life) orteiki(定期, ten-year renewable).Three of the five carriers write 終身 only, one writes 終身 and 定期 as separate products and one writes only a 医療保険(定期型)renewable to age 80 [S1][S4][S6] [S7][S9][S10]. The composite takes 終身 — the majority design, and the one that exercises the lifetime aggregate limit, which a ten-year term does not.
- issue_age()[source]#
x: the 契約年齢 on a 満年齢 basis, 20 to 80 [S3][S6][S10].
満年齢 is the attained age at the 契約日 with the fraction discarded, incremented at each 年単位の契約応当日 [S4][S10].
- sex()[source]#
The sex, M or F. A rating factor at every carrier [S6].
The published premium scales cross over between ages 30 and 40 — female above male at 20 and 30, below from 40 on [S3][S8] — which is a morbidity feature, not a pricing artefact, and is what the [std] sex factors on incidence reproduce.
- daily_amount()[source]#
D: the 入院給付金日額, JPY per day; menu ¥3,000-¥15,000 [S6].
The unit of account of the whole product. This is a frequency x severity x limit structure, not a sum-assured structure, so
Dmultiplies days and never a benefit amount.
- limit_per_hosp()[source]#
L1: the 1入院の支払限度日数, 60 or 120 days [S1][S4][S9].
Elected at issue and never changeable [S4][S9], which is why it is a model point attribute and not a state variable. Any code path that varies it over
tmodels a contract term that does not exist.
- limit_agg()[source]#
LA: the 通算支払限度日数, 1,095 or 1,000 days, applied per limb [S4][S1].
Four carriers write 1,095 and three write 1,000 [S1][S2][S4][S6][S7][S9][S10]; the composite takes the majority with 1,000 as a switch. Applying the cap separately to the 疾病 and 災害 limbs is the disclosed treatment at two carriers and is what this model implements — see
agg_days_dis()andagg_days_acc().
- prem_period_type()[source]#
The 保険料払込期間:
whole_life(終身払) orto_65(65歳払済) [S1][S6].終身払 is the default because it is offered everywhere and is the design under which no surrender value ever arises; the 短期払 variant is the only route by which this chassis acquires one at all.
P: the level monthly office premium per policy [std].
An input, not a computed quantity. No carrier publishes a rate table by age and duration: the 算出方法書 is a 基礎書類 filed with the 金融庁 and is not published [REG-R2], which is exactly why every pricing-basis parameter in this library is [std] while every contractual parameter carries an [S#] tag. The anchor value ¥2,100 sits between the two public specimen rates for this exact specification — ¥2,121 and ¥2,080 at age 40 male on a ¥5,000 daily amount, 60日型, 終身払 [S8][S3].
Level and 無配当 with no insurer repricing right on the 終身 chassis [S3][S6][S8], so every future premium is inside the contract boundary.
- prem_mode()[source]#
月払 / 半年払 / 年払.
Inert on this grid, which is monthly because the product is: 月払 is the dominant retail mode and one net-direct product is 月払 only [S10]. 6- or 12-month 前納 at a company-set discount [S4] is an immaterial modal refinement and is not modelled [std scope].
- surg_mult_op()[source]#
m_op: the 手術給付金 multiple of D for outpatient surgery, 5 or 0 [S1][S3].
Zero is a real market design, not a missing value: one carrier pays a flat 10倍 in hospital and does not cover outpatient surgery at all [S10].
- min_days_5()[source]#
Whether the five-day minimum payment applies; off in the composite base.
Two of the five carriers guarantee 「入院日数が5日以内の場合は、入院給付金日額×5」 [S4][S6][S7] and three pay actual days [S1][S2][S9][S10]. This is a first-order model choice and the two cannot be averaged: against a 28.4-day national mean stay the floor is invisible, against a 2.4-day 白内障 stay it roughly doubles the payment.
- lump_rider()[source]#
Whether the 入院一時金特約 is attached [S1]; off in the base run.
It matters economically because it is the market’s answer to falling stay lengths: as the mean stay falls a per-day benefit shrinks and a per-admission benefit does not.
- tokusoku_3dis()[source]#
Whether the 三大疾病無制限 特則 is elected [S1][S2]; off in the base run.
Elected at issue and never cancellable. For がん, 心疾患 and 脳血管疾患 the per-hospitalization limit is 無制限 and those days sit outside the 通算 count, which defers the benefit-driven termination. Lifetime cancer incidence in Japan is about 61.1% for men and 50.1% for women [REG-R28], so this is a mass-market feature rather than a fringe option.
- waiver_3dis()[source]#
Whether the 特定三疾病保険料払込免除特則 is elected [S1]; off in the base run.
When elected, premiums are waived for life on a first がん diagnosis, on 急性心筋梗塞 or on 脳卒中 under the conditions the 特則 sets [S1] — which is why
waived()is an absorbing state rather than a two-state chain.
- surg_after_limit()[source]#
Whether in-hospital surgery is paid once
L1is exhausted; true in the base.A genuine contradiction between carriers, not a gap: one carrier pays at the in-hospital multiple [S4] and another pays nothing at all [S10]. The composite pays [S4] — the only positively stated treatment among the retrieved 約款 — and carries the alternative as this switch. See
surg_ih_eff().
- pols_if_init()[source]#
The initial in-force probability: 1.0.
One policy at a time, projected on an expected basis, so
pols_ifis a probability rather than a count and no aggregation logic is specified.
- omega_age()[source]#
The terminal age of the mortality basis: 116 male, 118 female [REG-R18][REG-R20].
Read off
mort_table.csvrather than hard-coded, so that replacing the table replaces the horizon with it.
- expiry_age()[source]#
The 定期 flag’s final expiry age: the last ten-year renewal completing by 80.
Cover renews automatically at the renewal-date age and rate scale, and the 通算 aggregate limit and the 先進医療 cap run across renewals [S7][S10]. The reading of 「renewable to age 80」 as the last renewal whose term completes at or before 80 is [std]. Meaningless on the 終身 chassis, which is why it raises there.
- proj_len()[source]#
The number of projected policy months.
終身:
12 x (omega_age() - x + 1)— 924 months on the anchor cell, the whole of life to the terminal age of the mortality basis, with no maturity benefit and no 満期保険金 at it [S1][S6]. 定期:12 x (expiry_age() - x).On the 定期 flag the ten-year renewal reprices, which would ordinarily close the contract boundary at each renewal — but where the policy is on premium waiver the supervisory guideline requires the reserve to be computed as though every automatic renewal to final expiry occurs [REG-R14]. The two treatments point in opposite directions;
jplibprojects to final expiry and records the tension rather than resolving it.
- prem_end_month()[source]#
The first policy month in which no premium is payable.
proj_len()under 終身払, so a premium falls in every projected month; under the 65歳払済 variant the month of the 契約応当日 at age 65.
- mort_rate_at_age(x)[source]#
The [std] table rate at integral age
xfor this model point’s sex.mort_table.csvis a documented proxy for 第三分野標準生命表2018, not a copy of it: the publisher’s terms prohibit reproduction and transmission without written consent [REG-R21]. It is the library-wide canonical construction — log-linear between the sourced anchors and exact at every one of them, so maleq40is exactly the 0.00076 the technical notes quote [R4][REG-R18] — and the same cell carries the same value in everyjplibproduct that ships it. Ages above the terminal age take the terminal rate.
- mort_rate_base(t)[source]#
The valuation table rate at the age read in policy month t.
age_basis_offsetis 0 in the base run, so the table is read at the contract’s own 満年齢 [S4][S10] even though 第三分野標準生命表2018 is constructed for a 保険年齢方式 (nearest-birthday) basis [R5][REG-R20] — an understatement of the valuation age by about half a year, accepted and marked [std]. Setting the Reference to 0.5 reads the table atage(t) + 0.5by linear interpolation between integral ages, which is the alternative the notes name. Half a year sits between the projection basis and the valuation basis either way; the point of the switch is that it is stated rather than silently absorbed.
- mort_rate(t)[source]#
The annual best-estimate mortality rate applying in policy month t.
mort_be_factor xthe table rate, capped at 1. On a morbidity product the valuation table’s margin runs the wrong way for a best estimate: death releases the liability, so 第三分野標準生命表2018 is set deliberately below national mortality, with the risk-theory adjustment bounded below at 70% and above at 85% of the pre-adjustment rate [R5][REG-R20].mort_be_factor = 1.25[std] is the reciprocal of 0.80, a round value inside that band and a little above its 0.775 midpoint, so the factor unwinds the table’s stated margin and nothing more; the band’s own endpoints would give 1.176 and 1.429. At age 40 male it gives 0.00095, between 第三分野標準生命表2018’s 0.00076 and 生保標準生命表2018(死亡保険用)’s 0.00118 [R4][REG-R18], which is the direction sanity requires.Using the table unadjusted would overstate the liability, because an understatement of mortality on a health product overstates it — a conservative error in the reserving direction, and a material one over a projection this long.
- lapse_rate(t)[source]#
The annual lapse rate in the policy year containing month t [std].
9.0 / 7.0 / 6.0 / 5.5 / 5.0 percent, 4.5% in years 6-20 and 3.0% from year 21. The only published industry-wide Japanese persistency figure is 解約・失効率 5.6% p.a. on 個人保険, measured on opening in-force sum assured [REG-R31] — a sum-assured-weighted rate on a book dominated by 定期 and 終身 death cover, which a 医療保険 with no sum assured cannot even enter — and no Japanese durational lapse curve is public. The table is anchored to that figure by construction: its first ten years average 5.5%.
The step down at year 21 is [std] reasoning stated openly: on a contract with no surrender value and rising morbidity exposure, a long-duration policyholder has no cash incentive to lapse and a growing reason not to. Policy years beyond the table take its last row.
- lapse_rate_mth(t)[source]#
w(t): the monthly lapse rate,
1 - (1 - lapse_rate(t))^(1/12)[std].Applied at the end of month t, after mortality [std order]. A lapse pays nothing on the 終身払 anchor: there is no surrender value at any duration, and neither 契約者貸付 nor 自動振替貸付 is offered, so nothing carries a policy through a missed premium [S1][S6][S9]. The base run applies the lapse in the month the premium is missed and does not model the one-month 払込猶予期間 lag [S1][S4][S10] [std scope]; on an undiscounted projection that is a one-month timing effect.
復活 (reinstatement) is available within a year at the composite [S4][S9], but a reinstated policy is not the policy that lapsed — the 責任開始期 for pre-existing-condition tests resets to the 復活日 and the waiting periods re-run from it — so it belongs in the model as a new model point, and lapse is treated as absorbing [std scope].
- lapse_cum(t)[source]#
w_cum(t): the cumulative lapse proportion of the original cohort before month t.
A proportion of
pols_if_init(), not a running total oflapse_rate(), and it drives a loading on morbidity rather than on lapse. Zero in the first month.
- sel_lapse_factor(t)[source]#
The anti-selective lapse loading on morbidity in month t [std].
1 + lam max(0, w_cum(t) - w_ref), withsel_lapse_lambda = 0in the base run, where it returns 1 in every month. Healthy lives lapse first, so the persisting block is progressively impaired on the morbidity basis rather than the mortality one — the reverse of the term assurance case, where the loading falls on mortality. No Japanese selective-lapse evidence was retrieved, so both the shape and the level are standardizations.
- inc_rate_base(t)[source]#
The annual hospitalization incidence per life at
age(t)[std].The construction that makes this model buildable at all. There is no published morbidity table in Japan — 日本アクチュアリー会 publishes the mortality basis only [R4][REG-R23] and every insurer’s 危険発生率 is its own, unpublished [REG-R2] — so incidence is built from 患者調査, a 基幹統計 of 厚生労働省, in three steps:
入院受療率 is a point-in-time prevalence per 100,000 population, the expected proportion of the population in hospital on the census day [R6][REG-R26]. It is not an incidence rate, and treating it as one, or multiplying it straight by a daily amount, is the single commonest error in a Japanese medical model.
退院患者平均在院日数 gives the mean stay for the age band [R6][REG-R27].
In a stationary population person-days in hospital per year equal admissions x mean stay, so the [std] conversion — flagged as needed by [REG-R26] itself — is
inc = (juryoritsu / 100,000) x 365 / alos.
At age 40 that is
0.00258 x 365 / 20.2 = 0.046619per year; at 90 and over it is 0.6452 — a factor of 13.8, which is the 受療率 ratio of 24.3 damped by the 平均在院日数 ratio 20.2 / 35.5, because a longer stay turns the same prevalence into fewer admissions [REG-R26][REG-R27]. Every five-year 受療率 band the model needs is published and is carried sourced; only the sex factor is [std], because the 概況 publishes 入院受療率 by sex for all ages and by age band for both sexes combined but not the age x sex cross-tabulation, which lives in an e-Stat table that was not downloaded [R6][R7][REG-R33].
- inc_rate(t)[source]#
The annual effective incidence in month t: the table rate, loaded.
Equal to
inc_rate_base()in the base run, where the anti-selective lapse module is off.
- inc_rate_mth(t)[source]#
i(t): the monthly hospitalization incidence per in-force policy.
inc_rate(t) / 12[std] — uniform within the policy year, not a compounded twelfth, because an incidence is a count per unit time and not a probability of survival.
- los_band(t)[source]#
The broad 平均在院日数 band containing
age(t), keyed by its lower edge.Four bands, because that is the granularity 退院患者平均在院日数 is published at, against the five-year bands of 受療率 — the band mapping is itself [std] [REG-R26][REG-R27].
- los_days(band)[source]#
g_j: the stay-length day values of a length-of-stay band, ascending.
(2, 8, 20, 45, 160) at every age [std]: the 2-day band stands for the day-surgery mode and the 160-day band for the psychiatric and neurological tail that drives the sourced national mean [REG-R27].
- los_probs(band)[source]#
pi_j: the probabilities of a length-of-stay band, summing to 1 [std].
Solved so that the row mean equals the sourced 平均在院日数 for that band exactly [REG-R27]. The shape is a standardization and it matters more than the mean it reproduces: 患者調査 publishes the stay distribution in 32 bands by age band and cause, but those e-Stat CSVs were not downloaded [R7][REG-R33], and the sourced per-cause means run from 白内障 2.4 days to 精神及び行動の障害 290.4 days — a distribution with the same mean and a fatter tail changes the capped expectation without changing the calibration target at all.
- min_days_floor()[source]#
F: the five-day minimum floor in days, 5 when elected and 0 otherwise.
It is a floor on the amount — 「入院給付金日額×5」 [S4][S6][S7] — so it enters
d_ben()and neverd_pay(), and therefore never the 通算 ledger.
- d_raw(t)[source]#
Sum_j pi_j g_j: the uncapped mean stay in days at
age(t).20.2 days on the anchor cell’s 35-64 row, 35.5 on the 65+ row — the sourced 平均在院日数 that
los_probs()is calibrated to [REG-R27].
- d_pay_capped(t)[source]#
Sum_j pi_j min(g_j, L1): expected paid days per hospitalization after
L1.The per-hospitalization limit is applied inside the stay expectation, spell by spell, before anything else. 15.20 days on the anchor cell against an uncapped 20.20 — the 60-day cap removes 24.75% of raw days, and 33.8% on the 65+ row. Capping the mean instead would give
min(20.20, 60) = 20.20and remove the limit silently.
- d_ben_capped(t)[source]#
Sum_j pi_j max(F, min(g_j, L1)): expected benefit days after
L1.The five-day floor enters here and nowhere else. With
F = 5the anchor’s 35-64 row gives 16.10 benefit days against 15.20 paid days: the floor adds 0.90 days of benefit and zero days to the 通算 ledger.
- d_ben_raw(t)[source]#
Sum_j pi_j max(F, g_j): expected benefit days with no
L1at all.Used only by the 三大疾病無制限 特則, for which the per-hospitalization limit is removed [S1][S2].
The share of hospitalizations exempt from both day limits [std]; 0 in the base.
Zero unless the 三大疾病無制限 特則 is elected, in which case
share_3disof hospitalizations — がん, 心疾患 and 脳血管疾患 — carry noL1and consume no 通算 days [S1][S2].share_3disis a standardization with no observed range: no cause split of 入院受療率 was extracted in the research pass [R7][REG-R33]. It is a share of spells, not of days.
- d_pay(t)[source]#
d_pay: the expected days per hospitalization that consume the 通算 ledger.
d_pay_capped()on the anchor cell. Under the 三大疾病無制限 特則 the exempt share is removed, because those days sit outside the 通算 count entirely.
- d_ben_free(t)[source]#
The expected benefit days per hospitalization outside the 通算 count; 0 in the base.
- d_ben_ltd(t)[source]#
The expected benefit days per hospitalization inside the 通算 count.
d_ben_capped()on the anchor cell, where nothing is exempt.
- d_ben(t)[source]#
d_ben: the expected benefit days per hospitalization, before the 通算 cap.
d_ben_free(t) + d_ben_ltd(t), which collapses tod_ben_capped()whenever the 三大疾病無制限 特則 is not elected. Always at leastd_pay(), whichcheck_day_limits()asserts.
- room_dis(t)[source]#
The days left on the 疾病 limb’s 通算 ledger at the start of month t:
max(0, LA - A_dis).
- room_acc(t)[source]#
The days left on the 災害 limb’s 通算 ledger at the start of month t:
max(0, LA - A_acc).
- d_ben_dis(t)[source]#
The 疾病 limb’s benefit days after the 通算 cap [std proportional scaling].
d_ben x d_pay_dis / d_payon the anchor cell, exactly as the notes write it. The exempt share of the 三大疾病無制限 特則 is added back unscaled, because those days do not depend on the ledger at all.
- d_ben_acc(t)[source]#
The 災害 limb’s benefit days after the 通算 cap [std proportional scaling].
The 災害 limb pays the same daily amount on the same length-of-stay distribution [S1][S4][S9][S10]; admission must begin within 180 days of the accident. In the base run the split is therefore economically inert in the cash flows and structurally essential in the ledgers — which is precisely why there are two of them.
- agg_days_dis(t)[source]#
A_dis(t): the 疾病 limb’s 通算 ledger in days, per surviving policy.
A_dis(t+1) = A_dis(t) + i(t) s_dis d_pay_dis(t), unweighted bypols_if. Weighting it by the in-force probability would measure the block’s consumption rather than the policyholder’s and defer the limit forever; that is the easiest state-variable error in this product.On the anchor cell it grows by about 0.709 days a year at age 40 and reaches only single-digit hundreds by the terminal age, so
LAnever binds — a property of the expectation, not of the product, sinceE[min(Sum, LA)] != min(E[Sum], LA).
- agg_days_acc(t)[source]#
A_acc(t): the 災害 limb’s 通算 ledger in days, per surviving policy.
A separate ledger, because the 通算 limit is applied separately to the two limbs [S4][S1]. One combined ledger terminates the contract roughly twice as early. The 疾病/災害 split of incidence is [std] at 0.92 / 0.08: 損傷・中毒等 is 107 of the national 入院受療率 of 945 (11.3%) [REG-R26], and not every 損傷 admission arises from an 不慮の事故 with admission inside 180 days [S1][S4][S9][S10].
- term_rate(t)[source]#
term(t): the benefit-driven termination indicator, 0 or 1.
Cover ceases when both the 疾病 and 災害 aggregate limits are exhausted [S9]. This is a decrement a death-benefit product does not have, and it is why the aggregate limit is a tracked state variable rather than a cap applied at the end. Identically 0 on every shipped model point’s expectation, which is a fact about the deterministic grid and not a reason to delete the machinery.
- adv_freq_mth()[source]#
f_adv: the monthly 先進医療 frequency per life [std], flat across ages.
0.00040 per life-year. No public exposure denominator was retrieved, so it carries no observed range. Zero when the rider is not attached.
- adv_pay_pp(t)[source]#
pay(t) = min(S_adv, LV - V(t)): the 技術料 reimbursed per 療養, before the top-up.
The 先進医療特約 reimburses the 技術料 in full, up to a lifetime aggregate of ¥20,000,000 — the ¥20,000,000 cap is uniform at every carrier that publishes one [S1][S3][S5][S6][S7][S9], one of the few genuinely market-wide parameters in the product — and the rider terminates on reaching it [S1][S5].
adv_sev= ¥150,000 is [std]. The sourced anchors: in 令和5年度, 144,282 patients received 先進医療 across 81 technologies; 先進医療A averaged about ¥67,700 per case, while 陽子線治療 ran to about ¥2,660,000 over 824 cases and 重粒子線治療 to about ¥3,140,000 over 462 cases [R9]. A count-weighted mean of those three is about ¥92,300, but the A count is dominated by high-volume fertility technologies whose exposure is not this rider’s, so the [std] severity sits about 1.6x above it. The spread the tag stands over is a factor of 46 between the 先進医療A average per case and 重粒子線治療’s [R9]; no per-technology minimum was extracted, so the true spread is wider still.Eligibility is tested at the treatment date, so a technology that has left the 厚生労働大臣’s 先進医療 list pays nothing, and 患者申出療養 is a different scheme and is excluded [S1][S5][S6] — both scope facts, not modelled states.
- adv_claim_pp(t)[source]#
adv_claim(t): the 先進医療 claim per in-force policy in month t.
f_adv x [pay(t) + min(0.10 pay(t), 500,000)]. The 10% / ¥500,000 cash top-up is the middle of three market shapes and is [std] composite [S1]; the reimbursement limb itself is contractual.
- adv_paid(t)[source]#
V(t): the 先進医療 ledger in JPY, per surviving policy, against
LV.V(t+1) = V(t) + f_adv pay(t). Only the reimbursed 技術料 counts against the lifetime cap; the cash top-up does not. Never approached on the expectation — about ¥60 a year on the anchor cell against a ¥20,000,000 cap — which is a fact about the deterministic grid, exactly as for the day ledgers.
- lump_claims_pp(t)[source]#
The number of 入院一時金 payments per in-force policy in month t.
One payment per hospitalization, cause-blind, with the same 181st-day reset as the main contract, subject to a 通算 count limit of 50 [S1] [std]. Zero unless the rider is attached.
- lump_count(t)[source]#
The 入院一時金 通算 count ledger, per surviving policy, against 50 payments.
Carried on the same basis as the day ledgers and for the same reason: a count weighted by the in-force probability would defer the 通算50回 limit indefinitely.
- waiver_inc_mth(t)[source]#
The monthly 保険料払込免除 incidence [std]; zero in the base run.
The base contractual waiver is disability-triggered — 高度障害状態 from any cause, or a listed 身体障害の状態 from an 不慮の事故 within 180 days [S1][S2][S10] — and its incidence is zero in every run of this model, not merely the base one, because 第三分野標準生命表2018 excludes 高度障害 [R5][REG-R20] so the incidence cannot be read out of the mortality basis, and no public Japanese 高度障害 incidence table was retrieved. A model that reads it out of the table under-counts the waiver.
Where the 特定三疾病保険料払込免除特則 is elected the module switches on at the notes’ suggested placeholder,
waiver_inc_mult x mort_rate(t)a year. Zero after the premium-paying period, when there is nothing left to waive.
- waived(t)[source]#
The probability the policy is on 保険料払込免除 at the start of month t.
An absorbing state,
u(t+1) = u(t) + (1 - u(t)) inc(t): the 特則 waives premiums for life once triggered [S1], so there is no recovery limb. Zero throughout the base run. Mortality and lapse are assumed independent of the waiver state [std], which is what lets the waived population be carried as a fraction of the in-force rather than as a separate decrement.
- pols_if(t)[source]#
l(t): the in-force probability at the start of policy month t.
1 at
t = 0, thenl(t+1) = l(t)(1 - q(t))(1 - w(t))(1 - term(t)). This is the weight on every cash flow of the sameresult_cf()row. Zero outside0 .. proj_len() - 1.
- pols_if_at(t, timing)[source]#
The in-force probability 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 deaths, before lapses — the notes’ processing order is mortality then lapse [std order], so this is the population lapses are taken from.
"AFT_DECR"l(t+1), the end-of-month state: what is left once the month’s deaths, lapses and benefit-driven termination are taken, and zero in the final projected month because the cover ends there.
- pols_death(t)[source]#
Expected deaths at the end of policy month t.
A pure liability release: the main contract pays nothing on death [S1][S4][S6] [S9][S10], so there is no
claims_deathanywhere in this model. A death benefit column on a 医療保険 is a benefit that does not exist.
- pols_lapse(t)[source]#
Expected lapses at the end of policy month t, taken from the survivors of mortality.
Pays nothing on the 終身払 anchor — see
cv_pp()— so on that model point this movespols_if()and nothing else.
- pols_term(t)[source]#
Expected benefit-driven terminations at the end of policy month t.
Cover ceases when both 通算 limbs are exhausted [S9]. Zero on every shipped model point’s expectation; see
term_rate().
- pols_maturity(t)[source]#
Policies whose cover ends at the scheduled end of the contract.
The library-wide meaning: the count whose cover ends because the contract reaches its scheduled end, whether or not anything is paid for it. Nothing is paid here — the 定期 flag simply runs out at its final renewal, with no maturity value [S7][S10], so there is no
claims(t, "MATURITY")limb — but the count is needed for the in-force roll-forward to close. On the 終身 chassis there is no scheduled end at all and this is zero even in the final month, because the projection stops where the mortality table does and everybody has already died.
- pols_payer(t)[source]#
The in-force probability actually paying premium in policy month t.
l(t) (1 - waived(t)). Equal topols_if()throughout the base run, where the waiver module is off.
Premium income at the start of policy month t, an inflow.
P l(t) (1 - waived(t)), and zero fromprem_end_month()on. Level and 無配当 with no repricing right on the 終身 chassis [S3][S6][S8]; on the 定期 flag the ten-year renewal reprices and the base run holds the issue rate flat [std].
- cv_pp(t)[source]#
The 解約返戻金 per policy at the end of month t; zero under 終身払 [S1][S6][S9].
Every carrier examined writes no surrender value during the premium-paying period, and under 終身払 that is every duration. Where a 短期払 is chosen a small value appears afterwards, standardized across two carriers at 10 x 入院給付金日額 [S1][S6] — the single route by which this chassis ever acquires one, and the reason
claims()carries a"LAPSE"kind at all.
- surg_ih_eff(t)[source]#
The in-hospital surgeries per hospitalization actually payable [std].
s_ihwhensurg_after_limitis true — the composite’s position, and the only positively stated treatment among the retrieved 約款 [S4]. With the switch reversed [S10], and surgeries assumed uniform over stay-days [std], the truncated day fraction1 - d_pay_capped / d_raw— 24.75% on the anchor cell — of in-hospital surgeries falls outside cover.s_ih = 0.35ands_op = 0.15are [std]: 患者調査 crosses 推計退院患者数 with 手術の有無, giving a public in-hospital surgery proportion, but those CSVs were not downloaded [R7][REG-R33]. Radiation therapy is inside these frequencies and not a separate stream: the composite folds 放射線治療 into 手術給付金 through the 放射線治療料 limb of the trigger, subject to the 60-day lockout every carrier imposes [S1][S2][S6][S9][S10]. Adding a separate 放射線治療給付金 double-counts.
- claims(t, kind=None)[source]#
Benefit outgo at the end of policy month t, by kind; the total when omitted.
"HOSP"入院給付金:
l(t) D i(t) [s_dis d_ben_dis(t) + s_acc d_ben_acc(t)]. A hospitalization starting in month t is resolved in full in month t [std] — its paid days, its benefit and its consumption of both day limits are all recognised at t — because the per-hospitalization limit is a property of the whole spell and a grid that split the spell would have to carry a partial-spell state."SURGERY"手術給付金:
l(t) i(t) D [surg_ih_eff(t) m_ih + s_op m_op], unlimited in count [S1][S3]. ¥38,750 per hospitalization on the anchor cell."ADVANCED"先進医療給付金:
l(t) adv_claim(t), reimbursement plus the [std] cash top-up."LUMP"入院一時金: ¥100,000 per hospitalization while the 通算50回 count lasts; zero unless the rider is attached.
"LAPSE"the surrender value paid on lapse — identically zero under 終身払, which is every shipped model point but one. The kind exists so that the zero is stated rather than left to inference: it is the product fact, and a non-zero lapse row imported from a cash-value model is one of the notes’ pitfalls.
- expense_maint_pp(t)[source]#
e(t): the maintenance expense per policy in month t [std].
¥250 a month inflating at 1.0% p.a. at each anniversary. Against a ¥2,100 premium that is 11.9% of premium on the anchor cell, and the level premium is fixed for life while the expense is not — which is why the notes rate expense inflation a first-order lever on a product this small-premium. No Japanese medical expense scale is public, so both the level and the inflation rate are standardizations.
- claim_expenses(t)[source]#
ec i(t) l(t): the claim handling expense on the month’s hospitalizations [std].
¥3,000 per hospitalization event, covering the day benefit and any surgery on the same spell, uninflated. A cells of its own, outside
expenses(): it is deducted explicitly innet_cf()and printed as its ownclaim_expensescolumn byresult_cf().
- expenses(t)[source]#
Acquisition and maintenance expense outgo in policy month t [std].
The acquisition expense of ¥20,000 per policy at
t = 0, then the inflating maintenance expense at the start of every month. Both levels are standardizations: no Japanese medical expense scale is public.The claim handling expense is not in here. It is
claim_expenses(), deducted on its own line innet_cf()and published in its own column, so thatexpensesmeans acquisition + maintenance in every model in the three libraries.technical-notes.mdprints the two separately throughout — the worked-example table, its three arithmetic traces and the policy-year-1 aggregate all carry both lines — so nothing in the notes has to be read as the combined figure.
- commissions(t)[source]#
Commission outgo in policy month t [std].
1.5 x the annualized premium at
t = 0— ¥37,800 on the anchor cell — then 3.0% of premium income from policy year 2, that is fromt = 12. Both levels are standardizations; no Japanese commission scale is public. With the acquisition expense they produce the characteristic new-business strain of ¥57,800 att = 0, recovered out of the margin in the early durations.
- net_cf(t)[source]#
net_cf(t): the net cash flow of policy month t, income positive.
Premiums less every benefit limb, less
expenses(), lessclaim_expenses(), less commission. The notes’ own sign, which is also the library-wide convention, so unlike the whole life and payout annuity models there is no outgo-positiveliability_cfcompanion to publish.The shape to expect is a deep month-0 strain — ¥57,800 of acquisition expense and initial commission against one month’s premium — and then thin positive margins that thin further with age: on the [std] basis annual incidence runs from 0.0466 at age 40 to 0.6452 at 90 and over and expected paid days from 0.709 to 15.16, so the level premium prefunds a morbidity cost that rises steeply for the whole of life. Year-1 claims on the anchor cell are 21.5% of year-1 premium.
- check_pols_roll_fwd_resid(t)[source]#
The in-force roll-forward residual in policy month t; zero everywhere.
pols_if(t) - pols_if(t+1) - deaths - lapses - terminations - maturities. The last two terms are what makes this product’s roll-forward different from a term assurance’s: cover can cease because the 通算 limits are exhausted, and the 定期 flag reaches its scheduled end at the final renewal. Without them the roll-forward would appear to lose lives with no cause.
- 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.
- check_agg_days_resid(t)[source]#
The 通算 day-ledger residual in policy month t; zero everywhere.
Two terms per limb. The first restates the recursion — each ledger advances by exactly the month’s ledger-consuming paid days, unweighted by
pols_if, which is the state-variable error this product invites. The second is the one that can actually fail:max(0, A(t+1) - LA), the overflow above the aggregate limit, which is non-zero the moment the room calculation ind_pay_dis()ord_pay_acc()is wrong.
- check_day_limits_resid(t)[source]#
The day-limit ordering residual in policy month t; zero everywhere.
The three limits act in a fixed order and this is the identity that says so, summed as three non-negative violations:
max(0, d_pay_capped(t) - L1)— the per-hospitalization limit is applied inside the stay expectation, so no expectation may exceed it. Capping the mean instead of capping each stay would show up here.max(0, d_pay(t) - d_ben(t))— the five-day minimum is an amount, not five days, so benefit days are never fewer than ledger days. A model that credited the floor to the 通算 ledger would fail this.max(0, d_pay_dis(t) - room_dis(t))and the same on the 災害 limb — no month may consume more days than its ledger has left.
- check_day_limits()[source]#
True when the three day limits act in the notes’ order in every projected month.
- check_adv_ledger_resid(t)[source]#
The 先進医療 ledger residual in policy month t; zero everywhere.
V(t+1) - V(t) - f_adv pay(t)plusmax(0, V(t+1) - LV), the overflow above the ¥20,000,000 lifetime cap. Only the reimbursed 技術料 counts against the cap — a model that also charged the cash top-up to it would exhaust the rider early.
- check_lump_ledger_resid(t)[source]#
The 入院一時金 count-ledger residual in policy month t; zero everywhere.
count(t+1) - count(t) - claims_pp(t)plus the overflow above the 通算50回 limit. Zero by construction where the rider is not attached.
- check_lump_ledger()[source]#
True when the 入院一時金 count ledger rolls forward and stays inside its limit.
- check_waiver_roll_fwd_resid(t)[source]#
The 保険料払込免除 state residual in policy month t; zero everywhere.
u(t+1) - u(t) - (1 - u(t)) inc(t)plusmax(0, u(t+1) - 1). The state is absorbing — the 特則 waives premiums for life [S1] — so a recovery limb appearing here would be modelling a contract term that does not exist.
- check_waiver_roll_fwd()[source]#
True when the premium waiver state rolls forward in every projected month.
- check_net_cf_resid(t)[source]#
The cash flow statement residual in policy month t; zero everywhere.
net_cf(), which adds the benefit limbs one by one exactly asresult_cf()prints them, lesspremiums - claims - expenses - claim_expenses - commissionswithclaims()summing over its own kinds. A benefit limb present in the total but missing from the printed statement, or counted twice, shows up here; so does a claim expense folded back intoexpenses()instead of standing on its own line.
- result_cf()[source]#
Result table of cash flows, indexed by policy month t.
pols_ifis the start-of-month in-force probability, which is the weight applied to every cash flow on the same row.net_cfcarries the notes’ own income-positive sign.expensesis acquisition + maintenance only and the claim handling expense stands beside it in its ownclaim_expensescolumn, which is what the two names mean library-wide.claims_lapseis a column of zeros by product design on every 終身払 model point — there is no surrender value — and is published rather than dropped; see the Space docstring.