How we know the engine is right

Validation

A model is only as good as the tests it has survived. Every check below has an answer that does not come from us: a closed-form actuarial identity, a published statistic, or an invariant the mathematics requires. Nothing here is a test of our output against our own output.

55 / 55
checks passing

The suite runs against two independently written engines: the browser engine that powers the Valuation Lab on this site, and the reporting engine that produces the specimen Survey Report. They share no code. Where both are asked the same question they must give the same answer, which is itself one of the strongest tests available.

Closed-form identities

Where actuarial mathematics gives an exact answer, the engine must reproduce it exactly. An annuity-certain must equal (1 − vn)/d. Under a constant force of mortality the life annuity must equal 1/(1 − vp). At zero interest it must equal curtate life expectancy plus one. These are not approximations and the engine agrees to nine decimal places.

Published benchmarks

Mortality is calibrated so that period life expectancy at 65 reproduces the published Belgian figures rather than a convenient shape. The statutory minimum return and its 2025 step are checked against the Law of 18 December 2015.

Invariants and behaviour

The obligation must fall as the discount rate rises, rise with salary growth, rise with longevity improvement, and fall when retirement is deferred. Components must sum to the total, and 612 individual valuations must add to the portfolio figure.

Every check, and what it is measured against

CheckExpected value comes from EngineExpectedResult
1. Closed-form identities
Annuity-certain 40 yrs at 2.00%a-due(n) = (1 - v^n)/d27.902627.9026PASS
Annuity-certain 40 yrs at 2.00%a-due(n) = (1 - v^n)/d27.902627.9026PASS
Annuity-certain 40 yrs at 4.45%a-due(n) = (1 - v^n)/d19.358419.3584PASS
Annuity-certain 40 yrs at 4.45%a-due(n) = (1 - v^n)/d19.358419.3584PASS
Annuity-certain 40 yrs at 8.00%a-due(n) = (1 - v^n)/d12.878612.8786PASS
Annuity-certain 40 yrs at 8.00%a-due(n) = (1 - v^n)/d12.878612.8786PASS
Constant q=0.02 at 4.00%a-due = 1/(1 - v*p)17.333317.3333PASS
Constant q=0.02 at 4.00%a-due = 1/(1 - v*p)17.333317.3333PASS
Constant q=0.05 at 4.45%a-due = 1/(1 - v*p)11.052911.0529PASS
Constant q=0.05 at 4.45%a-due = 1/(1 - v*p)11.052911.0529PASS
Constant q=0.10 at 6.00%a-due = 1/(1 - v*p)6.6256.625PASS
Constant q=0.10 at 6.00%a-due = 1/(1 - v*p)6.6256.625PASS
Duration of a single 20-yr paymentD_mod = n/(1+i)19.147919.1479PASS
Duration of a single 20-yr paymentD_mod = n/(1+i)19.147919.1479PASS
Zero interest: a-due(65) = e(65) + 1identity at i = 03.967843.96784PASS
Zero interest: a-due(65) = e(65) + 1identity at i = 03.967843.96784PASS
2. Engine invariants
100bp-bump duration within 3% of analytic derivativeconvexity is second order21.441721.0595PASS
100bp-bump duration within 4% of analytic derivativeconvexity is second order22.822122.8221PASS
25bp move predicted by duration to within 5%first-order Taylor, convexity excluded3.77217noPASS
Accrued + future service = full projected PVPUC attribution identity89,211,21189,211,211PASS
Active + deferred + pensioner = total DBOadditivity46,990,33046,990,330PASS
Active + deferred + retiree = total DBOadditivity9,917,9789,917,978PASS
Cohort mode and flat-age mode give different answersthe switch actually does somethingyesyesPASS
Cohort mode assigns retirement age by year of birthstatutory schedule 65 / 66 / 67yesyesPASS
DBO decreasing in the discount ratemonotonicityyesyesPASS
DBO increasing in salary growthmonotonicityyesyesPASS
DBO strictly decreasing in the discount ratemonotonicityyesyesPASS
DBO strictly increasing in salary growthmonotonicityyesyesPASS
Flat-age 66 and 67 are not the same numberguards against a vacuous comparisonyesyesPASS
Later retirement reduces the DBO (flat-age mode)directionalyesyesPASS
Mortality improvement increases the DBOdirectionalyesyesPASS
Mortality improvement increases the DBOdirectionalyesyesPASS
Sum of 612 individual valuations = portfoliono cross-member interaction46,990,33046,990,330PASS
3. Published benchmarks
Life expectancy at 65, femaleStatbel period tables21.921.9PASS
Life expectancy at 65, female (Statbel ~21.9)Statbel period tables21.899921.9PASS
Life expectancy at 65, maleStatbel period tables18.618.6PASS
Life expectancy at 65, male (Statbel ~18.6)Statbel period tables18.60118.6PASS
Statutory minimum return from 1 Jan 2025WAP art.24, 2025 step2.52.5PASS
Statutory minimum return from 1 Jan 2025WAP art.24, 2025 step2.52.5PASS
Statutory minimum return pre-2025WAP art.241.751.75PASS
Statutory minimum return pre-2025WAP art.24 / Law 18 Dec 20151.751.75PASS
3b. Real published valuation
Convexity signature matches within 2%same disclosure, 25bp bump1.077081.07433PASS
Downward move exceeds upward, as the published report showsconvexity directionyesyesPASS
Implied duration matches Mercer's disclosure within 10%Mercer, Cayman Islands Government, IPSAS 39, 202120.815620.4732PASS
4. Duration matching
D-A: curve rate read at 29.3 yrseuro AA curve interpolation4.634.63PASS
D-B: curve rate read at 21.2 yrseuro AA curve interpolation4.593294.59328PASS
D-C: curve rate read at 12.2 yrseuro AA curve interpolation4.329134.32915PASS
Longer duration reads a higher rate (A > B > C)upward-sloping curveyesyesPASS
4. Statutory guarantee mechanism
Guarantee binds when the floor exceeds the contract rateemployer obligation, not a discount-rate testyesyesPASS
Guarantee does not bind when the contract pays above the flooremployer obligationnonoPASS
Guaranteed account splits generations by calendar yearWAP art.24, step 1 Jan 202515,41115,411PASS
5. Conformity checker
Conforming years reported as conformingno false positivesyesyesPASS
Contribution shortfall detectedseeded error 1yesyesPASS
Guarantee under-credit detectedseeded error 2yesyesPASS
Under-credit flagged in 2025, the year the floor steppedWAP art.24 stepyesyesPASS

