The Data Space#
Input data shared by every by-contract projection.
The six 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 contracts are projected.
Inputs are external files: plain CSVs in the model folder’s parent directory,
products/deferred_income_annuity/, 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
DIA_US_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 |
premium_schedule_file |
premium_schedule_table() |
premium_schedule.csv |
mort_table_file |
mort_table() |
mort_table.csv |
improvement_scale_file |
improvement_scale() |
improvement_scale.csv |
payout_factor_file |
payout_factor_table() |
payout_factor_table.csv |
rop_factor_file |
rop_factor_table() |
rop_factor_table.csv |
Why the premium schedule is a separate table. A DIA is a flexible-premium contract:
“any number of premiums during the deferral period” [S2][S3][S4][R13], each buying its
own paid-up income slice at the purchase rate then in force. A fixed set of premium
columns on the model point table would cap that number, so the schedule is a long table
keyed by point_id with one row per slice, and
premium_by_mth() collapses it to a
month-to-amount mapping once per contract.
The two factor tables are the pricing kernel’s data, and both are [std]. No
purchase-rate table was obtained and none is published — the Compact expressly relieves
the insurer of disclosing the deferral-period mortality and interest basis
[R13 §1.B(1)(a)] — so payout_factor_table.csv and rop_factor_table.csv carry the
technical notes’ illustrative factors, marked as such in their provenance columns.
A model point can bypass them entirely by setting factor_basis = "formula", which
computes equation (2) and the equation (3) mid-band approximation from the shipped
mortality table instead.
The mortality table and the improvement scale are keyed by (age, sex). They are
separate files on purpose: the technical notes prescribe the 2012 IAM Basic table
projected generationally with Projection Scale G2 [R9][REG-R59], two distinct
objects with distinct provenance, and neither may be embedded in the model — the shipped
tables are illustrative [std] stand-ins, the mortality table being the one that
reproduces the notes’ worked-example survival anchors. To swap in a licensed basis,
replace mort_table.csv with a same-schema file, or point mort_table_file at a
different name, then clear the cache. No formula changes.
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.
The premium schedules of every model point, from premium_schedule.csv.
Long format, one row per premium slice, keyed by
point_id- deliberately not indexed, so that selecting a contract’s rows returns a DataFrame whether it has one slice or many.
- improvement_scale()[source]#
The generational improvement scale by age and sex, from improvement_scale.csv.