@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.
Files changed (120) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +133 -0
  4. package/dist/benktander.d.ts +45 -0
  5. package/dist/benktander.d.ts.map +1 -0
  6. package/dist/benktander.js +38 -0
  7. package/dist/benktander.js.map +1 -0
  8. package/dist/berquist.d.ts +14 -0
  9. package/dist/berquist.d.ts.map +1 -0
  10. package/dist/berquist.js +292 -0
  11. package/dist/berquist.js.map +1 -0
  12. package/dist/bf.d.ts +23 -0
  13. package/dist/bf.d.ts.map +1 -0
  14. package/dist/bf.js +83 -0
  15. package/dist/bf.js.map +1 -0
  16. package/dist/capping.d.ts +96 -0
  17. package/dist/capping.d.ts.map +1 -0
  18. package/dist/capping.js +207 -0
  19. package/dist/capping.js.map +1 -0
  20. package/dist/caseOutstanding.d.ts +80 -0
  21. package/dist/caseOutstanding.d.ts.map +1 -0
  22. package/dist/caseOutstanding.js +147 -0
  23. package/dist/caseOutstanding.js.map +1 -0
  24. package/dist/chainladder.d.ts +15 -0
  25. package/dist/chainladder.d.ts.map +1 -0
  26. package/dist/chainladder.js +81 -0
  27. package/dist/chainladder.js.map +1 -0
  28. package/dist/clark.d.ts +91 -0
  29. package/dist/clark.d.ts.map +1 -0
  30. package/dist/clark.js +490 -0
  31. package/dist/clark.js.map +1 -0
  32. package/dist/diagnostics.d.ts +80 -0
  33. package/dist/diagnostics.d.ts.map +1 -0
  34. package/dist/diagnostics.js +359 -0
  35. package/dist/diagnostics.js.map +1 -0
  36. package/dist/discounting.d.ts +166 -0
  37. package/dist/discounting.d.ts.map +1 -0
  38. package/dist/discounting.js +210 -0
  39. package/dist/discounting.js.map +1 -0
  40. package/dist/elrMethods.d.ts +104 -0
  41. package/dist/elrMethods.d.ts.map +1 -0
  42. package/dist/elrMethods.js +151 -0
  43. package/dist/elrMethods.js.map +1 -0
  44. package/dist/factors.d.ts +19 -0
  45. package/dist/factors.d.ts.map +1 -0
  46. package/dist/factors.js +136 -0
  47. package/dist/factors.js.map +1 -0
  48. package/dist/fisherLange.d.ts +92 -0
  49. package/dist/fisherLange.d.ts.map +1 -0
  50. package/dist/fisherLange.js +224 -0
  51. package/dist/fisherLange.js.map +1 -0
  52. package/dist/freqSev.d.ts +57 -0
  53. package/dist/freqSev.d.ts.map +1 -0
  54. package/dist/freqSev.js +82 -0
  55. package/dist/freqSev.js.map +1 -0
  56. package/dist/ilf.d.ts +111 -0
  57. package/dist/ilf.d.ts.map +1 -0
  58. package/dist/ilf.js +449 -0
  59. package/dist/ilf.js.map +1 -0
  60. package/dist/index.d.ts +29 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +29 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/mack.d.ts +55 -0
  65. package/dist/mack.d.ts.map +1 -0
  66. package/dist/mack.js +244 -0
  67. package/dist/mack.js.map +1 -0
  68. package/dist/merzWuthrich.d.ts +29 -0
  69. package/dist/merzWuthrich.d.ts.map +1 -0
  70. package/dist/merzWuthrich.js +132 -0
  71. package/dist/merzWuthrich.js.map +1 -0
  72. package/dist/munichChainLadder.d.ts +101 -0
  73. package/dist/munichChainLadder.d.ts.map +1 -0
  74. package/dist/munichChainLadder.js +254 -0
  75. package/dist/munichChainLadder.js.map +1 -0
  76. package/dist/odpBootstrap.d.ts +65 -0
  77. package/dist/odpBootstrap.d.ts.map +1 -0
  78. package/dist/odpBootstrap.js +243 -0
  79. package/dist/odpBootstrap.js.map +1 -0
  80. package/dist/onlevel.d.ts +39 -0
  81. package/dist/onlevel.d.ts.map +1 -0
  82. package/dist/onlevel.js +104 -0
  83. package/dist/onlevel.js.map +1 -0
  84. package/dist/salvageSubro.d.ts +82 -0
  85. package/dist/salvageSubro.d.ts.map +1 -0
  86. package/dist/salvageSubro.js +100 -0
  87. package/dist/salvageSubro.js.map +1 -0
  88. package/dist/stochastic.d.ts +56 -0
  89. package/dist/stochastic.d.ts.map +1 -0
  90. package/dist/stochastic.js +99 -0
  91. package/dist/stochastic.js.map +1 -0
  92. package/dist/tail.d.ts +18 -0
  93. package/dist/tail.d.ts.map +1 -0
  94. package/dist/tail.js +121 -0
  95. package/dist/tail.js.map +1 -0
  96. package/dist/trend.d.ts +46 -0
  97. package/dist/trend.d.ts.map +1 -0
  98. package/dist/trend.js +99 -0
  99. package/dist/trend.js.map +1 -0
  100. package/dist/triangle.d.ts +19 -0
  101. package/dist/triangle.d.ts.map +1 -0
  102. package/dist/triangle.js +163 -0
  103. package/dist/triangle.js.map +1 -0
  104. package/dist/triangleAlgebra.d.ts +10 -0
  105. package/dist/triangleAlgebra.d.ts.map +1 -0
  106. package/dist/triangleAlgebra.js +97 -0
  107. package/dist/triangleAlgebra.js.map +1 -0
  108. package/dist/types.d.ts +280 -0
  109. package/dist/types.d.ts.map +1 -0
  110. package/dist/types.js +79 -0
  111. package/dist/types.js.map +1 -0
  112. package/dist/ulae.d.ts +172 -0
  113. package/dist/ulae.d.ts.map +1 -0
  114. package/dist/ulae.js +164 -0
  115. package/dist/ulae.js.map +1 -0
  116. package/dist/util.d.ts +24 -0
  117. package/dist/util.d.ts.map +1 -0
  118. package/dist/util.js +66 -0
  119. package/dist/util.js.map +1 -0
  120. package/package.json +66 -0
