The Data Space#
Input data shared by every by-policy projection.
The five input CSVs are read here, once per model, and referenced from
Projection as data. Projection is parameterized by
point_id, so each Projection[N] is a separate ItemSpace with its own cells cache;
if the readers lived there, every model point would re-read every file. Holding them in
an unparameterized Space reads each file once no matter how many policies are projected.
Inputs are external files: plain CSVs in the model folder’s parent directory,
products/assurance_vie_uc/, rather than data 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. 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
UC_FR_S folder without its parent’s CSVs produces a model that reads and then fails
on first evaluation.
input_dir() resolves the directory from _model.path.parent at run time, so the
model works wherever the repository is checked out. Each table has a filename Reference
and a reader Cells:
Reference |
Cells |
File |
|---|---|---|
model_point_file |
model_point_table() |
model_point_table.csv |
mort_table_file |
mort_table() |
mort_table.csv |
lapse_table_file |
lapse_table() |
lapse_table.csv |
plancher_rate_table_file |
plancher_rate_table() |
plancher_rate_table.csv |
uc_scenario_table_file |
uc_scenario_table() |
uc_scenario_table.csv |
Note what is not an input file. The charge rates — the premium charge, the UC management charge, the arbitrage fee, the euro credited rate — and every attribute of the garantie plancher except its tariff are model point columns rather than rate tables, because they are per-policy contractual and discretionary parameters rather than experience assumptions. Art. A. 132-8 requires charge maxima to be disclosed, not levels to be capped, and the retrieved contracts span 0.475% to 1.50% on the same charge line, so a single shipped rate card would assert a market fact that does not exist.
The plancher tariff is the exception and is a table, because it is the one price on this
product that an insurer publishes: plancher_rate_table.csv is Spirica’s own schedule,
an annual premium per 10,000 € of capital sous risque by attained age, ages 12 to 74.
It stops at 74 because the cover stops at 75; a model that extrapolated it would silently
invent a price, which is why plancher_rate() raises rather
than extends.
Cells Descriptions#
- input_dir()[source]#
The directory holding the input CSVs: the model folder’s parent.
Inputs are external files, not data stored inside the model, so the model folder is pure formulas. The path is resolved at run time from where the model was read, following
annuallife.TradLife_A.
- mort_table()[source]#
The base annual mortality rates by sex and age, from mort_table.csv.
A [std] proxy shaped like the INSEE national series, the only freely redistributable French mortality data. Art. A. 335-1 permits only a table homologated by ministerial arrete - by sex, on INSEE data for a non-annuity contract - or an undertaking’s own experience table certified by an independent actuary, so TH 00-02 / TF 00-02 are cited by name and article in the documents and are not shipped.
The table is anchored so that
Projection.mort_be_factortimes the male rate at age 65 reproduces the technical notes’ placeholderq = 1.20% p.a.exactly. That placeholder is not the mortality implied by the plancher tariff: 196 EUR a year per 10,000 EUR of capital sous risque at age 65 is 1.96% of the net amount at risk, and no insurer publishes the split between mortality, expense loading and margin, so the tariff cannot be decomposed. The model carries the tariff as a price and the mortality as an assumption, and the difference between them is the rider’s expected margin. Sorted on read, becauseProjection.mort_rateindexes into it.
- lapse_table()[source]#
The base annual total-surrender rates by policy year, from lapse_table.csv.
2% in year 1, 4% in years 2 to 4, 6% in years 5 to 7, 12% in year 8 and 6% thereafter. A [std] construction: no public French persistency study was retrieved, and no insurer document gives a lapse table.
The year-8 spike is the one shape that is not arbitrary. Art. 125-0 A CGI makes the eighth anniversary the point at which the withholding rate falls to 7.5% and the 4,600 EUR / 9,200 EUR annual abattement opens, and eight years is the recommended holding period printed in both retrieved key-information documents. A model with no duration-8 spike has ignored the single strongest driver of French surrender timing.
- plancher_rate_table()[source]#
The garantie plancher tariff by attained age, from plancher_rate_table.csv.
An annual premium per 10,000 EUR of capital sous risque, ages 12 to 74: Spirica’s published schedule, the only tariff retrieved together with an explicit premium formula,
Pr = K x (PA / 10 000) x 1/52. It is a price, not a decrement, and it is the only sourced quantitative table this model ships.The table stops at 74 because the cover stops at the 75th birthday.
Projection.plancher_ratereturns zero once the cover has ceased and raises if an attained age inside the cover falls outside the table, rather than extrapolating: extending the cessation age past 75 needs a tariff the sources do not contain.
- uc_scenario_table()[source]#
The UC liquidation-value scenarios, from uc_scenario_table.csv.
Each row is a segment of one scenario: a monthly return applying from
from_monthtoto_monthinclusive. Both bounds are written in the projection’s own 0-based policy months, so the first segment of every scenario opens atfrom_month = 0andProjection.uc_return_mthcompares them againsttdirectly. Three scenarios ship, all [std]:stress_yr1, the worked example’s path of +1.00% a month for six months then -5.00% a month for six;base_490, a deterministic 4.90% a year, the five-year average performance of UC supports net of fund charges; andbear_5pct, a sustained -5.00% a year that holds the plancher in the money.The path is exogenous and the base run is deterministic, which understates the plancher cost:
E[max(0, F - AV)]exceedsmax(0, F - E[AV]), so a stochastic or scenario-set run is not an enhancement here but the only way to price the rider. Fund-level recurring costs, anencours-weighted 1.60% a year, are inside these returns and accrue to the fund manager rather than to the insurer. Sorted on read, becauseProjection.uc_return_mthindexes into it.