Products Insurance and reinsurance
Reserving and ESG
Claims reserving and economic scenario generation
Reserve ranges and scenario sets that rerun to the same bits.
Reserving and ESG covers the actuarial engines behind technical provisions. GraphAtlas runs chain ladder and Mack, bootstrap and Bornhuetter-Ferguson, builds the EIOPA risk-free curve under the rule in force on the day, and generates market-consistent scenarios with every random draw fixed, so a scenario set reproduces exactly on any machine.
Try the calculation Request a walkthrough
- Verification
- 38 statements. 8 proved, 0 certified, 30 tested.
- Regime
- Directive 2009/138/EC, Articles 75 to 86
- Set by
-
- European Insurance and Occupational Pensions Authority
- European Commission and the European Supervisory Authorities
- Built for
-
- Reserving actuaries
- Insurance risk
- Investment and ALM teams
- Version
- 3.9
Try it
Run it on published data
Choose the RAA triangle or paste your own, and read the reserve and the standard error of Mack. Then set a date on each side of 30 January 2027 and watch the discount curve change its rule. The two rules agree up to the first smoothing point and part after it. Fig. 2 puts a value on the payments of Fig. 1 under both.
Fig. 1 A run-off triangle, its reserve and the standard error of Mack
Verifying receipt
The triangle
The amounts
Each amount is the total for its origin year up to that development year.
Read 10 origin years and 55 amounts.
Each line is one amount shorter than the line above it. Separate amounts with spaces, tabs, commas or semicolons, and do not put a comma inside an amount.
The reserve is 52,135. The standard error of Mack is 26,909, which is 51.6% of the reserve.
| Origin year | Seen so far | Ultimate | Reserve | Share of the largest reserve | Standard error |
|---|---|---|---|---|---|
| 1981 | 18,834 | 18,834 | 0 | 0 | |
| 1982 | 16,704 | 16,858 | 154 | 206 | |
| 1983 | 23,466 | 24,083 | 617 | 623 | |
| 1984 | 27,067 | 28,703 | 1,636 | 747 | |
| 1985 | 26,180 | 28,927 | 2,747 | 1,469 | |
| 1986 | 15,852 | 19,501 | 3,649 | 2,002 | |
| 1987 | 12,314 | 17,749 | 5,435 | 2,209 | |
| 1988 | 13,112 | 24,019 | 10,907 | 5,358 | |
| 1989 | 5,395 | 16,045 | 10,650 | 6,333 | |
| 1990 | 2,063 | 18,402 | 16,339 | 24,566 | |
| All years | 160,987 | 213,122 | 52,135 | 26,909not the sum of the years |
The years share the same factors, so the error of all years together is not the sum of the errors of the years.
Development factors
- 1 to 2
- 2.999
- 2 to 3
- 1.624
- 3 to 4
- 1.271
- 4 to 5
- 1.172
- 5 to 6
- 1.113
- 6 to 7
- 1.042
- 7 to 8
- 1.033
- 8 to 9
- 1.017
- 9 to 10
- 1.009
Each factor is the sum of the amounts in one development year over the sum of the same origin years a year before.
Payments to come
| Year | Paid | Of the reserve | Size |
|---|---|---|---|
| 1 | 17,501 | 34% | |
| 2 | 13,069 | 59% | |
| 3 | 8,871 | 76% | |
| 4 | 5,725 | 87% | |
| 5 | 3,529 | 93% | |
| 6 | 1,760 | 97% | |
| 7 | 1,061 | 99% | |
| 8 | 450 | 100% | |
| 9 | 168 | 100% |
The share is what has been paid by the end of that year. Fig. 2 puts a value on these payments.
Against the vignette
All 8 lines agree.
The vignette of the ChainLadder package, 18 February 2026 prints these figures for this triangle. Each is compared to the digits it prints.
| Figure | Printed | Here | Result |
|---|---|---|---|
| Latest, all yearsPrinted 160,987 | 160,987 | 160,987 | Agrees |
| Ultimate, all yearsPrinted 213,122.23 | 213,122.23 | 213,122.23 | Agrees |
| Reserve, all yearsPrinted 52,135.23 | 52,135.23 | 52,135.23 | Agrees |
| Standard error, all yearsPrinted 26,909.01 | 26,909.01 | 26,909.01 | Agrees |
| Development factors, to three decimalsPrinted 9 figures | 9 figures | 9 agree | Agrees |
| Ultimate of each year, to the unitPrinted 10 figures | 10 figures | 10 agree | Agrees |
| Reserve of each year, to a tenthPrinted 10 figures | 10 figures | 10 agree | Agrees |
| Standard error of each year, to a tenthPrinted 10 figures | 10 figures | 10 agree | Agrees |
The completed square
The factors fill the lower right of the triangle. Amounts in italics are projected, and the others are what was read, as running totals.
| Origin year | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1981 | 5,012 | 8,269 | 10,907 | 11,805 | 13,539 | 16,181 | 18,009 | 18,608 | 18,662 | 18,834 |
| 1982 | 106 | 4,285 | 5,396 | 10,666 | 13,782 | 15,599 | 15,496 | 16,169 | 16,704 | 16,858 |
| 1983 | 3,410 | 8,992 | 13,873 | 16,141 | 18,735 | 22,214 | 22,863 | 23,466 | 23,863 | 24,083 |
| 1984 | 5,655 | 11,555 | 15,766 | 21,266 | 23,425 | 26,083 | 27,067 | 27,967 | 28,441 | 28,703 |
| 1985 | 1,092 | 9,565 | 15,836 | 22,169 | 25,955 | 26,180 | 27,278 | 28,185 | 28,663 | 28,927 |
| 1986 | 1,513 | 6,445 | 11,702 | 12,935 | 15,852 | 17,649 | 18,389 | 19,001 | 19,323 | 19,501 |
| 1987 | 557 | 4,020 | 10,946 | 12,314 | 14,428 | 16,064 | 16,738 | 17,294 | 17,587 | 17,749 |
| 1988 | 1,351 | 6,947 | 13,112 | 16,664 | 19,525 | 21,738 | 22,650 | 23,403 | 23,800 | 24,019 |
| 1989 | 3,133 | 5,395 | 8,759 | 11,132 | 13,043 | 14,521 | 15,130 | 15,634 | 15,898 | 16,045 |
| 1990 | 2,063 | 6,188 | 10,046 | 12,767 | 14,959 | 16,655 | 17,353 | 17,931 | 18,234 | 18,402 |
Fig. 2 A discount curve under the two rules of the Solvency II framework
Verifying receipt
The day and the rule
Try and , the last day before the amended framework applies and the first day of it.
The rates
Read 20 rates, from year 1 to year 20.
The terms
The closed form follows the rates up to this year and extrapolates after it. Smith-Wilson fits every rate that is given.
Table 4 starts in 2027, so there is nothing to phase in on an earlier day.
Rule applied
Smith-Wilson
30 Oct 2026 is before 30 Jan 2027, the day the amended framework starts to apply, so the rule in force is the Smith-Wilson fit.
Alpha is 0.123761. It is the lowest value of six decimals, and not below 0.05, that brings the forward rate within one basis point of the ultimate rate by year 60.
Zero rate at 40 years
2.787%
Smith-Wilson applies. The closed form gives 2.728%, which is 5.9 bp lower.
- Smith-Wilson, applied
- Closed form
- A maturity that was given
- Zero rate
- 2.787%
- Other rule
- 2.728%
- Gap
- +5.9 bp
- Discount
- 0.33298
- Forward
- 4.067%
Smith-Wilson is above the closed form by at most 5.9 bp, at 42 years. At 150 years the gap is +2.1 bp. The gap is Smith-Wilson less the closed form. The discount is what one unit due at that year is worth now, and the forward is the rate for the year before it.
Against the published table
Table 29 of the numerical illustration has 242 numbers, the intensity and the rate at each of 121 maturities. The largest difference from this curve is 0.0000058 percentage points, at 55 years. The table prints five decimals.
The payments of Fig. 1
- Added up
- 52,135
- On this curve
- 51,584
- On the other rule
- 51,584
On this curve the payments are worth 51,584, which is 98.9% of the 52,135 that they add up to. They fall in years 1 to 9, where the two curves are the same to a tenth of a basis point, so the other rule gives the same value.
Zero rates at selected years
| Years | Smith-Wilsonapplied | Closed form | Gap |
|---|---|---|---|
| 1 | 0.200% | 0.200% | 0.0 bp |
| 2 | 0.225% | 0.225% | 0.0 bp |
| 3 | 0.300% | 0.300% | 0.0 bp |
| 5 | 0.552% | 0.552% | 0.0 bp |
| 7 | 0.860% | 0.860% | 0.0 bp |
| 10 | 1.306% | 1.306% | 0.0 bp |
| 15 | 1.768% | 1.768% | 0.0 bp |
| 20 | 1.960% | 1.960% | 0.0 bp |
| 25 | 2.168% | 2.143% | +2.5 bp |
| 30 | 2.403% | 2.357% | +4.6 bp |
| 40 | 2.787% | 2.728% | +5.9 bp |
| 50 | 3.054% | 2.998% | +5.6 bp |
| 60 | 3.241% | 3.191% | +5.0 bp |
| 80 | 3.479% | 3.440% | +3.9 bp |
| 100 | 3.623% | 3.592% | +3.1 bp |
| 120 | 3.719% | 3.693% | +2.6 bp |
| 150 | 3.815% | 3.794% | +2.1 bp |
Inputs and outputs
What goes in. What comes out
The plate runs a slice of the engine. This is the whole shape of it.
What goes in
- Triangle
- The amounts of each origin year, as running totals or as the amounts of each development year, from two to forty origin years. The plate reads a sheet that was pasted.
- Rates
- The par swap rates or the zero coupon rates of the currency, each with its maturity in whole years. The plate takes up to thirty, typed or pasted.
- Terms
- The ultimate forward rate, the first smoothing point, the currency and whether the undertaking phases in. All four are yours to set.
- Valuation date
- The day that the curve is for. It picks the rule, because the framework changes on 30 January 2027, and a rule can also be chosen whatever the day.
What comes out
- Chain ladder
- The development factors, the ultimate and the reserve of each origin year, and what the factors say will be paid in each year to come.
- Standard error of Mack
- For each origin year and for all years together, or the reason that it cannot be given.
- Discount curve
- The annual zero rate for every year from 1 to 150 under the rule in force, the curve of the other rule beside it, and the gap in basis points.
- Present value
- What a stream of payments is worth on the curve, such as the payments that the chain ladder expects.
- Receipts
- A hash of the inputs, the rule and every number, one for the reserve and one for the curve. Anyone can recompute them.
What the plate covers
In the plate above
- The chain ladder and the standard error of Mack, on two published triangles or on your own, with the figures that the vignette of the ChainLadder package prints beside them.
- The Smith-Wilson fit with its search for the convergence parameter, and the closed form from the first smoothing point, on the swap rates of the numerical illustration of EIOPA or on yours.
- The rule in force on a day, with the change of 30 January 2027, the convergence parameters of the two groups of currencies and the phasing in of Table 4.
- Table 29 of the numerical illustration, compared with the fit number by number.
- The two curves side by side and the gap between them, and the value of the payments of the first figure under each.
In the licensed engine, not the plate
- The rest of the product. The bootstrap of the residuals, Bornhuetter-Ferguson, the other averages of the link ratios, the tail factor and the economic scenario generators with their fixed seeds are not here.
- The choice of the instruments and of the first smoothing point from the market, the credit risk adjustment, the volatility adjustment, the matching adjustment and the symmetric adjustment.
- The ultimate forward rate of each year. Annex C derives it from real rates and inflation targets that the plate does not read. The steps of Annex C are in the engine and are tested, and the plate takes the rate as a number.
- Everything else that technical provisions need. The risk margin, the choice between methods and the judgement of the actuary are not arithmetic, and a reserve is not one number from one method.
Clause map
Every rule has an address
Each row names the clause, the function that carries it and the statements that check it. A test opens each file and confirms the function exists.
| Reference | Rule | Carried by | Checked by |
|---|---|---|---|
| ChainLadder vignette, the basic idea of the chain ladder | A development factor is the total of the amounts of one development year over the total of the same origin years a year before. It is a mean of the ratios between neighbouring amounts, with the earlier amount as the weight. | development src/ | Proved RS-01 Tested RS-11 |
| ChainLadder vignette, the basic idea of the chain ladder | The latest amount of each open origin year is carried forward with the factors still to come. That gives its ultimate, and the ultimate less the latest amount is its reserve. The RAA triangle gives a reserve of 52,135.23, and what is to be paid in each year to come adds up to it. | chain src/ | Proved RS-02 Tested RS-12 Tested RS-13 Tested RS-14 |
| ChainLadder vignette, the Mack chain ladder | The standard error of the reserve of each origin year, and of all years together, comes from the variance of the ratios of each development year. The variance of the last year rests on one ratio, so it is carried on from the two before it, as the option of the package that follows Mack does. The RAA triangle gives 26,909.01 for the whole reserve. | mack src/ | Proved RS-03 Tested RS-15 Tested RS-16 Tested RS-17 |
| Rule of this product, the triangle | A triangle has from two to forty origin years, and each has one amount fewer than the year before. Every amount is finite. Every development year that has a successor adds up to more than zero, or no factor could be found. | check src/ | Tested RS-09 |
| Rule of this product, running totals | The amounts of each development year are added from left to right into running totals, and taken back out of them. The amounts of Taylor and Ashe give the running totals that the vignette prints. | cumulate src/ | Tested RS-10 |
| Rule of this product, a triangle from a sheet | A triangle copied from a sheet is read with tabs, spaces, commas or semicolons between the amounts. Cells that are empty or say NA at the end of a line are dropped, and anything that is not an amount is named with its line. | parse src/ | Tested RS-18 |
| Rule of this product, a reserving run | A run takes running totals or the amounts of each year, gives the chain ladder and the formula of Mack, and says why when the formula cannot be applied. It shares no array with its input. | reserving src/ | Tested RS-19 |
| Receipt of a reserving run | The receipt covers the amounts, the basis, the factors, what is to be paid and every error, with nothing where there is no error. It is the same for the same amounts and changes with the last bit of any amount. | reserving src/ | Tested RS-19 |
| Directive (EU) 2025/2, Article 4(1) | The amended framework applies from 30 January 2027. The engine builds the Smith-Wilson curve up to 29 January 2027 and the closed form from 30 January 2027, and it never goes back to the old rule on a later day. | rule src/ | Tested RS-22 |
| EIOPA-BoS-26/198, paragraph 8.1.5 and Table 4, and Article 77a of Directive 2009/138/EC | The convergence parameter of the closed form is 0.11 for every currency but the Swedish krona and 0.4 for the krona. An undertaking that phases in follows Table 4 from 2027 to 2032. Every value leaves at least 77.5 per cent of the weight on the ultimate forward rate 40 years past the first smoothing point. | alpha src/ | Tested RS-23 |
| EIOPA-BoS-26/198, paragraphs 8.5.5 to 8.5.8 | The weight of the last liquid forward rate at a horizon h is (1 − e^(−a×h)) / (a×h), which is one at the start and falls towards zero. | convergence src/ | Proved RS-05 Tested RS-32 |
| EIOPA-BoS-26/198, paragraphs 8.5.5 to 8.5.8 | The forward rate at each horizon is the ultimate forward rate plus the weight times the way back to the last liquid forward rate, so it lies between the two the whole way. | forward src/ | Proved RS-06 |
| EIOPA-BoS-26/198, paragraphs 8.5.5 to 8.5.8 | The last liquid forward rate is a weighted mean of the forwards from the first smoothing point. The zero rate at each horizon is the mean of the zero rate at the point and the forward, weighted by the years that each covers. | extrapolate src/ | Proved RS-07 Tested RS-33 Tested RS-34 Tested RS-38 |
| EIOPA-BoS-26/198, Annex C, paragraph C.2.2 | The ultimate forward rate of a year is the rate of the year before, or that rate plus or less 15 basis points. It moves when the rate before the limit is at least 15 basis points away from the rate of the year before. | limit src/ | Proved RS-04 Tested RS-24 |
| EIOPA-BoS-26/198, Annex C, paragraph C.3.6 | The expected real rate is rounded to whole steps of five basis points, upwards when it is below the rounded rate of the year before and downwards when it is not. | round src/ | Proved RS-08 Tested RS-25 |
| EIOPA-BoS-26/198, Annex C, paragraph C.4.1 | An inflation target falls in one of four buckets, and a target at or below one per cent falls in the lowest. The bucket gives the expected inflation, which with the rounded real rate makes the rate before the limit. | expected src/ | Tested RS-25 |
| EIOPA-BoS-26/198, Annex D, paragraphs D.1 to D.9 | The zero rates that par swap rates imply are found one maturity after the next, with a constant forward rate between two maturities that are not a year apart. Every swap is priced at par, and zero coupon rates give back the rate at each maturity. | bootstrap src/ | Tested RS-31 |
| EIOPA-BoS-25-471, paragraph 9.7.1 | The function of Wilson is H(u, v) = a×min(u, v) − e^(−a×max(u, v)) × sinh(a×min(u, v)), the same from either side. It is written so that a product of an exponential and a hyperbolic sine cannot overflow. | wilson src/ | Tested RS-26 |
| EIOPA-BoS-25-471, paragraphs 9.8 to 9.13 | The curve is fixed by a linear system in the prices of the instruments, built from the function of Wilson. The fit prices every instrument at its own price, and a unit paid at the start is worth one. | sw src/ | Tested RS-27 Tested RS-28 |
| EIOPA-BoS-25-471, paragraphs 9.4.1, 9.4.2, 9.14.4 and 9.14.5 | The convergence parameter is the lowest value of six decimals, not below 0.05, that brings the forward rate within one basis point of the ultimate rate at the convergence point. That point is 40 years past the last liquid point and never before year 60. | sw src/ | Tested RS-20 Tested RS-21 Tested RS-29 |
| EIOPA-BoS-25-471, Annex D, Table 29 | The curve lists the intensity, the annual rate and the forward rate for each year to 150. On the twenty swap rates of the illustration it gives every one of the 242 numbers of Table 29 to the fifth decimal, and prices each swap at par. | sw src/ | Tested RS-20 Tested RS-30 |
| Rule of this product, one curve | The date picks the rule, and a choice overrides it and says so. The two rules give the same rates where the swaps fix the curve, and different ones after it. | curve src/ | Tested RS-35 |
| Rule of this product, what a payment is worth | A payment at the end of year t is discounted by one over one plus the rate of that year, to the power t. Payments add up, and a payment after the last year of the curve, or one that is not a number, is refused. | present src/ | Tested RS-36 |
| Receipt of a curve | The receipt covers every input, the rule that was applied and how it was chosen, the convergence parameter and the rate of every year. It is the same for the same inputs and changes when any input changes. | curve src/ | Tested RS-37 |
| Rule of this product, the same bits everywhere | The exponential and the logarithm are written out, so that a receipt made in one engine is the same in every other. They stay within three units in the last place of the platform library. | exp src/ | Tested KE-01 |
Verification
What we claim, and how it is checked
Every statement is registered, and each says which level of assurance it has earned. The ladder is explained on the verification page.
Proved
True for every input.
- RS-01
For positive amounts, the development factor of a year is the mean of the ratios from that year to the next, weighted by the amounts of the first of the two. So it is not below the smallest of those ratios and not above the largest, and it is their common value when they are all alike.
4 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 4 broken variants are refuted. proofs/smt2/RS-01.smt2
- RS-02
In a triangle of four origin years, what the chain ladder expects to be paid in the three calendar years to come adds up to the reserve, which is the ultimate less the latest amount of each origin year. The first year pays the next factor of every open origin year, and when no factor is below one, no payment is below zero.
3 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 4 broken variants are refuted. proofs/smt2/RS-02.smt2
- RS-03
The variance that the formula of Mack gives to the last development year, which rests on a single ratio, is never below zero and never above either of the two estimates before it. It is the continuation of their decline when they do not rise, the earlier of the two when they rise, and nothing when the earlier is nothing.
6 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 4 broken variants are refuted. proofs/smt2/RS-03.smt2
Show the other 5 Show fewer
- RS-04
The ultimate forward rate of a year is the rate of the year before, or that rate plus 15 basis points, or that rate less 15 basis points. It rises exactly when the rate before the limit is at least 15 basis points above the rate of the year before, and falls exactly when it is at least 15 basis points below. It never ends farther from the rate before the limit than it began, and a higher rate before the limit never gives a lower ultimate rate.
5 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 5 broken variants are refuted. proofs/smt2/RS-04.smt2
- RS-05
Beyond the first smoothing point, the weight of the last liquid forward rate, which is (1 − e^(−a×h)) over a×h, is above zero and not above one. It is not below 1 − a×h/2, and a×h times it is not above one.
4 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 3 broken variants are refuted. proofs/smt2/RS-05.smt2
- RS-06
Beyond the first smoothing point, the forward rate of each horizon lies between the last liquid forward rate and the ultimate forward rate. Its distance from the first is at most a×h/2 of the distance between the two, and its distance from the second is at most 1/(a×h) of it.
4 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 3 broken variants are refuted. proofs/smt2/RS-06.smt2
- RS-07
Beyond the first smoothing point, the zero rate of each horizon lies between the zero rate at the point and the forward rate of that horizon. It is nearer to the one that covers more years, which is the forward rate when the horizon is longer than the point and the zero rate at the point when it is shorter.
4 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 3 broken variants are refuted. proofs/smt2/RS-07.smt2
- RS-08
The expected real rate is rounded to a whole number of five basis points, upwards when it is below the rounded rate of the year before and downwards otherwise. The rounded rate is less than five basis points from the unrounded one, a rate that is already a whole number of five basis points stays as it is, and a higher unrounded rate never gives a lower rounded one.
6 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 4 broken variants are refuted. proofs/smt2/RS-08.smt2
Tested
True on every input we tried.
- RS-09
A run-off triangle has from two to forty origin years, and each has one amount fewer than the year before it. Every amount is a finite number, and every development year that has a successor adds up to more than zero, or no factor could be found. A zero or a negative amount is allowed where its column still adds up to more than zero. A message names the origin year or the development year, counting from one. The first origin year is held to the number of years, since no year comes before it, and a later one to the year before it.
tests/kernel/reserving.test.ts
- RS-10
The amounts of each development year are added from left to right into running totals, and taken back out of them. The two are inverses of each other for whole amounts, keep the shape and check it. The amounts of Taylor and Ashe give the running totals that the vignette prints as the latest amounts.
tests/kernel/reserving.test.ts
- RS-11
The development factors of the RAA triangle are the nine that the vignette prints, to the three decimals it prints, and the ones that an independent script gives, to the last digit but a few. A factor is the total of the next year over the total of this one, for the origin years that have both. It is a mean of the link ratios with the earlier amounts as weights, it lies between the smallest and the largest of them, and it agrees with exact fractions. The argument is checked before anything is done.
tests/kernel/reserving.test.ts
Show the other 27 Show fewer
- RS-12
On the RAA triangle the chain ladder keeps what was observed and has for the rest the amounts that the vignette prints, to the unit. The ultimate and the reserve of each origin year, and the totals of 213,122.23 and 52,135.23, are the ones that the vignette prints. On the triangle of Taylor and Ashe the reserve of each origin year is the one that the vignette prints, to the unit. The reserve is the ultimate less the latest amount and each total is the sum of its column. The oldest year has nothing to come, a triangle of two origin years is enough, and the ultimate of every origin year agrees with exact fractions to fourteen digits.
tests/kernel/reserving.test.ts
- RS-13
What the factors say will be paid in each calendar year to come is listed with the next year first. Each year holds the next development year of every origin year that is still open. Together the years pay out the whole reserve, on every triangle the generator made. A proof shows the same for four origin years.
tests/kernel/reserving.test.ts
- RS-14
When every amount is scaled by a power of two, the factors stay the same and the ultimates, the reserves and the payments scale by that number exactly. When every origin year is a multiple of the first, the factors are those of the first. The triangle that was given is not changed, and the same triangle gives the same answer on every run.
tests/kernel/reserving.test.ts
- RS-15
The standard error of Mack needs at least four origin years, because the variance of the last factor is extrapolated from the two before it. It needs every amount above zero, wherever that amount stands. The reason is one of two messages, the shape is looked at first, and a chain ladder that was made from other rows is refused.
tests/kernel/reserving.test.ts
- RS-16
On the RAA triangle the standard error of each origin year is the one that the vignette prints, to the tenth, and that of the whole reserve is the 26,909.01 that it prints, to the hundredth. An independent script gives the variances, the errors and the total to thirteen digits, for this triangle and for the one of Taylor and Ashe. The variances, the squares of the errors and the square of the total agree with exact fractions. The oldest year has no error, and the smallest triangle that can be used has four origin years and a variance for each of three factors.
tests/kernel/reserving.test.ts
- RS-17
The error of the whole reserve is at least that of any one origin year, because the years share their factors. Scaling every amount by a power of two scales every error by it. A triangle whose origin years are all multiples of the first has next to no error. The variance of the last factor is the geometric continuation of the two before it when they do not rise, held to no more than either, and nothing when the earlier one is nothing. What was given is not changed.
tests/kernel/reserving.test.ts
- RS-18
A triangle copied from a sheet is read with tabs, spaces, commas or semicolons between the amounts, and with either kind of line end. Cells copied empty or as NA at the end of a line are dropped, and so are blank lines, but NA in the middle of a line is not. Signs, decimals, exponents and the minus sign of typography are read. A text that is not an amount is named with its line and shortened if it is long, and an empty text says that there is nothing to read. A triangle written out is read back as it was, and the two sample triangles come back as the page prints them.
tests/kernel/reserving.test.ts
- RS-19
A run takes running totals, or the amounts of each development year, which it adds first, and gives the chain ladder and the formula of Mack. It says why when the formula cannot be applied and then gives no error. It refuses a triangle that is not one on either basis, and shares no array with its input. The receipt covers the amounts, the basis, the factors, what comes to be paid and every error, with nothing where there is no error. It is the same for the same amounts, and it changes with the last bit of any amount and with the basis.
tests/kernel/reserving.test.ts
- RS-20
On the numerical illustration of Annex D of the technical documentation of October 2025, the Smith-Wilson fit finds the convergence parameter and the quasi-constant that the page prints. It gives the vector Q b to its three decimals and every one of the 242 numbers of Table 29 to the fifth decimal, and it prices each of the twenty swaps at par. The search for the parameter runs a few hundred times at most.
tests/kernel/curve.test.ts
- RS-21
The table of Annex D was made with the root of the gap, which is 0.12376048 to eight places, and the page prints it as 0.123760. The rule of the documentation asks for the lowest value of six decimals that brings the gap within one basis point. That value is 0.123761, one millionth above the root, and the printed 0.123760 misses the tolerance by a hair. The engine follows the rule, and the test keeps the difference in view.
tests/kernel/curve.test.ts
- RS-22
The rule in force is Smith-Wilson up to 29 January 2027 and the closed form from 30 January 2027, and it never goes back to the old one on a later day. A day is written year-month-day, and the calendar knows which centuries have a leap day. A day that is not on the calendar, or that is written another way, is refused, and the message says what it wants.
tests/kernel/curve.test.ts
- RS-23
The convergence parameter of the closed form is 11 per cent for every currency but the Swedish krona and 40 per cent for the krona. An undertaking that phases in follows Table 4 year by year from 2027 and ends where the plain value starts, stepping down by the same amount each year within each group. At 40 years past the first smoothing point every one of these values leaves at least 77.5 per cent of the weight on the ultimate forward rate, which is the floor of Article 77a, and 11 per cent is the lowest value of two decimals that does. Before 2027 there is nothing to phase in, and the message says so.
tests/kernel/curve.test.ts
- RS-24
The ultimate forward rate moves by 15 basis points when the rate before the limit is 15 or more away, and stays otherwise. At the boundary of 15 it moves, as the text puts it. Rates are read to a hundredth of a basis point, so a sum of doubles cannot decide a boundary. The rate changes by one step or none, never against the pull and never past it, and it does not fall when the rate before the limit rises. A proof shows the same for every rate.
tests/kernel/curve.test.ts
- RS-25
An inflation target falls in one of four buckets, with the edges where paragraph C.4.1 puts them, and a target at or below one per cent falls in the lowest. The expected real rate is rounded to five basis points, up when it is below the rounded rate of the year before and down when it is not, a negative rate included, and a rate already on the grid stays. A year of Annex C gives the euro rate 4.05 per cent from 4.20 when the rounded real rate falls to 2.00 per cent and the target is 2 per cent. It says when the rate does not move and when it rises.
tests/kernel/curve.test.ts
- RS-26
The function of Wilson is the same from either side, and is the form that the documentation writes in three ways. It is zero at zero, and on the diagonal it is alpha u less half of one minus the exponential of minus two alpha u. It does not overflow where a product of an exponential and a hyperbolic sine would. Its slope and its second derivative are those that the documentation gives, on both sides of the diagonal and across it.
tests/kernel/curve-fit.test.ts
- RS-27
The fit refuses a setup that cannot be fitted and says which part, an alpha that is not above zero, and instruments that do not fix the curve. It gives the same fit twice for the same alpha and another for another. The price starts at one and the spot is the zero-year limit of the yield. Beyond the last date the forward intensity is the closed form, it is the slope of minus the logarithm of the price, and the yield is its average. The gap is the distance of the forward intensity at the convergence point from the ultimate one.
tests/kernel/curve-fit.test.ts
- RS-28
The fit reprices what it was fitted to. Every par swap of a smooth curve is priced at par, for any curve the generator makes, and so is every zero coupon bond at its price, at the maturities it was fitted to and at the odd ones in between. A curve that already sits at the ultimate forward rate stays there. A curve of negative rates is fitted too, because the method needs the instruments to be independent and nothing more.
tests/kernel/curve-fit.test.ts
- RS-29
The search takes the lower bound when that is enough. Otherwise it returns an alpha that meets the tolerance and, to the decimals asked for, no lower one does. It agrees with a scan of a coarser step for any curve the generator makes, and a looser tolerance gives a lower alpha and a tighter one a higher alpha. It looks at the convergence point of the last date, which is 40 years after the last liquid point and never before year 60. Options that make no sense, and a tolerance that nothing can meet, are refused.
tests/kernel/curve-fit.test.ts
- RS-30
A curve lists 150 years, each with an intensity, an annual rate and a forward, and a spot. It tends to the ultimate forward rate from below and passes it by no more than the tolerance at the convergence point. It keeps the rate at 20 years where the swaps put it. A fit whose price falls to zero or below, which very high swap rates can cause, has no rate for that year, so it is refused with the first such year named, and a curve that is given never has a gap.
tests/kernel/curve-fit.test.ts
- RS-31
The bootstrap of Annex D gives the zero rates that the swaps imply, as an independent Newton-Raphson on equation D.5.9 gives them. It prices every swap at par, for any curve and any choice of maturities, and has one rate for each year to the last. It agrees with the Smith-Wilson fit at every maturity the swaps cover, is flat up to the first maturity, and keeps the forward constant between two maturities that are not a year apart. Zero coupon rates give back the rate at each maturity, with the forward that D.9.3 gives. What cannot be bootstrapped is refused, and the message says why.
tests/kernel/curve-rules.test.ts
- RS-32
The weight of the last liquid forward rate is one at the start and falls to zero, whatever alpha is. It is one less the exponential of minus a h, over a h, the same in alpha and in the horizon, and it keeps its digits for a small product, to four units in the last place, where a difference of two numbers close to one would lose them. It is continuous where the series gives way to the closed form. The forward rate is a weighted mean of the last liquid forward rate and the ultimate one for every horizon, the first at once and the second in the end. An alpha or a horizon that is not above zero is refused.
tests/kernel/curve-rules.test.ts
- RS-33
The extrapolation from the first smoothing point gives the zero rates, the last liquid forward rate and the ultimate forward rate that an independent script gives, to thirteen digits. That holds for a point at 20, 15, 10, 5 and 1 years, for other values of the ultimate rate and of alpha, and for forwards weighted by notionals in the order of the maturities from the point. The zero rates up to the point are those of the bootstrap.
tests/kernel/curve-rules.test.ts
- RS-34
The forward just before the point is the only leg, with the whole weight, when the point is the longest maturity, and the first leg runs from zero when the point is the first maturity. With gaps between the maturities the forward before the point is the constant forward of the bootstrap. The curve is continuous at the point, and a point at the last year has nothing after it.
tests/kernel/curve-rules.test.ts
- RS-35
A curve run builds the Smith-Wilson curve before 30 January 2027 and the closed form from that day, with the alpha of the day, and it says that the date decided. It takes the rule that is asked for whatever the date, and says that it was a choice. It uses the alpha of the krona and the phasing in when they apply, gives the same rates under both rules where the swaps fix the curve and different ones after, fits zero coupon rates too, and uses the notionals that it is given. A date that is not a date is refused under either rule, and so is a point that is not a maturity.
tests/kernel/curve-rules.test.ts
- RS-36
A payment at the end of year t is discounted by one over one plus the rate of that year, to the power t. Payments add, nothing is worth nothing, and the value is linear in the payments and falls at a higher rate when no payment is negative. A payment after the last year of the curve, and a payment that is not a number, are refused.
tests/kernel/curve-rules.test.ts
- RS-37
The receipt of a curve covers every input, the rule that was applied and how it was chosen, alpha and the rate of every year. It is the same for the same inputs, it does not depend on the type of the arrays, and it changes when any input changes, even by the last bit.
tests/kernel/curve-rules.test.ts
- RS-38
After the point the zero rate lies between the rate at the point and the forward for every horizon. The forward runs from the last liquid forward rate to the ultimate one, between the two the whole way and faster for a higher alpha, and a curve that already sits at the ultimate rate stays there. What does not fit is refused in a fixed order, and the message says what.
tests/kernel/curve-rules.test.ts
Use it
The same call, anywhere
This sample is written from the input the plate starts with, so the code and the numbers cannot drift apart.
import {
reservingReceiptPayload,
reservingRun,
} from '@graphatlas/kernel/reserving';
import type { ReservingInput } from '@graphatlas/kernel/reserving';
import {
curveReceiptPayload,
curveRun,
presentValue,
} from '@graphatlas/kernel/curve';
import type { CurveInput } from '@graphatlas/kernel/curve';
import { receipt } from '@graphatlas/kernel/receipt';
// General liability reinsurance, ten origin years, as running totals.
// The oldest origin year comes first.
const triangle: ReservingInput = {
basis: 'cumulative',
rows: [
[5012, 8269, 10907, 11805, 13539, 16181, 18009, 18608, 18662, 18834],
[106, 4285, 5396, 10666, 13782, 15599, 15496, 16169, 16704],
[3410, 8992, 13873, 16141, 18735, 22214, 22863, 23466],
[5655, 11555, 15766, 21266, 23425, 26083, 27067],
[1092, 9565, 15836, 22169, 25955, 26180],
[1513, 6445, 11702, 12935, 15852],
[557, 4020, 10946, 12314],
[1351, 6947, 13112],
[3133, 5395],
[2063],
],
};
const reserve = reservingRun(triangle);
const reserveHash = await receipt(reservingReceiptPayload(triangle, reserve));
// The twenty swap rates of the numerical illustration of EIOPA,
// on the day that the plate starts with.
const market: CurveInput = {
kind: 'par',
maturities: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
],
rates: [
0.002, 0.00225, 0.003, 0.00425, 0.0055, 0.007, 0.0085, 0.01, 0.0115,
0.01275, 0.014, 0.01475, 0.01575, 0.0165, 0.017, 0.0175, 0.018, 0.01825,
0.0185, 0.01875,
],
ufr: 0.042,
valuation: '2026-10-30',
currency: 'other',
phasedIn: false,
fsp: 20,
rule: 'date',
};
const curve = curveRun(market);
const curveHash = await receipt(curveReceiptPayload(market, curve));
// What the payments that the chain ladder expects are worth on that curve.
const worth = presentValue(reserve.cl.payments, curve.rates); const out = {
reserve: {
factors: [2.999, 1.624, 1.271, 1.172, 1.113, 1.042, 1.033, 1.017, 1.009],
ultimate: [
18834, 16857.9539, 24083.3709, 28703.1422, 28926.7363, 19501.1032,
17749.3026, 24019.1925, 16044.9841, 18402.4425,
],
total: 52135.2283,
standardError: 26909.0112,
payments: [
17501.4246, 13068.6106, 8870.9309, 5724.9554, 3529.4849, 1760.1799,
1061.3706, 450.2125, 168.0588,
],
},
curve: {
rule: 'smith-wilson',
decidedBy: 'date',
alpha: 0.123761,
rates: {
1: 0.002, 5: 0.005525, 10: 0.013057, 20: 0.019603, 40: 0.027873,
60: 0.032409, 100: 0.036226, 150: 0.038147,
},
},
worth: 51583.7045,
receipts: {
reserve: '40d32d54f7ebe60264cdc3d04f64c7dc855d9e93929aa9f65f4598d62f639ed7',
curve: '52eaa57fb4c55b51d1d69e381dfe43d2fc891a9c747ac6fe29e7ff9f4537fe9f',
},
}; The call and the numbers come from the engine that built this page, run on the same input as the plate above. The triangle and the swap rates are published, and the day is the one that the plate starts with. The two receipts are also made in your browser, where the plates compare them with these. The factors are rounded to the three decimals that the vignette prints. Values are rounded to four places for display. The receipt hashes the unrounded numbers.
Runs on
- Browser
- Edge
- Node.js
- Python
- JVM
- .NET
- Excel
- Command line
- Container
Green surfaces are measured on every build of this site. Each must return the same receipt, bit for bit. The others are packaged targets that the build does not measure. How the platform works
Changes
When the rule moves, so does the engine
Publications that touch this regime, and the release that answered each.
-
Updated methodology for the risk-free interest rate term structure
Shipped as Reserving 3.8, 9 days later
-
Amended Solvency II framework applies from 30 January 2027
Shipped as Solvency II 6.0, 14 days later