Two findings the suite caught that reading the code did not

Mortality seven times too heavy

An early build of the reporting engine used a mortality law that implied an 8.7% chance of death at age 65, against a Belgian reality of about 1.2%. Life expectancy at 65 came out at 6.6 years instead of 18.6. Because pensioners were assumed to die a decade early, every annuity factor and the whole obligation were understated. The published-benchmark check found it immediately; no amount of reading the formula would have.

The guarantee split off by one year

The browser engine decided which contributions earn the 2.50% statutory floor by counting years backwards rather than by calendar year, which credited the new rate to a 2024 generation that is entitled to 1.75%. It is a small sum, and it sat inside the exact mechanism this whole review turns on. The generation test now pins it to the 1 January 2025 step.

We are showing you our own defects on purpose. Both were found before award, by tests we wrote against ourselves, and both are fixed and re-tested. A contractor who tells you their model has never been wrong is telling you they have not looked. What matters is whether the checking is real and whether it runs again every time the model changes.

The suite runs again every time the model changes

This is not a one-off exercise for a proposal. The validation suite ships with the engine, and it is how the Embassy's own team can satisfy itself in later years that nothing has drifted.

Re-run it yourself

Two commands, no licence, no dependency on us. The browser engine's suite runs with node js/validate.mjs; the reporting engine's with python validate.py. Each prints a pass or fail line per check and exits non-zero if anything breaks.

Change one assumption a year

Next year's review is mostly the same plan with a new census, a new curve reading and a year of ledger. The assumption file and the census are the inputs that change. The method, the tests and the report architecture do not.

The tests are the handover

Documentation goes stale, tests do not. If a future change breaks the annuity identity or moves life expectancy away from the published figure, the suite says so before anyone signs a report.