@actuarial-ts/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.md +133 -0
- package/dist/benktander.d.ts +45 -0
- package/dist/benktander.d.ts.map +1 -0
- package/dist/benktander.js +38 -0
- package/dist/benktander.js.map +1 -0
- package/dist/berquist.d.ts +14 -0
- package/dist/berquist.d.ts.map +1 -0
- package/dist/berquist.js +292 -0
- package/dist/berquist.js.map +1 -0
- package/dist/bf.d.ts +23 -0
- package/dist/bf.d.ts.map +1 -0
- package/dist/bf.js +83 -0
- package/dist/bf.js.map +1 -0
- package/dist/capping.d.ts +96 -0
- package/dist/capping.d.ts.map +1 -0
- package/dist/capping.js +207 -0
- package/dist/capping.js.map +1 -0
- package/dist/caseOutstanding.d.ts +80 -0
- package/dist/caseOutstanding.d.ts.map +1 -0
- package/dist/caseOutstanding.js +147 -0
- package/dist/caseOutstanding.js.map +1 -0
- package/dist/chainladder.d.ts +15 -0
- package/dist/chainladder.d.ts.map +1 -0
- package/dist/chainladder.js +81 -0
- package/dist/chainladder.js.map +1 -0
- package/dist/clark.d.ts +91 -0
- package/dist/clark.d.ts.map +1 -0
- package/dist/clark.js +490 -0
- package/dist/clark.js.map +1 -0
- package/dist/diagnostics.d.ts +80 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +359 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/discounting.d.ts +166 -0
- package/dist/discounting.d.ts.map +1 -0
- package/dist/discounting.js +210 -0
- package/dist/discounting.js.map +1 -0
- package/dist/elrMethods.d.ts +104 -0
- package/dist/elrMethods.d.ts.map +1 -0
- package/dist/elrMethods.js +151 -0
- package/dist/elrMethods.js.map +1 -0
- package/dist/factors.d.ts +19 -0
- package/dist/factors.d.ts.map +1 -0
- package/dist/factors.js +136 -0
- package/dist/factors.js.map +1 -0
- package/dist/fisherLange.d.ts +92 -0
- package/dist/fisherLange.d.ts.map +1 -0
- package/dist/fisherLange.js +224 -0
- package/dist/fisherLange.js.map +1 -0
- package/dist/freqSev.d.ts +57 -0
- package/dist/freqSev.d.ts.map +1 -0
- package/dist/freqSev.js +82 -0
- package/dist/freqSev.js.map +1 -0
- package/dist/ilf.d.ts +111 -0
- package/dist/ilf.d.ts.map +1 -0
- package/dist/ilf.js +449 -0
- package/dist/ilf.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/mack.d.ts +55 -0
- package/dist/mack.d.ts.map +1 -0
- package/dist/mack.js +244 -0
- package/dist/mack.js.map +1 -0
- package/dist/merzWuthrich.d.ts +29 -0
- package/dist/merzWuthrich.d.ts.map +1 -0
- package/dist/merzWuthrich.js +132 -0
- package/dist/merzWuthrich.js.map +1 -0
- package/dist/munichChainLadder.d.ts +101 -0
- package/dist/munichChainLadder.d.ts.map +1 -0
- package/dist/munichChainLadder.js +254 -0
- package/dist/munichChainLadder.js.map +1 -0
- package/dist/odpBootstrap.d.ts +65 -0
- package/dist/odpBootstrap.d.ts.map +1 -0
- package/dist/odpBootstrap.js +243 -0
- package/dist/odpBootstrap.js.map +1 -0
- package/dist/onlevel.d.ts +39 -0
- package/dist/onlevel.d.ts.map +1 -0
- package/dist/onlevel.js +104 -0
- package/dist/onlevel.js.map +1 -0
- package/dist/salvageSubro.d.ts +82 -0
- package/dist/salvageSubro.d.ts.map +1 -0
- package/dist/salvageSubro.js +100 -0
- package/dist/salvageSubro.js.map +1 -0
- package/dist/stochastic.d.ts +56 -0
- package/dist/stochastic.d.ts.map +1 -0
- package/dist/stochastic.js +99 -0
- package/dist/stochastic.js.map +1 -0
- package/dist/tail.d.ts +18 -0
- package/dist/tail.d.ts.map +1 -0
- package/dist/tail.js +121 -0
- package/dist/tail.js.map +1 -0
- package/dist/trend.d.ts +46 -0
- package/dist/trend.d.ts.map +1 -0
- package/dist/trend.js +99 -0
- package/dist/trend.js.map +1 -0
- package/dist/triangle.d.ts +19 -0
- package/dist/triangle.d.ts.map +1 -0
- package/dist/triangle.js +163 -0
- package/dist/triangle.js.map +1 -0
- package/dist/triangleAlgebra.d.ts +10 -0
- package/dist/triangleAlgebra.d.ts.map +1 -0
- package/dist/triangleAlgebra.js +97 -0
- package/dist/triangleAlgebra.js.map +1 -0
- package/dist/types.d.ts +280 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +79 -0
- package/dist/types.js.map +1 -0
- package/dist/ulae.d.ts +172 -0
- package/dist/ulae.d.ts.map +1 -0
- package/dist/ulae.js +164 -0
- package/dist/ulae.js.map +1 -0
- package/dist/util.d.ts +24 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +66 -0
- package/dist/util.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { mackEstimators, extrapolateSigma2 } from "./mack.js";
|
|
2
|
+
import { ReservingError } from "./types.js";
|
|
3
|
+
import { isNum, lastObservedIndex } from "./util.js";
|
|
4
|
+
/** Cell usable for ratio work: both triangles observed, both strictly positive. */
|
|
5
|
+
function usablePair(p, inc) {
|
|
6
|
+
return isNum(p) && isNum(inc) && p > 0 && inc > 0;
|
|
7
|
+
}
|
|
8
|
+
export function runMunichChainLadder(paid, incurred, options = {}) {
|
|
9
|
+
const n = paid.origins.length;
|
|
10
|
+
const K = paid.ages.length;
|
|
11
|
+
if (incurred.origins.length !== n ||
|
|
12
|
+
incurred.ages.length !== K ||
|
|
13
|
+
paid.origins.some((o, i) => incurred.origins[i] !== o) ||
|
|
14
|
+
paid.ages.some((a, j) => incurred.ages[j] !== a)) {
|
|
15
|
+
throw new ReservingError("SHAPE", "Munich chain ladder needs paid and incurred triangles with identical origins and ages");
|
|
16
|
+
}
|
|
17
|
+
for (const tri of [paid, incurred]) {
|
|
18
|
+
if (tri.values.length !== n || tri.values.some((row) => row.length !== K)) {
|
|
19
|
+
throw new ReservingError("SHAPE", "Triangle values must be a full origins x ages rectangle (null below the diagonal)");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (K < 2) {
|
|
23
|
+
throw new ReservingError("TOO_SMALL", "Munich chain ladder requires at least two development ages");
|
|
24
|
+
}
|
|
25
|
+
const warnings = [];
|
|
26
|
+
// Chain-ladder estimators, shared with Mack so the two can never drift.
|
|
27
|
+
const paidEst = mackEstimators(paid);
|
|
28
|
+
const incurredEst = mackEstimators(incurred);
|
|
29
|
+
// sigma completion: the final column (single factor) is never estimable.
|
|
30
|
+
// An explicit lastColumnSigma wins (the paper's manual 0.100); otherwise
|
|
31
|
+
// Mack's extrapolation rule fills every non-estimable column.
|
|
32
|
+
const completeSigma2 = (raw, label, override) => {
|
|
33
|
+
const withOverride = [...raw];
|
|
34
|
+
if (withOverride[K - 2] === null) {
|
|
35
|
+
const tag = label === "paid" ? "P" : "I";
|
|
36
|
+
if (isNum(override) && override >= 0) {
|
|
37
|
+
withOverride[K - 2] = override * override;
|
|
38
|
+
warnings.push(`sigma^${tag} for the final development column is not estimable; using the caller-supplied ${override} (Quarg-Mack set 0.100 in their example)`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
warnings.push(`sigma^${tag} for the final development column is not estimable; filled by Mack's extrapolation rule (the paper suggests a sounder extrapolation in practice)`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return extrapolateSigma2(withOverride, paid.ages, warnings);
|
|
45
|
+
};
|
|
46
|
+
const sigma2Paid = completeSigma2(paidEst.sigma2, "paid", options.lastColumnSigma?.paid);
|
|
47
|
+
const sigma2Incurred = completeSigma2(incurredEst.sigma2, "incurred", options.lastColumnSigma?.incurred);
|
|
48
|
+
// qhat_s (incurred-weighted average P/I per column) and the rho variance
|
|
49
|
+
// estimators for the ratio series (Sec 3.1.2; denominator = pairs - 1,
|
|
50
|
+
// exactly the Mack convention, verified against the printed rho rows).
|
|
51
|
+
const qRatios = new Array(K).fill(null);
|
|
52
|
+
const rhoPaid = new Array(K).fill(null);
|
|
53
|
+
const rhoIncurred = new Array(K).fill(null);
|
|
54
|
+
for (let s = 0; s < K; s++) {
|
|
55
|
+
let sumP = 0;
|
|
56
|
+
let sumI = 0;
|
|
57
|
+
let count = 0;
|
|
58
|
+
for (let i = 0; i < n; i++) {
|
|
59
|
+
const p = paid.values[i][s] ?? null;
|
|
60
|
+
const inc = incurred.values[i][s] ?? null;
|
|
61
|
+
if (usablePair(p, inc)) {
|
|
62
|
+
sumP += p;
|
|
63
|
+
sumI += inc;
|
|
64
|
+
count++;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (count === 0 || sumP <= 0 || sumI <= 0)
|
|
68
|
+
continue;
|
|
69
|
+
const q = sumP / sumI;
|
|
70
|
+
qRatios[s] = q;
|
|
71
|
+
if (count < 2)
|
|
72
|
+
continue;
|
|
73
|
+
let devP = 0;
|
|
74
|
+
let devI = 0;
|
|
75
|
+
for (let i = 0; i < n; i++) {
|
|
76
|
+
const p = paid.values[i][s] ?? null;
|
|
77
|
+
const inc = incurred.values[i][s] ?? null;
|
|
78
|
+
if (!usablePair(p, inc))
|
|
79
|
+
continue;
|
|
80
|
+
devP += p * (inc / p - 1 / q) ** 2;
|
|
81
|
+
devI += inc * (p / inc - q) ** 2;
|
|
82
|
+
}
|
|
83
|
+
rhoPaid[s] = Math.sqrt(devP / (count - 1));
|
|
84
|
+
rhoIncurred[s] = Math.sqrt(devI / (count - 1));
|
|
85
|
+
}
|
|
86
|
+
// The four residual triangles. Factor residuals need the DATA-ESTIMATED
|
|
87
|
+
// sigma (not the extrapolated one); ratio residuals need rho > 0.
|
|
88
|
+
const residuals = {
|
|
89
|
+
paidFactor: Array.from({ length: n }, () => new Array(K - 1).fill(null)),
|
|
90
|
+
incurredFactor: Array.from({ length: n }, () => new Array(K - 1).fill(null)),
|
|
91
|
+
paidRatio: Array.from({ length: n }, () => new Array(K).fill(null)),
|
|
92
|
+
incurredRatio: Array.from({ length: n }, () => new Array(K).fill(null)),
|
|
93
|
+
};
|
|
94
|
+
for (let s = 0; s < K; s++) {
|
|
95
|
+
const q = qRatios[s];
|
|
96
|
+
const rP = rhoPaid[s];
|
|
97
|
+
const rI = rhoIncurred[s];
|
|
98
|
+
if (!isNum(q) || !isNum(rP) || !isNum(rI) || rP <= 0 || rI <= 0)
|
|
99
|
+
continue;
|
|
100
|
+
for (let i = 0; i < n; i++) {
|
|
101
|
+
const p = paid.values[i][s] ?? null;
|
|
102
|
+
const inc = incurred.values[i][s] ?? null;
|
|
103
|
+
if (!usablePair(p, inc))
|
|
104
|
+
continue;
|
|
105
|
+
residuals.paidRatio[i][s] = ((inc / p - 1 / q) / rP) * Math.sqrt(p);
|
|
106
|
+
residuals.incurredRatio[i][s] = ((p / inc - q) / rI) * Math.sqrt(inc);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
for (let s = 0; s < K - 1; s++) {
|
|
110
|
+
const s2P = paidEst.sigma2[s];
|
|
111
|
+
const s2I = incurredEst.sigma2[s];
|
|
112
|
+
for (let i = 0; i < n; i++) {
|
|
113
|
+
const p0 = paid.values[i][s] ?? null;
|
|
114
|
+
const p1 = paid.values[i][s + 1] ?? null;
|
|
115
|
+
if (isNum(s2P) && s2P > 0 && isNum(p0) && isNum(p1) && p0 > 0) {
|
|
116
|
+
residuals.paidFactor[i][s] = ((p1 / p0 - paidEst.f[s]) / Math.sqrt(s2P)) * Math.sqrt(p0);
|
|
117
|
+
}
|
|
118
|
+
const i0 = incurred.values[i][s] ?? null;
|
|
119
|
+
const i1 = incurred.values[i][s + 1] ?? null;
|
|
120
|
+
if (isNum(s2I) && s2I > 0 && isNum(i0) && isNum(i1) && i0 > 0) {
|
|
121
|
+
residuals.incurredFactor[i][s] =
|
|
122
|
+
((i1 / i0 - incurredEst.f[s]) / Math.sqrt(s2I)) * Math.sqrt(i0);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Size gate: the pooled regressions need factor residuals, which exist
|
|
127
|
+
// only where a development column has two or more observed factors (a 3x3
|
|
128
|
+
// triangle at minimum). Zero-variance ratio series (rho = 0) are NOT a
|
|
129
|
+
// size problem - they collapse lambda to 0 below, the paper's built-in
|
|
130
|
+
// safety mechanism.
|
|
131
|
+
const anySigma = (raw) => raw.some((v) => v !== null);
|
|
132
|
+
if (!anySigma(paidEst.sigma2) && !anySigma(incurredEst.sigma2)) {
|
|
133
|
+
throw new ReservingError("TOO_SMALL", "Munich chain ladder needs at least one development column with two observed factors (a 3x3 triangle at minimum) to pool residuals");
|
|
134
|
+
}
|
|
135
|
+
// lambda^P / lambda^I: through-origin regression slopes over the pooled
|
|
136
|
+
// residual pairs (factor residual on the preceding ratio residual).
|
|
137
|
+
let numP = 0;
|
|
138
|
+
let denP = 0;
|
|
139
|
+
let numI = 0;
|
|
140
|
+
let denI = 0;
|
|
141
|
+
for (let s = 0; s < K - 1; s++) {
|
|
142
|
+
for (let i = 0; i < n; i++) {
|
|
143
|
+
const fResP = residuals.paidFactor[i][s];
|
|
144
|
+
const rResP = residuals.paidRatio[i][s];
|
|
145
|
+
if (isNum(fResP) && isNum(rResP)) {
|
|
146
|
+
numP += rResP * fResP;
|
|
147
|
+
denP += rResP * rResP;
|
|
148
|
+
}
|
|
149
|
+
const fResI = residuals.incurredFactor[i][s];
|
|
150
|
+
const rResI = residuals.incurredRatio[i][s];
|
|
151
|
+
if (isNum(fResI) && isNum(rResI)) {
|
|
152
|
+
numI += rResI * fResI;
|
|
153
|
+
denI += rResI * rResI;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const lambdaFor = (num, den, label) => {
|
|
158
|
+
if (den > 0)
|
|
159
|
+
return num / den;
|
|
160
|
+
warnings.push(`No usable ${label} residual variation; lambda^${label === "paid" ? "P" : "I"} set to 0 (the projection collapses to the separate chain ladder)`);
|
|
161
|
+
return 0;
|
|
162
|
+
};
|
|
163
|
+
const lambdaPaid = lambdaFor(numP, denP, "paid");
|
|
164
|
+
const lambdaIncurred = lambdaFor(numI, denI, "incurred");
|
|
165
|
+
// Simultaneous cell-by-cell projection, and the SCL comparison projection.
|
|
166
|
+
const projectedPaid = new Array(n).fill(null);
|
|
167
|
+
const projectedIncurred = new Array(n).fill(null);
|
|
168
|
+
const rows = [];
|
|
169
|
+
const totals = { paidUltimate: 0, incurredUltimate: 0, sclPaidUltimate: 0, sclIncurredUltimate: 0 };
|
|
170
|
+
const droppedCorrectionColumns = new Set();
|
|
171
|
+
for (let i = 0; i < n; i++) {
|
|
172
|
+
const lastP = lastObservedIndex(paid.values[i]);
|
|
173
|
+
const lastI = lastObservedIndex(incurred.values[i]);
|
|
174
|
+
if (lastP < 0 || lastI < 0) {
|
|
175
|
+
warnings.push(`Origin ${paid.origins[i]} has no observed ${lastP < 0 ? "paid" : "incurred"} values; excluded from results`);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (lastP !== lastI) {
|
|
179
|
+
warnings.push(`Origin ${paid.origins[i]}: paid and incurred diagonals end at different ages (${paid.ages[lastP]} vs ${paid.ages[lastI]}); the joint projection starts at the earlier age and observed cells are kept as given`);
|
|
180
|
+
}
|
|
181
|
+
const start = Math.min(lastP, lastI);
|
|
182
|
+
const mclP = paid.values[i].map((v) => (isNum(v) ? v : null));
|
|
183
|
+
const mclI = incurred.values[i].map((v) => (isNum(v) ? v : null));
|
|
184
|
+
for (let s = start; s < K - 1; s++) {
|
|
185
|
+
const p = mclP[s];
|
|
186
|
+
const inc = mclI[s];
|
|
187
|
+
// Multiplied-out recursion (Sec 3.2.1): no division by p or inc, so
|
|
188
|
+
// zero paid stays projectable, driven by the incurred side.
|
|
189
|
+
let nextP = p * paidEst.f[s];
|
|
190
|
+
let nextI = inc * incurredEst.f[s];
|
|
191
|
+
const q = qRatios[s];
|
|
192
|
+
const rP = rhoPaid[s];
|
|
193
|
+
const rI = rhoIncurred[s];
|
|
194
|
+
if (isNum(q) && q > 0 && isNum(rP) && rP > 0 && isNum(rI) && rI > 0) {
|
|
195
|
+
nextP += lambdaPaid * (Math.sqrt(sigma2Paid[s]) / rP) * (inc - p / q);
|
|
196
|
+
nextI += lambdaIncurred * (Math.sqrt(sigma2Incurred[s]) / rI) * (p - inc * q);
|
|
197
|
+
}
|
|
198
|
+
else if (!droppedCorrectionColumns.has(s)) {
|
|
199
|
+
droppedCorrectionColumns.add(s);
|
|
200
|
+
warnings.push(`No usable (P/I) ratio parameters at age ${paid.ages[s]}; the MCL correction is dropped for that step (falls back to the chain-ladder factor)`);
|
|
201
|
+
}
|
|
202
|
+
// Never overwrite an observation (only possible on ragged diagonals).
|
|
203
|
+
const observedP = mclP[s + 1] ?? null;
|
|
204
|
+
const observedI = mclI[s + 1] ?? null;
|
|
205
|
+
mclP[s + 1] = isNum(observedP) ? observedP : nextP;
|
|
206
|
+
mclI[s + 1] = isNum(observedI) ? observedI : nextI;
|
|
207
|
+
}
|
|
208
|
+
projectedPaid[i] = mclP;
|
|
209
|
+
projectedIncurred[i] = mclI;
|
|
210
|
+
// Separate chain ladder from each triangle's own diagonal.
|
|
211
|
+
let sclP = paid.values[i][lastP];
|
|
212
|
+
for (let s = lastP; s < K - 1; s++)
|
|
213
|
+
sclP *= paidEst.f[s];
|
|
214
|
+
let sclI = incurred.values[i][lastI];
|
|
215
|
+
for (let s = lastI; s < K - 1; s++)
|
|
216
|
+
sclI *= incurredEst.f[s];
|
|
217
|
+
const paidUltimate = mclP[K - 1];
|
|
218
|
+
const incurredUltimate = mclI[K - 1];
|
|
219
|
+
rows.push({
|
|
220
|
+
origin: paid.origins[i],
|
|
221
|
+
paidLatest: paid.values[i][lastP],
|
|
222
|
+
incurredLatest: incurred.values[i][lastI],
|
|
223
|
+
paidUltimate,
|
|
224
|
+
incurredUltimate,
|
|
225
|
+
sclPaidUltimate: sclP,
|
|
226
|
+
sclIncurredUltimate: sclI,
|
|
227
|
+
finalRatio: incurredUltimate > 0 ? paidUltimate / incurredUltimate : null,
|
|
228
|
+
sclFinalRatio: sclI > 0 ? sclP / sclI : null,
|
|
229
|
+
});
|
|
230
|
+
totals.paidUltimate += paidUltimate;
|
|
231
|
+
totals.incurredUltimate += incurredUltimate;
|
|
232
|
+
totals.sclPaidUltimate += sclP;
|
|
233
|
+
totals.sclIncurredUltimate += sclI;
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
method: "munichChainLadder",
|
|
237
|
+
paidFactors: paidEst.f,
|
|
238
|
+
incurredFactors: incurredEst.f,
|
|
239
|
+
sigmaPaid: sigma2Paid.map((v) => Math.sqrt(v)),
|
|
240
|
+
sigmaIncurred: sigma2Incurred.map((v) => Math.sqrt(v)),
|
|
241
|
+
qRatios,
|
|
242
|
+
rhoPaid,
|
|
243
|
+
rhoIncurred,
|
|
244
|
+
lambdaPaid,
|
|
245
|
+
lambdaIncurred,
|
|
246
|
+
residuals,
|
|
247
|
+
projectedPaid,
|
|
248
|
+
projectedIncurred,
|
|
249
|
+
rows,
|
|
250
|
+
totals,
|
|
251
|
+
warnings,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=munichChainLadder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"munichChainLadder.js","sourceRoot":"","sources":["../src/munichChainLadder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Triangle } from "./types.js";
|
|
2
|
+
import { type StochasticResult } from "./stochastic.js";
|
|
3
|
+
/**
|
|
4
|
+
* Over-dispersed Poisson (ODP) bootstrap of the chain ladder.
|
|
5
|
+
*
|
|
6
|
+
* Ground truth (England & Verrall 1999/2002; Shapland, CAS Monograph No. 4):
|
|
7
|
+
* - The cross-classified ODP GLM's fitted values reproduce the all-year
|
|
8
|
+
* volume-weighted chain ladder EXACTLY. In practice the fitted past
|
|
9
|
+
* incrementals come from the backwards recursion: anchor each row's
|
|
10
|
+
* latest observed cumulative, divide back through the volume-weighted
|
|
11
|
+
* factors, and difference.
|
|
12
|
+
* - Unscaled Pearson residuals r = (q - m) / sqrt(m) on incrementals; the
|
|
13
|
+
* scale parameter is phi = sum(r^2) / (n - p) with n = observed
|
|
14
|
+
* incrementals and p = 2I - 1 parameters for an I-origin triangle.
|
|
15
|
+
* - Resampling: draw residuals with replacement onto the fitted past
|
|
16
|
+
* (q* = m + r sqrt(m)), cumulate, refit volume-weighted factors, project
|
|
17
|
+
* each future incremental, and add process variance by sampling
|
|
18
|
+
* Gamma(mean m_f, variance phi m_f). Residuals are inflated by
|
|
19
|
+
* sqrt(n / (n - p)) first (the standard small-sample bias adjustment) —
|
|
20
|
+
* controllable via options.
|
|
21
|
+
* - Structural zero residuals (cells the fit reproduces exactly by
|
|
22
|
+
* construction, e.g. the corners) are excluded from the resampling pool.
|
|
23
|
+
*
|
|
24
|
+
* The GLM-mean == chain-ladder identity is the method's own validation
|
|
25
|
+
* hook: `odpFit(tri).reserveByOrigin` must tie to the volume-weighted
|
|
26
|
+
* chain ladder to floating-point precision, and the test suite pins it.
|
|
27
|
+
*/
|
|
28
|
+
export interface OdpFit {
|
|
29
|
+
/** Volume-weighted all-year factors, one per development interval. */
|
|
30
|
+
factors: number[];
|
|
31
|
+
/** Fitted past incrementals m_ij (null where unobserved). */
|
|
32
|
+
fittedIncrementals: (number | null)[][];
|
|
33
|
+
/** Unscaled Pearson residuals (null where unobserved or structurally zero). */
|
|
34
|
+
residuals: (number | null)[][];
|
|
35
|
+
/** Future incremental means per cell (null where already observed). */
|
|
36
|
+
futureMeans: (number | null)[][];
|
|
37
|
+
/** Expected unpaid per origin (== volume-weighted chain ladder reserve). */
|
|
38
|
+
reserveByOrigin: {
|
|
39
|
+
origin: string;
|
|
40
|
+
reserve: number;
|
|
41
|
+
}[];
|
|
42
|
+
phi: number;
|
|
43
|
+
n: number;
|
|
44
|
+
p: number;
|
|
45
|
+
/** Residuals actually in the resampling pool (structural zeros excluded). */
|
|
46
|
+
poolSize: number;
|
|
47
|
+
warnings: string[];
|
|
48
|
+
}
|
|
49
|
+
/** Fits the ODP cross-classified model via the chain-ladder equivalence. */
|
|
50
|
+
export declare function odpFit(tri: Triangle): OdpFit;
|
|
51
|
+
export interface OdpBootstrapOptions {
|
|
52
|
+
nSims: number;
|
|
53
|
+
seed: number;
|
|
54
|
+
/** Inflate residuals by sqrt(n/(n-p)) before resampling (default true). */
|
|
55
|
+
biasAdjust?: boolean;
|
|
56
|
+
/** Add ODP process variance via gamma sampling (default true). */
|
|
57
|
+
processVariance?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface OdpBootstrapResult extends StochasticResult {
|
|
60
|
+
method: "odpBootstrap";
|
|
61
|
+
fit: OdpFit;
|
|
62
|
+
}
|
|
63
|
+
/** The ODP bootstrap. Same seed + same triangle = same result, bit for bit. */
|
|
64
|
+
export declare function runOdpBootstrap(tri: Triangle, options: OdpBootstrapOptions): OdpBootstrapResult;
|
|
65
|
+
//# sourceMappingURL=odpBootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"odpBootstrap.d.ts","sourceRoot":"","sources":["../src/odpBootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,MAAM;IACrB,sEAAsE;IACtE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6DAA6D;IAC7D,kBAAkB,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IACxC,+EAA+E;IAC/E,SAAS,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAC/B,uEAAuE;IACvE,WAAW,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IACjC,4EAA4E;IAC5E,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA4BD,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CA6G5C;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAiH/F"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { ReservingError } from "./types.js";
|
|
2
|
+
import { isNum, lastObservedIndex } from "./util.js";
|
|
3
|
+
import { cumulativeToIncremental } from "./triangleAlgebra.js";
|
|
4
|
+
import { createRng, summarizeSample, } from "./stochastic.js";
|
|
5
|
+
/** Volume-weighted all-year factors (the ODP GLM's implied development). */
|
|
6
|
+
function volumeWeightedFactors(tri) {
|
|
7
|
+
const K = tri.ages.length;
|
|
8
|
+
const out = [];
|
|
9
|
+
for (let j = 0; j < K - 1; j++) {
|
|
10
|
+
let num = 0;
|
|
11
|
+
let den = 0;
|
|
12
|
+
for (let i = 0; i < tri.origins.length; i++) {
|
|
13
|
+
const c0 = tri.values[i][j] ?? null;
|
|
14
|
+
const c1 = tri.values[i][j + 1] ?? null;
|
|
15
|
+
if (isNum(c0) && isNum(c1) && c0 > 0) {
|
|
16
|
+
num += c1;
|
|
17
|
+
den += c0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (den <= 0) {
|
|
21
|
+
throw new ReservingError("NO_FACTOR", `Development column ${tri.ages[j]}-${tri.ages[j + 1]} has no usable factors for the ODP fit`);
|
|
22
|
+
}
|
|
23
|
+
out.push(num / den);
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/** Fits the ODP cross-classified model via the chain-ladder equivalence. */
|
|
28
|
+
export function odpFit(tri) {
|
|
29
|
+
const warnings = [];
|
|
30
|
+
const I = tri.origins.length;
|
|
31
|
+
const K = tri.ages.length;
|
|
32
|
+
if (I < 3 || K < 3) {
|
|
33
|
+
throw new ReservingError("TOO_SMALL", "The ODP bootstrap needs at least a 3x3 triangle");
|
|
34
|
+
}
|
|
35
|
+
const factors = volumeWeightedFactors(tri);
|
|
36
|
+
const incr = cumulativeToIncremental(tri);
|
|
37
|
+
// Backwards recursion for fitted past cumulatives, anchored at each row's
|
|
38
|
+
// latest observed diagonal.
|
|
39
|
+
const fittedCum = tri.origins.map(() => new Array(K).fill(null));
|
|
40
|
+
const latestIdx = [];
|
|
41
|
+
for (let i = 0; i < I; i++) {
|
|
42
|
+
const d = lastObservedIndex(tri.values[i]);
|
|
43
|
+
latestIdx.push(d);
|
|
44
|
+
if (d < 0) {
|
|
45
|
+
warnings.push(`Origin ${tri.origins[i]} has no observed cells; excluded from the fit`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const anchor = tri.values[i][d];
|
|
49
|
+
fittedCum[i][d] = anchor;
|
|
50
|
+
for (let j = d - 1; j >= 0; j--) {
|
|
51
|
+
fittedCum[i][j] = fittedCum[i][j + 1] / factors[j];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Fitted past incrementals.
|
|
55
|
+
const fittedIncrementals = fittedCum.map((row, i) => {
|
|
56
|
+
const d = latestIdx[i];
|
|
57
|
+
return row.map((v, j) => {
|
|
58
|
+
if (j > d || !isNum(v))
|
|
59
|
+
return null;
|
|
60
|
+
if (j === 0)
|
|
61
|
+
return v;
|
|
62
|
+
return v - row[j - 1];
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
// Pearson residuals; structural zeros (|q - m| ~ 0 at machine precision
|
|
66
|
+
// where the fit reproduces the cell by construction) leave the pool.
|
|
67
|
+
const residuals = tri.origins.map(() => new Array(K).fill(null));
|
|
68
|
+
let n = 0;
|
|
69
|
+
let sumSq = 0;
|
|
70
|
+
let pool = 0;
|
|
71
|
+
let negativeFitted = 0;
|
|
72
|
+
for (let i = 0; i < I; i++) {
|
|
73
|
+
for (let j = 0; j <= latestIdx[i]; j++) {
|
|
74
|
+
const q = incr.values[i][j] ?? null;
|
|
75
|
+
const m = fittedIncrementals[i][j] ?? null;
|
|
76
|
+
if (!isNum(q) || !isNum(m))
|
|
77
|
+
continue;
|
|
78
|
+
n++;
|
|
79
|
+
if (m <= 0) {
|
|
80
|
+
negativeFitted++;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const r = (q - m) / Math.sqrt(m);
|
|
84
|
+
sumSq += r * r;
|
|
85
|
+
if (Math.abs(r) > 1e-10) {
|
|
86
|
+
residuals[i][j] = r;
|
|
87
|
+
pool++;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
residuals[i][j] = 0; // structural zero: reported, not resampled
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (negativeFitted > 0) {
|
|
95
|
+
warnings.push(`${negativeFitted} fitted incremental(s) are non-positive; their residuals are undefined and excluded (see Shapland on negative incrementals)`);
|
|
96
|
+
}
|
|
97
|
+
const p = 2 * I - 1;
|
|
98
|
+
if (n <= p) {
|
|
99
|
+
throw new ReservingError("TOO_SMALL", `The ODP fit has ${n} observations for ${p} parameters; no degrees of freedom remain`);
|
|
100
|
+
}
|
|
101
|
+
const phi = sumSq / (n - p);
|
|
102
|
+
// Future incremental means from the fitted projection.
|
|
103
|
+
const futureMeans = tri.origins.map(() => new Array(K).fill(null));
|
|
104
|
+
const reserveByOrigin = [];
|
|
105
|
+
for (let i = 0; i < I; i++) {
|
|
106
|
+
const d = latestIdx[i];
|
|
107
|
+
if (d < 0)
|
|
108
|
+
continue;
|
|
109
|
+
let cum = tri.values[i][d];
|
|
110
|
+
let reserve = 0;
|
|
111
|
+
for (let j = d + 1; j < K; j++) {
|
|
112
|
+
const next = cum * factors[j - 1];
|
|
113
|
+
const m = next - cum;
|
|
114
|
+
futureMeans[i][j] = m;
|
|
115
|
+
reserve += m;
|
|
116
|
+
cum = next;
|
|
117
|
+
}
|
|
118
|
+
reserveByOrigin.push({ origin: tri.origins[i], reserve });
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
factors,
|
|
122
|
+
fittedIncrementals,
|
|
123
|
+
residuals,
|
|
124
|
+
futureMeans,
|
|
125
|
+
reserveByOrigin,
|
|
126
|
+
phi,
|
|
127
|
+
n,
|
|
128
|
+
p,
|
|
129
|
+
poolSize: pool,
|
|
130
|
+
warnings,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/** The ODP bootstrap. Same seed + same triangle = same result, bit for bit. */
|
|
134
|
+
export function runOdpBootstrap(tri, options) {
|
|
135
|
+
const { nSims, seed } = options;
|
|
136
|
+
if (!Number.isInteger(nSims) || nSims < 100) {
|
|
137
|
+
throw new ReservingError("TOO_SMALL", "The bootstrap needs an integer nSims >= 100");
|
|
138
|
+
}
|
|
139
|
+
const biasAdjust = options.biasAdjust ?? true;
|
|
140
|
+
const processVariance = options.processVariance ?? true;
|
|
141
|
+
const fit = odpFit(tri);
|
|
142
|
+
const warnings = [...fit.warnings];
|
|
143
|
+
const I = tri.origins.length;
|
|
144
|
+
const K = tri.ages.length;
|
|
145
|
+
const rng = createRng(seed);
|
|
146
|
+
// Residual pool (bias-adjusted), flattened.
|
|
147
|
+
const inflate = biasAdjust ? Math.sqrt(fit.n / (fit.n - fit.p)) : 1;
|
|
148
|
+
const pool = [];
|
|
149
|
+
for (const row of fit.residuals) {
|
|
150
|
+
for (const r of row) {
|
|
151
|
+
if (isNum(r) && Math.abs(r) > 1e-10)
|
|
152
|
+
pool.push(r * inflate);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (pool.length < 10) {
|
|
156
|
+
throw new ReservingError("TOO_SMALL", "Fewer than 10 usable residuals; bootstrap unreliable");
|
|
157
|
+
}
|
|
158
|
+
const latestIdx = tri.values.map((row) => lastObservedIndex(row));
|
|
159
|
+
let negativeFutureMeans = 0;
|
|
160
|
+
const totals = new Array(nSims).fill(0);
|
|
161
|
+
const perOrigin = tri.origins.map(() => new Array(nSims).fill(0));
|
|
162
|
+
for (let b = 0; b < nSims; b++) {
|
|
163
|
+
// 1. Pseudo past incrementals -> pseudo cumulative triangle.
|
|
164
|
+
const pseudoCum = tri.origins.map(() => new Array(K).fill(null));
|
|
165
|
+
for (let i = 0; i < I; i++) {
|
|
166
|
+
let running = 0;
|
|
167
|
+
for (let j = 0; j <= latestIdx[i]; j++) {
|
|
168
|
+
const m = fit.fittedIncrementals[i][j];
|
|
169
|
+
if (!isNum(m) || m <= 0) {
|
|
170
|
+
// Cells without a usable fitted value keep their mean contribution.
|
|
171
|
+
running += isNum(m) ? m : 0;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const r = pool[Math.floor(rng.next() * pool.length)];
|
|
175
|
+
running += m + r * Math.sqrt(m);
|
|
176
|
+
}
|
|
177
|
+
pseudoCum[i][j] = running;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const pseudo = {
|
|
181
|
+
kind: tri.kind,
|
|
182
|
+
origins: tri.origins,
|
|
183
|
+
ages: tri.ages,
|
|
184
|
+
values: pseudoCum,
|
|
185
|
+
};
|
|
186
|
+
// 2. Refit and project; 3. process variance on each future incremental.
|
|
187
|
+
let factors;
|
|
188
|
+
try {
|
|
189
|
+
factors = volumeWeightedFactors(pseudo);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// A pathological resample (non-positive column volume) is discarded by
|
|
193
|
+
// reusing the fitted factors; counted and warned once at the end.
|
|
194
|
+
factors = fit.factors;
|
|
195
|
+
negativeFutureMeans++;
|
|
196
|
+
}
|
|
197
|
+
for (let i = 0; i < I; i++) {
|
|
198
|
+
const d = latestIdx[i];
|
|
199
|
+
if (d < 0)
|
|
200
|
+
continue;
|
|
201
|
+
let cum = pseudoCum[i][d];
|
|
202
|
+
let reserve = 0;
|
|
203
|
+
for (let j = d + 1; j < K; j++) {
|
|
204
|
+
const next = cum * factors[j - 1];
|
|
205
|
+
let m = next - cum;
|
|
206
|
+
if (processVariance) {
|
|
207
|
+
if (m > 0) {
|
|
208
|
+
// Gamma with mean m, variance phi m.
|
|
209
|
+
m = rng.gamma(m / fit.phi) * fit.phi;
|
|
210
|
+
}
|
|
211
|
+
else if (m < 0) {
|
|
212
|
+
negativeFutureMeans++;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
reserve += m;
|
|
216
|
+
// The projection chain advances on the mean path; process noise is
|
|
217
|
+
// per-cell around the mean (England & Verrall 2002, Appendix 3).
|
|
218
|
+
cum = next;
|
|
219
|
+
}
|
|
220
|
+
perOrigin[i][b] = reserve;
|
|
221
|
+
totals[b] += reserve;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (negativeFutureMeans > 0) {
|
|
225
|
+
warnings.push(`${negativeFutureMeans} simulated future incremental(s)/resample(s) had non-positive means; added deterministically without process variance (documented simplification for downward development)`);
|
|
226
|
+
}
|
|
227
|
+
const byOrigin = tri.origins
|
|
228
|
+
.map((origin, i) => ({ origin, samples: perOrigin[i] }))
|
|
229
|
+
.filter((e) => latestIdx[tri.origins.indexOf(e.origin)] >= 0 && e.samples.some((v) => v !== 0))
|
|
230
|
+
.map((e) => ({ origin: e.origin, summary: summarizeSample(e.samples) }));
|
|
231
|
+
return {
|
|
232
|
+
method: "odpBootstrap",
|
|
233
|
+
quantity: "unpaid",
|
|
234
|
+
seed,
|
|
235
|
+
nSims,
|
|
236
|
+
total: summarizeSample(totals),
|
|
237
|
+
byOrigin,
|
|
238
|
+
totalSamples: [...totals].sort((a, b) => a - b),
|
|
239
|
+
fit,
|
|
240
|
+
warnings,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=odpBootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"odpBootstrap.js","sourceRoot":"","sources":["../src/odpBootstrap.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EACL,SAAS,EACT,eAAe,GAEhB,MAAM,iBAAiB,CAAC;AA+CzB,4EAA4E;AAC5E,SAAS,qBAAqB,CAAC,GAAa;IAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACrC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;YACzC,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;gBACrC,GAAG,IAAI,EAAE,CAAC;gBACV,GAAG,IAAI,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,cAAc,CACtB,WAAW,EACX,sBAAsB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,wCAAwC,CAC7F,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,MAAM,CAAC,GAAa;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,cAAc,CAAC,WAAW,EAAE,iDAAiD,CAAC,CAAC;IAC3F,CAAC;IACD,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAE1C,0EAA0E;IAC1E,4BAA4B;IAC5B,MAAM,SAAS,GAAwB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtF,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC;QAC5C,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,QAAQ,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,+CAA+C,CAAC,CAAC;YACvF,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;QAClC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QACzD,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,MAAM,kBAAkB,GAAwB,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACvE,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC;QACxB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACtB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC,CAAC;YACtB,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,SAAS,GAAwB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACrC,MAAM,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAAE,SAAS;YACrC,CAAC,EAAE,CAAC;YACJ,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACX,cAAc,EAAE,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;gBACxB,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACrB,IAAI,EAAE,CAAC;YACT,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,2CAA2C;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,QAAQ,CAAC,IAAI,CACX,GAAG,cAAc,6HAA6H,CAC/I,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,cAAc,CACtB,WAAW,EACX,mBAAmB,CAAC,qBAAqB,CAAC,2CAA2C,CACtF,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5B,uDAAuD;IACvD,MAAM,WAAW,GAAwB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,MAAM,eAAe,GAA0C,EAAE,CAAC;IAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC;YAAE,SAAS;QACpB,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;QAC7B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACnC,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;YACrB,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC,CAAC;YACb,GAAG,GAAG,IAAI,CAAC;QACb,CAAC;QACD,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,OAAO;QACP,kBAAkB;QAClB,SAAS;QACT,WAAW;QACX,eAAe;QACf,GAAG;QACH,CAAC;QACD,CAAC;QACD,QAAQ,EAAE,IAAI;QACd,QAAQ;KACT,CAAC;AACJ,CAAC;AAgBD,+EAA+E;AAC/E,MAAM,UAAU,eAAe,CAAC,GAAa,EAAE,OAA4B;IACzE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAC5C,MAAM,IAAI,cAAc,CAAC,WAAW,EAAE,6CAA6C,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;IAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC;IAExD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE5B,4CAA4C;IAC5C,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK;gBAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,cAAc,CAAC,WAAW,EAAE,sDAAsD,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,IAAI,mBAAmB,GAAG,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAa,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAe,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,6DAA6D;QAC7D,MAAM,SAAS,GAAwB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,CAAC,GAAG,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxB,oEAAoE;oBACpE,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAE,CAAC;oBACtD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClC,CAAC;gBACD,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAa;YACvB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,SAAS;SAClB,CAAC;QAEF,wEAAwE;QACxE,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,kEAAkE;YAClE,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YACtB,mBAAmB,EAAE,CAAC;QACxB,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC;gBAAE,SAAS;YACpB,IAAI,GAAG,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;YAC5B,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;gBACnC,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;gBACnB,IAAI,eAAe,EAAE,CAAC;oBACpB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACV,qCAAqC;wBACrC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC;oBACvC,CAAC;yBAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACjB,mBAAmB,EAAE,CAAC;oBACxB,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAC,CAAC;gBACb,mEAAmE;gBACnE,iEAAiE;gBACjE,GAAG,GAAG,IAAI,CAAC;YACb,CAAC;YACD,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YAC3B,MAAM,CAAC,CAAC,CAAE,IAAI,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IACD,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CACX,GAAG,mBAAmB,4KAA4K,CACnM,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO;SACzB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;SACxD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;SAC/F,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAE3E,OAAO;QACL,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,QAAQ;QAClB,IAAI;QACJ,KAAK;QACL,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC;QAC9B,QAAQ;QACR,YAAY,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,GAAG;QACH,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallelogram-method premium on-leveling (Werner & Modlin ch. 5).
|
|
3
|
+
*
|
|
4
|
+
* Assumptions, stated plainly: policies carry an ANNUAL term, are written
|
|
5
|
+
* uniformly through time, and premium earns evenly over the policy term. A
|
|
6
|
+
* rate change applies to policies WRITTEN on or after its effective date.
|
|
7
|
+
* Under those assumptions the share of a calendar period's EARNED premium
|
|
8
|
+
* sitting at each historical rate level is a piece of parallelogram
|
|
9
|
+
* geometry, computed here exactly (piecewise-linear integration, no grids).
|
|
10
|
+
*
|
|
11
|
+
* The on-level factor for a period = current cumulative rate level divided
|
|
12
|
+
* by the average rate level earned in that period.
|
|
13
|
+
*/
|
|
14
|
+
export interface RateChange {
|
|
15
|
+
/** ISO date the change takes effect (applies to policies written on/after it). */
|
|
16
|
+
effectiveDate: string;
|
|
17
|
+
/** Rate change, e.g. 0.05 = +5%. */
|
|
18
|
+
change: number;
|
|
19
|
+
}
|
|
20
|
+
export interface OnLevelRow {
|
|
21
|
+
origin: string;
|
|
22
|
+
/** Average relative rate level earned in the period (1 = initial level). */
|
|
23
|
+
averageRateLevel: number;
|
|
24
|
+
/** currentLevel / averageRateLevel. */
|
|
25
|
+
onLevelFactor: number;
|
|
26
|
+
}
|
|
27
|
+
export interface OnLevelResult {
|
|
28
|
+
rows: OnLevelRow[];
|
|
29
|
+
/** Cumulative rate level after all changes (1 = initial level). */
|
|
30
|
+
currentLevel: number;
|
|
31
|
+
warnings: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* On-level factors per origin period from a rate-change history. Changes
|
|
35
|
+
* effective before all data simply set the base level; an empty history
|
|
36
|
+
* yields factors of exactly 1.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parallelogramOnLevel(origins: string[], history: RateChange[]): OnLevelResult;
|
|
39
|
+
//# sourceMappingURL=onlevel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onlevel.d.ts","sourceRoot":"","sources":["../src/onlevel.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAuDD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,UAAU,EAAE,GACpB,aAAa,CAsDf"}
|