The Data Space#
Input data shared by every by-policy projection.
The four 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_euro/, 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
Euro_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 |
fin_rate_file |
fin_rate_table() |
fin_rate_table.csv |
Note what is not in a file. The crediting rule that actually drives this product —
the target taux servi, the dotation and release policy, the FIFO release order, the
expense loadings, the dynamic-surrender coefficients — lives in model point columns and
Projection References rather than in a rate table, and that is not an oversight.
None of it is published. Only the outer bounds of the discretion are public: at
least 85% of the compte financier and the art. A132-11 technical share must reach
policyholders, and the PPB must be released within eight years. Between those bounds no
insurer publishes its own rule, so every value is a standardization, and putting them
where a reader trips over them is better than filing them in a table that looks like
data.
The three rate tables each carry a provenance column that says in words what the
numbers are. That column is never read by a formula; it is there so that a file lifted
out of this directory still says what it is.
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.
- model_point_table()[source]#
The model point table, read from model_point_table.csv.
Eleven model points. Point 1 is the notes’ worked example; the rest exercise the variants the notes discuss - the garantie brute floor, an aggressive target rate, a paid-up contract, a nil PPB, a young vintage profile, the low and high financial scenarios, a small new-business cell with an entry charge, a drawdown cell and a grouped cell carrying 250 policies.
- mort_table()[source]#
The base annual mortality rates by sex and age, from mort_table.csv.
A [std] proxy shaped like French population mortality. The statutory tables - TH00-02/TF00-02 and TGH05/TGF05, annexed to the arrêté du 1er août 2006 - are cited in the documents but not redistributed here, and the Institut des actuaires’ certified experience tables are not public either, so no permitted insured basis can be reproduced. INSEE population data is the only freely redistributable French mortality source, and this is a Makeham curve fitted to its shape.
Projection.mort_be_factorcarries the allowance for population mortality being heavier than insured experience; the table is anchored so that the two together give the notes’ placeholderq = 0.0060at male age 60 exactly. Sorted on read, becauseProjection.mort_rateindexes into it.
- lapse_table()[source]#
The base annual surrender rates by completed policy duration, from lapse_table.csv.
4% at durations 1-7, 8% at duration 8, 5% at durations 9 and beyond. The duration-8 step is the tax threshold rather than a behavioural guess: the reduced 7.5% rate and the EUR 4 600 / EUR 9 200 annual allowance both switch on at eight years, and a French savings projection with no surrender step there has ignored the single strongest driver of French partial-surrender timing. The levels are [std] - the ACPR publishes aggregate surrender flows with no split by duration, age or vintage - and the dynamic term layered on them in
Projection.lapse_ratematters more than the levels do.
- fin_rate_table()[source]#
The financial scenario paths, from fin_rate_table.csv.
Three scenarios by projection year: the fund’s taux de rendement de l’actif
r_finand the market reference rateref_ratethe dynamic surrender term keys off. The key column isy, the model’s own projection year, 0-based:y = 0is the first projected year and the file runs 0 to 39. It is namedyand nottbecausetis a policy month everywhere else in this model - the table is an annual path andProjection.r_finreads it atproj_year(t) = t // 12. The base path runs 3.30% down to 2.30% over twelve years and stays there, anchored to the ACPR’s observed asset return - 2.8% in 2025, 2.5% in 2024, half of undertakings between 2.4% and 3.3% - and to the reinvestment picture behind it.ref_rateis 2.20% throughout, the 2025 average Livret A rate. These are [std] scenarios, not forecasts.