package/dist/mack.js ADDED
@@ -0,0 +1,244 @@
1
+ import { ReservingError } from "./types.js";
2
+ import { isNum, lastObservedIndex } from "./util.js";
3
+ /**
4
+ * Mack (1993) distribution-free chain ladder standard errors, alpha = 1,
5
+ * extended per Mack (1999) to selected development factors and a tail:
6
+ *
7
+ * - f_k = sum(C_{i,k+1}) / sum(C_{i,k}) over rows with both cells observed
8
+ * - s^2_k = 1/(n_k - 1) * sum C_{i,k} (F_{ik} - f_k)^2, always estimated
9
+ * around the volume-weighted f_k (the data-driven estimator) even when
10
+ * the projection uses selected factors
11
+ * - s^2 for the final column is extrapolated per Mack:
12
+ * min(s^4_{K-2}/s^2_{K-3}, min(s^2_{K-3}, s^2_{K-2}))
13
+ * - se(R_i)^2 = C_ult^2 * sum_k (s^2_k / f*_k^2) (1/C_ik + 1/sum_j C_jk)
14
+ * with f* the projection factors and projected C below the diagonal
15
+ * - a tail step (tailFactor > 1) extends the sum by one column, with s^2
16
+ * extrapolated once more by the same rule and the final column's volume
17
+ * as its denominator - an approximation, flagged in warnings
18
+ * - the total includes Mack's cross-covariance term between accident years
19
+ */
20
+ /**
21
+ * Mack's base estimators: volume-weighted development factors f_k, their
22
+ * column volumes (sum of C_{i,k} over the rows used), the per-column pair
23
+ * counts, and the DATA-ESTIMATED sigma^2_k (null where fewer than two
24
+ * factors exist — extrapolation is runMack's business, not the estimator's).
25
+ * Shared by runMack and the residual diagnostics so the two can never drift.
26
+ */
27
+ export function mackEstimators(tri) {
28
+ const n = tri.origins.length;
29
+ const K = tri.ages.length;
30
+ if (K < 2) {
31
+ throw new ReservingError("TOO_SMALL", "Mack requires at least two development ages");
32
+ }
33
+ const f = [];
34
+ const denomSums = [];
35
+ const counts = [];
36
+ for (let k = 0; k < K - 1; k++) {
37
+ let num = 0;
38
+ let den = 0;
39
+ let count = 0;
40
+ for (let i = 0; i < n; i++) {
41
+ const c0 = tri.values[i][k] ?? null;
42
+ const c1 = tri.values[i][k + 1] ?? null;
43
+ if (isNum(c0) && isNum(c1) && c0 > 0) {
44
+ num += c1;
45
+ den += c0;
46
+ count++;
47
+ }
48
+ }
49
+ if (den <= 0) {
50
+ throw new ReservingError("NO_FACTOR", `Development column ${tri.ages[k]}-${tri.ages[k + 1]} has no usable factors for Mack`);
51
+ }
52
+ f.push(num / den);
53
+ denomSums.push(den);
54
+ counts.push(count);
55
+ }
56
+ const sigma2 = new Array(K - 1).fill(null);
57
+ for (let k = 0; k < K - 1; k++) {
58
+ let sum = 0;
59
+ let count = 0;
60
+ for (let i = 0; i < n; i++) {
61
+ const c0 = tri.values[i][k] ?? null;
62
+ const c1 = tri.values[i][k + 1] ?? null;
63
+ if (isNum(c0) && isNum(c1) && c0 > 0) {
64
+ const F = c1 / c0;
65
+ sum += c0 * (F - f[k]) ** 2;
66
+ count++;
67
+ }
68
+ }
69
+ sigma2[k] = count > 1 ? sum / (count - 1) : null;
70
+ }
71
+ return { f, denomSums, counts, sigma2 };
72
+ }
73
+ /**
74
+ * Mack's sigma^2 extrapolation for columns the data cannot estimate (fewer
75
+ * than two observed factors - usually only the final column):
76
+ * sigma^2_k = min(sigma^4_{k-1} / sigma^2_{k-2}, sigma^2_{k-2}, sigma^2_{k-1}),
77
+ * Mack (1993), also eq. (4.1) of Merz-Wuthrich (2008). Shared by runMack and
78
+ * runMerzWuthrich so the two can never disagree on the final column.
79
+ *
80
+ * Takes the raw per-column estimates (null = not estimable) and returns the
81
+ * completed array; when the min-rule inputs are unavailable it falls back to
82
+ * the prior column's value, then 0, pushing a warning either way.
83
+ */
84
+ export function extrapolateSigma2(sigma2Raw, ages, warnings) {
85
+ const sigma2 = sigma2Raw.map((s) => (s === null ? NaN : s));
86
+ for (let k = 0; k < sigma2.length; k++) {
87
+ if (!Number.isNaN(sigma2[k]))
88
+ continue;
89
+ const s2a = k >= 2 ? sigma2[k - 2] : NaN;
90
+ const s2b = k >= 1 ? sigma2[k - 1] : NaN;
91
+ if (isNum(s2a) && isNum(s2b) && s2a > 0) {
92
+ sigma2[k] = Math.min((s2b * s2b) / s2a, Math.min(s2a, s2b));
93
+ }
94
+ else if (isNum(s2b)) {
95
+ sigma2[k] = s2b;
96
+ warnings.push(`sigma^2 for the ${ages[k]}-${ages[k + 1]} column could not use Mack's extrapolation; reused the prior column's value`);
97
+ }
98
+ else {
99
+ sigma2[k] = 0;
100
+ warnings.push(`sigma^2 for the ${ages[k]}-${ages[k + 1]} column is not estimable; set to 0 (standard errors understated)`);
101
+ }
102
+ }
103
+ return sigma2;
104
+ }
105
+ export function runMack(tri, options = {}) {
106
+ const n = tri.origins.length;
107
+ const K = tri.ages.length;
108
+ const warnings = [];
109
+ const estimators = mackEstimators(tri);
110
+ const f = estimators.f;
111
+ const denomSums = estimators.denomSums;
112
+ // Projection factors: the caller's selections when provided (nulls and
113
+ // non-positive values become 1.000, mirroring the chain ladder), else the
114
+ // volume-weighted estimates - which reproduces Mack (1993) exactly.
115
+ let fEff = f;
116
+ if (options.selected !== undefined) {
117
+ if (options.selected.length !== K - 1) {
118
+ throw new ReservingError("SELECTION_SHAPE", `Expected ${K - 1} LDF selections (one per development interval), got ${options.selected.length}`);
119
+ }
120
+ fEff = options.selected.map((s, k) => {
121
+ if (s === null || s === undefined)
122
+ return 1;
123
+ if (!isNum(s) || s <= 0) {
124
+ warnings.push(`Selected LDF for ${tri.ages[k]}-${tri.ages[k + 1]} months is not positive; treated as 1.000`);
125
+ return 1;
126
+ }
127
+ return s;
128
+ });
129
+ const differs = fEff.some((v, k) => Math.abs(v - f[k]) > 1e-9);
130
+ if (differs) {
131
+ warnings.push("Standard errors pair the selected development factors with sigma^2 estimated around the volume-weighted factors (Mack 1999)");
132
+ }
133
+ }
134
+ const tail = options.tailFactor ?? 1;
135
+ if (!isNum(tail) || tail <= 0) {
136
+ throw new ReservingError("BAD_TAIL", "Tail factor must be a positive number");
137
+ }
138
+ // sigma^2_k estimates: data-estimated where possible; Mack's extrapolation
139
+ // fills columns with a single factor (usually the last).
140
+ const sigma2 = extrapolateSigma2(estimators.sigma2, tri.ages, warnings);
141
+ // Tail step variance: extrapolate sigma^2 one more column by Mack's rule
142
+ // and reuse the final column's volume as its denominator (approximation).
143
+ let sigma2Tail = 0;
144
+ let denomTail = 0;
145
+ if (tail !== 1) {
146
+ const s2a = K >= 3 ? sigma2[K - 3] : NaN;
147
+ const s2b = sigma2[K - 2];
148
+ if (isNum(s2a) && isNum(s2b) && s2a > 0) {
149
+ sigma2Tail = Math.min((s2b * s2b) / s2a, Math.min(s2a, s2b));
150
+ }
151
+ else if (isNum(s2b)) {
152
+ sigma2Tail = s2b;
153
+ }
154
+ denomTail = denomSums[K - 2];
155
+ warnings.push("The tail step's standard-error contribution extrapolates sigma^2 beyond the observed columns and reuses the final column's volume; treat it as approximate (Mack 1999)");
156
+ }
157
+ // Project the full rectangle with the projection factors.
158
+ const projected = tri.values.map((row) => {
159
+ const out = new Array(K).fill(NaN);
160
+ const last = lastObservedIndex(row);
161
+ for (let j = 0; j <= last; j++)
162
+ out[j] = row[j] ?? NaN;
163
+ for (let j = last + 1; j < K; j++)
164
+ out[j] = out[j - 1] * fEff[j - 1];
165
+ return out;
166
+ });
167
+ const rows = [];
168
+ const mseByRow = new Array(n).fill(0);
169
+ for (let i = 0; i < n; i++) {
170
+ const last = lastObservedIndex(tri.values[i]);
171
+ if (last < 0)
172
+ continue;
173
+ const latest = tri.values[i][last];
174
+ const ultimate = projected[i][K - 1] * tail;
175
+ // mse(R_i) accumulated over the projected development range plus tail.
176
+ let mse = 0;
177
+ for (let k = last; k < K - 1; k++) {
178
+ const cik = projected[i][k];
179
+ if (!(cik > 0))
180
+ continue;
181
+ mse += ((sigma2[k] / fEff[k] ** 2) * (1 / cik + 1 / denomSums[k]));
182
+ }
183
+ if (tail !== 1 && projected[i][K - 1] > 0) {
184
+ mse += (sigma2Tail / tail ** 2) * (1 / projected[i][K - 1] + 1 / denomTail);
185
+ }
186
+ mse *= ultimate ** 2;
187
+ mseByRow[i] = mse;
188
+ const reserve = ultimate - latest;
189
+ rows.push({
190
+ origin: tri.origins[i],
191
+ latest,
192
+ ultimate,
193
+ reserve,
194
+ standardError: Math.sqrt(mse),
195
+ cv: reserve !== 0 ? Math.sqrt(mse) / reserve : null,
196
+ });
197
+ }
198
+ // Total mse: sum of row mse plus cross terms (Mack 1993 corollary). The
199
+ // tail step participates like one more development column.
200
+ let totalMse = 0;
201
+ for (let i = 0; i < n; i++)
202
+ totalMse += mseByRow[i];
203
+ for (let i = 0; i < n; i++) {
204
+ const lastI = lastObservedIndex(tri.values[i]);
205
+ if (lastI < 0 || (tail === 1 && lastI >= K - 1))
206
+ continue;
207
+ let laterUltimates = 0;
208
+ for (let j = i + 1; j < n; j++) {
209
+ if (lastObservedIndex(tri.values[j]) >= 0)
210
+ laterUltimates += projected[j][K - 1] * tail;
211
+ }
212
+ if (laterUltimates <= 0)
213
+ continue;
214
+ let inner = 0;
215
+ for (let k = lastI; k < K - 1; k++) {
216
+ inner += (2 * sigma2[k]) / fEff[k] ** 2 / denomSums[k];
217
+ }
218
+ if (tail !== 1) {
219
+ inner += (2 * sigma2Tail) / tail ** 2 / denomTail;
220
+ }
221
+ totalMse += projected[i][K - 1] * tail * laterUltimates * inner;
222
+ }
223
+ const totals = rows.reduce((acc, r) => ({
224
+ latest: acc.latest + r.latest,
225
+ ultimate: acc.ultimate + r.ultimate,
226
+ reserve: acc.reserve + r.reserve,
227
+ }), { latest: 0, ultimate: 0, reserve: 0 });
228
+ const totalSe = Math.sqrt(totalMse);
229
+ return {
230
+ method: "mack",
231
+ developmentFactors: fEff,
232
+ sigmaSquared: sigma2,
233
+ tailFactor: tail,
234
+ sigmaSquaredTail: tail !== 1 ? sigma2Tail : undefined,
235
+ rows,
236
+ totals: {
237
+ ...totals,
238
+ standardError: totalSe,
239
+ cv: totals.reserve !== 0 ? totalSe / totals.reserve : null,
240
+ },
241
+ warnings,
242
+ };
243
+ }
244
+ //# sourceMappingURL=mack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mack.js","sourceRoot":"","sources":["../src/mack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { MerzWuthrichResult, Triangle } from "./types.js";
2
+ /**
3
+ * Merz-Wuthrich (2008) one-year claims development result (CDR) msep.
4
+ *
5
+ * Source: Merz, M. & Wuthrich, M.V. (2008), "Modelling the Claims Development
6
+ * Result for Solvency Purposes", CAS E-Forum Fall 2008, 542-568. Implements
7
+ * Result 3.5's closed forms: eq. (3.17) per accident year and eq. (3.18) for
8
+ * the aggregate - the msep of the observable one-year CDR around 0, i.e. the
9
+ * Solvency II / SST one-year reserve-risk quantity. Everything is computable
10
+ * at time I from the observed triangle D_I alone: S_j^{I+1} = S_j^I +
11
+ * C_{I-j,j} adds only the current diagonal element, which is in D_I.
12
+ *
13
+ * Estimators are shared with runMack - volume-weighted fhat_j and Mack's
14
+ * sigma^2_j with the min-rule extrapolation for the final column, which is
15
+ * exactly the paper's eq. (4.1) - and Mack's full-runoff msep is computed via
16
+ * runMack so every row carries the one-year vs ultimate-view comparison.
17
+ *
18
+ * Constraints (Sec. 2 of the paper): the closed forms assume a regular
19
+ * run-off triangle with I = J - as many origin periods as development ages,
20
+ * every cell on or left of the latest diagonal observed and positive, and
21
+ * nothing observed beyond it. Violations throw ReservingError("SHAPE").
22
+ *
23
+ * Caveat: (3.17)/(3.18) are the paper's linear approximations (Appendix A)
24
+ * of the exact product-form formulas. They are the published, industry-
25
+ * standard form (the paper's Table 4 is produced by them), accurate when
26
+ * sigma^2_j / (fhat_j^2 C_{i,j}) << 1, which holds for typical triangles.
27
+ */
28
+ export declare function runMerzWuthrich(tri: Triangle): MerzWuthrichResult;
29
+ //# sourceMappingURL=merzWuthrich.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merzWuthrich.d.ts","sourceRoot":"","sources":["../src/merzWuthrich.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKhF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,kBAAkB,CAmHjE"}
@@ -0,0 +1,132 @@
1
+ import { ReservingError } from "./types.js";
2
+ import { extrapolateSigma2, mackEstimators, runMack } from "./mack.js";
3
+ import { isNum } from "./util.js";
4
+ /**
5
+ * Merz-Wuthrich (2008) one-year claims development result (CDR) msep.
6
+ *
7
+ * Source: Merz, M. & Wuthrich, M.V. (2008), "Modelling the Claims Development
8
+ * Result for Solvency Purposes", CAS E-Forum Fall 2008, 542-568. Implements
9
+ * Result 3.5's closed forms: eq. (3.17) per accident year and eq. (3.18) for
10
+ * the aggregate - the msep of the observable one-year CDR around 0, i.e. the
11
+ * Solvency II / SST one-year reserve-risk quantity. Everything is computable
12
+ * at time I from the observed triangle D_I alone: S_j^{I+1} = S_j^I +
13
+ * C_{I-j,j} adds only the current diagonal element, which is in D_I.
14
+ *
15
+ * Estimators are shared with runMack - volume-weighted fhat_j and Mack's
16
+ * sigma^2_j with the min-rule extrapolation for the final column, which is
17
+ * exactly the paper's eq. (4.1) - and Mack's full-runoff msep is computed via
18
+ * runMack so every row carries the one-year vs ultimate-view comparison.
19
+ *
20
+ * Constraints (Sec. 2 of the paper): the closed forms assume a regular
21
+ * run-off triangle with I = J - as many origin periods as development ages,
22
+ * every cell on or left of the latest diagonal observed and positive, and
23
+ * nothing observed beyond it. Violations throw ReservingError("SHAPE").
24
+ *
25
+ * Caveat: (3.17)/(3.18) are the paper's linear approximations (Appendix A)
26
+ * of the exact product-form formulas. They are the published, industry-
27
+ * standard form (the paper's Table 4 is produced by them), accurate when
28
+ * sigma^2_j / (fhat_j^2 C_{i,j}) << 1, which holds for typical triangles.
29
+ */
30
+ export function runMerzWuthrich(tri) {
31
+ const n = tri.origins.length;
32
+ const K = tri.ages.length;
33
+ if (n !== K) {
34
+ throw new ReservingError("SHAPE", `Merz-Wuthrich requires a square triangle (I = J): got ${n} origin periods by ${K} development ages`);
35
+ }
36
+ // Regularity: every cell on or left of the time-I diagonal must be observed
37
+ // and positive (the formulas divide by diagonal cells and the variance
38
+ // assumption needs C > 0); nothing may be observed beyond the diagonal.
39
+ for (let i = 0; i < n; i++) {
40
+ const row = tri.values[i] ?? [];
41
+ const diag = K - 1 - i;
42
+ for (let j = 0; j <= diag; j++) {
43
+ const v = row[j] ?? null;
44
+ if (!isNum(v) || v <= 0) {
45
+ throw new ReservingError("SHAPE", `Merz-Wuthrich requires every cell on or left of the latest diagonal to be observed and positive: origin ${tri.origins[i]} at age ${tri.ages[j]} months is ${isNum(v) ? "non-positive" : "missing"}`);
46
+ }
47
+ }
48
+ for (let j = diag + 1; j < K; j++) {
49
+ if (isNum(row[j] ?? null)) {
50
+ throw new ReservingError("SHAPE", `Merz-Wuthrich assumes a time-I snapshot: origin ${tri.origins[i]} has an observation beyond the latest diagonal at age ${tri.ages[j]} months`);
51
+ }
52
+ }
53
+ }
54
+ const warnings = [];
55
+ const estimators = mackEstimators(tri);
56
+ const f = estimators.f;
57
+ // S_j^I (2.9): column-j volume EXCLUDING the diagonal element C_{I-j,j}.
58
+ const sI = estimators.denomSums;
59
+ const sigma2 = extrapolateSigma2(estimators.sigma2, tri.ages, warnings);
60
+ const I = K - 1; // = J; row i's latest observed cell is column I - i.
61
+ // sjr(j) = sigmahat_j^2 / fhat_j^2, the paper's recurring ratio.
62
+ const sjr = sigma2.map((s2, j) => s2 / f[j] ** 2);
63
+ // S_j^{I+1} = S_j^I + C_{I-j,j} (2.10): INCLUDES the diagonal element.
64
+ const sIPlus1 = sI.map((s, j) => s + tri.values[I - j][j]);
65
+ // Chain ladder ultimates Chat_{i,J}^I (2.11).
66
+ const ultimates = tri.values.map((row, i) => {
67
+ let u = row[I - i];
68
+ for (let j = I - i; j < I; j++)
69
+ u *= f[j];
70
+ return u;
71
+ });
72
+ // Mack's ultimate-view msep on the identical estimators, for comparison.
73
+ const mack = runMack(tri);
74
+ const rows = [];
75
+ const msepByRow = new Array(n).fill(0);
76
+ // Estimation-error piece shared by (3.17) and (3.18)'s cross terms:
77
+ // sjr(I-i)/S_{I-i}^I + sum_{j=I-i+1}^{J-1} (C_{I-j,j}/S_j^{I+1}) sjr(j)/S_j^I
78
+ // (FIRST power of C_{I-j,j}/S_j^{I+1} - the Delta and Phi tails merge).
79
+ const estimationTerm = new Array(n).fill(0);
80
+ let totalReserve = 0;
81
+ for (let i = 0; i < n; i++) {
82
+ const d = I - i;
83
+ if (i > 0) {
84
+ let laterDiagonals = 0;
85
+ for (let j = d + 1; j <= I - 1; j++) {
86
+ laterDiagonals += (tri.values[I - j][j] / sIPlus1[j]) * (sjr[j] / sI[j]);
87
+ }
88
+ estimationTerm[i] = sjr[d] / sI[d] + laterDiagonals;
89
+ // (3.17): process term sjr(I-i)/C_{i,I-i} plus the estimation term.
90
+ msepByRow[i] = ultimates[i] ** 2 * (sjr[d] / tri.values[i][d] + estimationTerm[i]);
91
+ }
92
+ // i = 0 is fully developed: its CDR is identically 0 (the paper prints
93
+ // this row with reserve 0 and blank volatility cells).
94
+ const cdrMsepRoot = Math.sqrt(msepByRow[i]);
95
+ const mackMsepRoot = mack.rows[i].standardError;
96
+ const reserve = ultimates[i] - tri.values[i][d];
97
+ totalReserve += reserve;
98
+ rows.push({
99
+ origin: tri.origins[i],
100
+ reserve,
101
+ cdrMsepRoot,
102
+ mackMsepRoot,
103
+ oneYearRatio: mackMsepRoot > 0 ? cdrMsepRoot / mackMsepRoot : null,
104
+ });
105
+ }
106
+ // (3.18): aggregate = sum of the single-year mseps plus cross terms
107
+ // 2 * Chat_i * Chat_k over 0 < i < k <= I, each scaled by the estimation
108
+ // term of the EARLIER accident year i.
109
+ let totalMsep = msepByRow.reduce((a, b) => a + b, 0);
110
+ for (let i = 1; i < n; i++) {
111
+ let laterUltimates = 0;
112
+ for (let k = i + 1; k < n; k++)
113
+ laterUltimates += ultimates[k];
114
+ totalMsep += 2 * ultimates[i] * laterUltimates * estimationTerm[i];
115
+ }
116
+ const totalCdrMsepRoot = Math.sqrt(totalMsep);
117
+ const totalMackMsepRoot = mack.totals.standardError;
118
+ return {
119
+ method: "merzWuthrich",
120
+ developmentFactors: f,
121
+ sigmaSquared: sigma2,
122
+ rows,
123
+ totals: {
124
+ reserve: totalReserve,
125
+ cdrMsepRoot: totalCdrMsepRoot,
126
+ mackMsepRoot: totalMackMsepRoot,
127
+ oneYearRatio: totalMackMsepRoot > 0 ? totalCdrMsepRoot / totalMackMsepRoot : null,
128
+ },
129
+ warnings,
130
+ };
131
+ }
132
+ //# sourceMappingURL=merzWuthrich.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merzWuthrich.js","sourceRoot":"","sources":["../src/merzWuthrich.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import type { Triangle } from "./types.js";
2
+ /**
3
+ * Munich chain ladder, Quarg & Mack (2004): a paired paid/incurred projection
4
+ * that corrects each triangle's development factors with the momentary
5
+ * (paid/incurred) ratio, so the projected paid and incurred ultimates
6
+ * converge instead of preserving each accident year's (P/I) gap forever
7
+ * (the separate-chain-ladder problem, Sec 1.1.2 of the paper).
8
+ *
9
+ * Estimators (Sec 3.1, all reproduced against the paper's printed rows):
10
+ * - fhat^P/fhat^I: volume-weighted development factors (shared with Mack).
11
+ * - sigmahat: Mack variance estimators around fhat, denominator = pairs - 1.
12
+ * - qhat_s: incurred-weighted average (P/I) per column; its reciprocal
13
+ * estimates the conditional mean of (I/P).
14
+ * - rhohat^P_s / rhohat^I_s: Mack-style variance estimators for the ratio
15
+ * series, volume-weighted by paid resp. incurred, denominator = cells - 1.
16
+ * - lambda^P / lambda^I: slopes of the single regression line THROUGH THE
17
+ * ORIGIN over the pooled residual plots (factor residual vs preceding
18
+ * ratio residual, all development years at once). The lambdas equal the
19
+ * residual correlation coefficients, so weak correlation collapses MCL
20
+ * gracefully toward the separate chain ladder.
21
+ *
22
+ * Projection (Sec 3.1.2): the paid and incurred recursions run
23
+ * SIMULTANEOUSLY, cell by cell left to right, because each paid step needs
24
+ * the current projected (I/P) ratio and each incurred step the projected
25
+ * (P/I). Implemented in the multiplied-out form of Sec 3.2.1
26
+ * (P*f + lambda*(sigma/rho)*(I - P/q)), which needs no division by the
27
+ * projected paid/incurred value and therefore stays sensible when current
28
+ * paid is tiny or zero.
29
+ */
30
+ export interface MunichChainLadderOptions {
31
+ /**
32
+ * Explicit sigma (standard-deviation scale, same units as the printed
33
+ * sigmahat rows) for the FINAL development column, whose sigma is never
34
+ * estimable from a single factor. Quarg-Mack manually set both to 0.100
35
+ * in the paper's example. When omitted, the engine falls back to Mack's
36
+ * sigma^2 extrapolation rule (extrapolateSigma2); a warning is pushed
37
+ * either way, since the paper notes a sounder extrapolation should be
38
+ * used in practice.
39
+ */
40
+ lastColumnSigma?: {
41
+ paid?: number;
42
+ incurred?: number;
43
+ };
44
+ }
45
+ /** The four estimated-residual triangles (Sec 3.1.2), null where not estimable. */
46
+ export interface MunichChainLadderResiduals {
47
+ /** Reshat(P_{i,t}): paid development-factor residuals, [origin][step]. */
48
+ paidFactor: (number | null)[][];
49
+ /** Reshat(I_{i,t}): incurred development-factor residuals. */
50
+ incurredFactor: (number | null)[][];
51
+ /** Reshat(Q^-1_{i,s}): (I/P) ratio residuals, [origin][ageColumn]. */
52
+ paidRatio: (number | null)[][];
53
+ /** Reshat(Q_{i,s}): (P/I) ratio residuals. */
54
+ incurredRatio: (number | null)[][];
55
+ }
56
+ export interface MunichChainLadderRow {
57
+ origin: string;
58
+ paidLatest: number;
59
+ incurredLatest: number;
60
+ paidUltimate: number;
61
+ incurredUltimate: number;
62
+ /** Separate (plain volume-weighted) chain ladder ultimates for comparison. */
63
+ sclPaidUltimate: number;
64
+ sclIncurredUltimate: number;
65
+ /** MCL ultimate paid / ultimate incurred; null when incurred is not positive. */
66
+ finalRatio: number | null;
67
+ /** SCL ultimate paid / ultimate incurred (the gap MCL is built to close). */
68
+ sclFinalRatio: number | null;
69
+ }
70
+ export interface MunichChainLadderResult {
71
+ method: "munichChainLadder";
72
+ /** Volume-weighted fhat^P per development step. */
73
+ paidFactors: number[];
74
+ /** Volume-weighted fhat^I per development step. */
75
+ incurredFactors: number[];
76
+ /** sigmahat^P per step, after last-column fallback (see options). */
77
+ sigmaPaid: number[];
78
+ sigmaIncurred: number[];
79
+ /** qhat_s per age column; null where a column has no usable (P, I) pairs. */
80
+ qRatios: (number | null)[];
81
+ /** rhohat^P_s per age column; null where fewer than two pairs exist. */
82
+ rhoPaid: (number | null)[];
83
+ rhoIncurred: (number | null)[];
84
+ /** Through-origin regression slopes over the pooled residuals. */
85
+ lambdaPaid: number;
86
+ lambdaIncurred: number;
87
+ residuals: MunichChainLadderResiduals;
88
+ /** Full projected rectangles (observed cells passed through); null rows = skipped. */
89
+ projectedPaid: ((number | null)[] | null)[];
90
+ projectedIncurred: ((number | null)[] | null)[];
91
+ rows: MunichChainLadderRow[];
92
+ totals: {
93
+ paidUltimate: number;
94
+ incurredUltimate: number;
95
+ sclPaidUltimate: number;
96
+ sclIncurredUltimate: number;
97
+ };
98
+ warnings: string[];
99
+ }
100
+ export declare function runMunichChainLadder(paid: Triangle, incurred: Triangle, options?: MunichChainLadderOptions): MunichChainLadderResult;
101
+ //# sourceMappingURL=munichChainLadder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"munichChainLadder.d.ts","sourceRoot":"","sources":["../src/munichChainLadder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACxD;AAED,mFAAmF;AACnF,MAAM,WAAW,0BAA0B;IACzC,0EAA0E;IAC1E,UAAU,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAChC,8DAA8D;IAC9D,cAAc,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IACpC,sEAAsE;IACtE,SAAS,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAC/B,8CAA8C;IAC9C,aAAa,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iFAAiF;IACjF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,6EAA6E;IAC7E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,mDAAmD;IACnD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,mDAAmD;IACnD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,qEAAqE;IACrE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC3B,wEAAwE;IACxE,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC3B,WAAW,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC/B,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,0BAA0B,CAAC;IACtC,sFAAsF;IACtF,aAAa,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,iBAAiB,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IAChD,IAAI,EAAE,oBAAoB,EAAE,CAAC;IAC7B,MAAM,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CA2RzB"}