@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
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core domain types for the reserving engine.
|
|
3
|
+
*
|
|
4
|
+
* Triangle semantics (ground truth for the whole engine):
|
|
5
|
+
* - rows = origin periods, columns = development ages
|
|
6
|
+
* - cells not yet observable are null
|
|
7
|
+
* - every computation must be null-safe; division by a missing, zero, or
|
|
8
|
+
* negative denominator yields "no factor" (null), never an exception or NaN
|
|
9
|
+
*/
|
|
10
|
+
/** Cadence of origin periods. */
|
|
11
|
+
export type OriginCadence = "annual" | "quarterly";
|
|
12
|
+
/** The kinds of triangles the engine knows how to build and analyze. */
|
|
13
|
+
export type TriangleKind = "paid" | "incurred" | "caseReserve" | "reportedCount" | "openCount" | "closedCount" | "closedWithPayCount";
|
|
14
|
+
export interface Triangle {
|
|
15
|
+
kind: TriangleKind;
|
|
16
|
+
/** Human-readable origin period labels, ascending (e.g. "2019", "2021Q3"). */
|
|
17
|
+
origins: string[];
|
|
18
|
+
/** Development ages in months, ascending (e.g. [12, 24, 36] or [3, 6, 9]). */
|
|
19
|
+
ages: number[];
|
|
20
|
+
/** values[originIndex][ageIndex]; null = not yet observable / missing. */
|
|
21
|
+
values: (number | null)[][];
|
|
22
|
+
}
|
|
23
|
+
/** A single claim evaluation snapshot: one row per claim per evaluation date. */
|
|
24
|
+
export interface ClaimSnapshot {
|
|
25
|
+
claimId: string;
|
|
26
|
+
/** ISO date (yyyy-mm-dd) the loss occurred. */
|
|
27
|
+
accidentDate: string;
|
|
28
|
+
/** ISO date the claim was reported to the insurer. */
|
|
29
|
+
reportDate: string;
|
|
30
|
+
/** ISO date this snapshot was evaluated. */
|
|
31
|
+
evaluationDate: string;
|
|
32
|
+
/** Cumulative paid loss as of the evaluation date. */
|
|
33
|
+
paidToDate: number;
|
|
34
|
+
/** Outstanding case reserve as of the evaluation date. */
|
|
35
|
+
caseReserve: number;
|
|
36
|
+
/** Claim status as of the evaluation date. */
|
|
37
|
+
status: "open" | "closed";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Exposure data by origin period. A period may carry earned premium (the base
|
|
41
|
+
* for the loss-ratio method), exposure units (the base for the pure-premium
|
|
42
|
+
* method), or both. The reserving methods are base-agnostic: the caller feeds
|
|
43
|
+
* whichever base the chosen method uses into `earnedPremium`.
|
|
44
|
+
*/
|
|
45
|
+
export interface ExposureRecord {
|
|
46
|
+
/** Origin period label matching triangle origins (e.g. "2021" or "2021Q3"). */
|
|
47
|
+
origin: string;
|
|
48
|
+
/** Earned premium for the period (the loss-ratio base); null if not imported. */
|
|
49
|
+
earnedPremium: number | null;
|
|
50
|
+
/** Exposure units for the period (the pure-premium base); null if not imported. */
|
|
51
|
+
exposureUnits: number | null;
|
|
52
|
+
}
|
|
53
|
+
/** How a link-ratio average is computed for a development column. */
|
|
54
|
+
/**
|
|
55
|
+
* Keys of the standard averages menu (DEFAULT_AVERAGES). Custom AverageSpec
|
|
56
|
+
* keys remain legal; these are the ones every exhibit and consumer can rely
|
|
57
|
+
* on being present.
|
|
58
|
+
*/
|
|
59
|
+
export declare const AVERAGE_KEYS: readonly ["all-wtd", "all-str", "5-wtd", "5-str", "3-wtd", "3-str", "med-5x1", "geo-all"];
|
|
60
|
+
export type AverageKey = (typeof AVERAGE_KEYS)[number];
|
|
61
|
+
export interface AverageSpec {
|
|
62
|
+
/** One of AVERAGE_KEYS for the standard menu; custom keys are permitted. */
|
|
63
|
+
key: AverageKey | (string & {});
|
|
64
|
+
label: string;
|
|
65
|
+
kind: "straight" | "weighted" | "medial" | "geometric";
|
|
66
|
+
/** Number of most recent origin periods to include; omit for all-year. */
|
|
67
|
+
years?: number;
|
|
68
|
+
}
|
|
69
|
+
/** Age-to-age factors for one triangle. */
|
|
70
|
+
export interface DevelopmentFactors {
|
|
71
|
+
/** For column j: development from ages[j] to ages[j+1]. Length = ages.length - 1. */
|
|
72
|
+
fromAges: number[];
|
|
73
|
+
toAges: number[];
|
|
74
|
+
/** individual[originIndex][columnIndex]; null where not computable. */
|
|
75
|
+
individual: (number | null)[][];
|
|
76
|
+
/** Per-average-key, per-column computed averages; null where not computable. */
|
|
77
|
+
averages: {
|
|
78
|
+
spec: AverageSpec;
|
|
79
|
+
values: (number | null)[];
|
|
80
|
+
}[];
|
|
81
|
+
}
|
|
82
|
+
/** Per-column LDF selection made by the user or the advisor. */
|
|
83
|
+
export interface LdfSelections {
|
|
84
|
+
/** selected[j] = LDF for development column j; null = not selected. */
|
|
85
|
+
selected: (number | null)[];
|
|
86
|
+
tailFactor: number;
|
|
87
|
+
}
|
|
88
|
+
export interface ChainLadderRow {
|
|
89
|
+
origin: string;
|
|
90
|
+
/** Age (months) of the latest observed diagonal cell for this origin. */
|
|
91
|
+
latestAge: number;
|
|
92
|
+
/** Value on the latest observed diagonal. */
|
|
93
|
+
latestValue: number;
|
|
94
|
+
/** Cumulative development factor from latestAge to ultimate. */
|
|
95
|
+
cdf: number;
|
|
96
|
+
percentDeveloped: number;
|
|
97
|
+
ultimate: number;
|
|
98
|
+
/** ultimate - latestValue (IBNR on incurred basis; unpaid on paid basis). */
|
|
99
|
+
unpaid: number;
|
|
100
|
+
}
|
|
101
|
+
export interface ChainLadderResult {
|
|
102
|
+
method: "chainLadder";
|
|
103
|
+
basis: TriangleKind;
|
|
104
|
+
/** cdfs[j] = cumulative factor from ages[j] to ultimate (last = tail factor). */
|
|
105
|
+
cdfs: number[];
|
|
106
|
+
percentDeveloped: number[];
|
|
107
|
+
rows: ChainLadderRow[];
|
|
108
|
+
totals: {
|
|
109
|
+
latest: number;
|
|
110
|
+
ultimate: number;
|
|
111
|
+
unpaid: number;
|
|
112
|
+
};
|
|
113
|
+
warnings: string[];
|
|
114
|
+
}
|
|
115
|
+
export interface BornhuetterFergusonRow {
|
|
116
|
+
origin: string;
|
|
117
|
+
latestValue: number;
|
|
118
|
+
cdf: number;
|
|
119
|
+
/** A-priori expected loss ratio applied to the exposure base. */
|
|
120
|
+
aprioriLossRatio: number;
|
|
121
|
+
earnedPremium: number;
|
|
122
|
+
expectedUltimate: number;
|
|
123
|
+
expectedUnreported: number;
|
|
124
|
+
ultimate: number;
|
|
125
|
+
unpaid: number;
|
|
126
|
+
}
|
|
127
|
+
export interface BornhuetterFergusonResult {
|
|
128
|
+
method: "bornhuetterFerguson";
|
|
129
|
+
basis: TriangleKind;
|
|
130
|
+
rows: BornhuetterFergusonRow[];
|
|
131
|
+
totals: {
|
|
132
|
+
latest: number;
|
|
133
|
+
ultimate: number;
|
|
134
|
+
unpaid: number;
|
|
135
|
+
};
|
|
136
|
+
warnings: string[];
|
|
137
|
+
}
|
|
138
|
+
export type TailMethod = "exponentialDecay" | "inversePower";
|
|
139
|
+
export interface TailFit {
|
|
140
|
+
method: TailMethod;
|
|
141
|
+
/** ln(f-1) = intercept + slope * x, x = period index (exp) or ln(index) (power). */
|
|
142
|
+
intercept: number;
|
|
143
|
+
slope: number;
|
|
144
|
+
rSquared: number;
|
|
145
|
+
nPoints: number;
|
|
146
|
+
/** Individual extrapolated age-to-age factors beyond the last observed age. */
|
|
147
|
+
extrapolatedFactors: number[];
|
|
148
|
+
tailFactor: number;
|
|
149
|
+
valid: boolean;
|
|
150
|
+
warnings: string[];
|
|
151
|
+
}
|
|
152
|
+
export interface MackRow {
|
|
153
|
+
origin: string;
|
|
154
|
+
latest: number;
|
|
155
|
+
ultimate: number;
|
|
156
|
+
reserve: number;
|
|
157
|
+
standardError: number;
|
|
158
|
+
/** standardError / reserve; null when reserve is 0. */
|
|
159
|
+
cv: number | null;
|
|
160
|
+
}
|
|
161
|
+
export interface MackResult {
|
|
162
|
+
method: "mack";
|
|
163
|
+
/** The projection factors: selected LDFs when supplied, else volume-weighted. */
|
|
164
|
+
developmentFactors: number[];
|
|
165
|
+
sigmaSquared: number[];
|
|
166
|
+
/** Tail factor the projection used (1 = none). */
|
|
167
|
+
tailFactor?: number;
|
|
168
|
+
/** Extrapolated sigma^2 for the tail step; present only when a tail was applied. */
|
|
169
|
+
sigmaSquaredTail?: number;
|
|
170
|
+
rows: MackRow[];
|
|
171
|
+
totals: {
|
|
172
|
+
latest: number;
|
|
173
|
+
ultimate: number;
|
|
174
|
+
reserve: number;
|
|
175
|
+
standardError: number;
|
|
176
|
+
cv: number | null;
|
|
177
|
+
};
|
|
178
|
+
warnings: string[];
|
|
179
|
+
}
|
|
180
|
+
export interface MerzWuthrichRow {
|
|
181
|
+
origin: string;
|
|
182
|
+
/** Chain ladder reserve at time I (ultimate minus the latest diagonal). */
|
|
183
|
+
reserve: number;
|
|
184
|
+
/**
|
|
185
|
+
* sqrt of the one-year CDR msep (Merz-Wuthrich 2008, eq. 3.17): the
|
|
186
|
+
* prediction uncertainty of 0 for next year's observable claims
|
|
187
|
+
* development result - the Solvency II / SST one-year reserve risk.
|
|
188
|
+
*/
|
|
189
|
+
cdrMsepRoot: number;
|
|
190
|
+
/** sqrt of Mack's full-runoff msep for the same origin (ultimate view). */
|
|
191
|
+
mackMsepRoot: number;
|
|
192
|
+
/** cdrMsepRoot / mackMsepRoot; null when the Mack msep is 0. */
|
|
193
|
+
oneYearRatio: number | null;
|
|
194
|
+
}
|
|
195
|
+
export interface MerzWuthrichResult {
|
|
196
|
+
method: "merzWuthrich";
|
|
197
|
+
/** Volume-weighted development factors fhat_j estimated at time I. */
|
|
198
|
+
developmentFactors: number[];
|
|
199
|
+
/** sigma^2_j estimates; the final column uses Mack's extrapolation (4.1). */
|
|
200
|
+
sigmaSquared: number[];
|
|
201
|
+
rows: MerzWuthrichRow[];
|
|
202
|
+
totals: {
|
|
203
|
+
reserve: number;
|
|
204
|
+
/** Aggregate one-year msep root per eq. (3.18), cross terms included. */
|
|
205
|
+
cdrMsepRoot: number;
|
|
206
|
+
/** Mack's total full-runoff msep root, cross terms included. */
|
|
207
|
+
mackMsepRoot: number;
|
|
208
|
+
/** totals.cdrMsepRoot / totals.mackMsepRoot; null when the Mack total is 0. */
|
|
209
|
+
oneYearRatio: number | null;
|
|
210
|
+
};
|
|
211
|
+
warnings: string[];
|
|
212
|
+
}
|
|
213
|
+
export interface BerquistCaseAdequacyResult {
|
|
214
|
+
/** Average open case reserve per open claim, by cell. */
|
|
215
|
+
averageCaseReserves: (number | null)[][];
|
|
216
|
+
/** Annual severity trend used to restate historical average case reserves. */
|
|
217
|
+
severityTrend: number;
|
|
218
|
+
/** Whether the trend was fitted from the data or supplied by the user. */
|
|
219
|
+
trendSource: "fitted" | "user";
|
|
220
|
+
restatedAverageCaseReserves: (number | null)[][];
|
|
221
|
+
/** paid + restated average case reserve x open counts. */
|
|
222
|
+
adjustedIncurred: Triangle;
|
|
223
|
+
warnings: string[];
|
|
224
|
+
}
|
|
225
|
+
export interface BerquistSettlementResult {
|
|
226
|
+
/** disposal[i][j] = closed counts / ultimate counts for origin i. */
|
|
227
|
+
disposalRates: (number | null)[][];
|
|
228
|
+
/** Selected disposal rate per age (latest diagonal). */
|
|
229
|
+
selectedDisposalRates: (number | null)[];
|
|
230
|
+
ultimateCounts: number[];
|
|
231
|
+
adjustedClosedCounts: (number | null)[][];
|
|
232
|
+
interpolation: "exponential" | "linear";
|
|
233
|
+
adjustedPaid: Triangle;
|
|
234
|
+
warnings: string[];
|
|
235
|
+
}
|
|
236
|
+
export interface CalendarYearDiagnostic {
|
|
237
|
+
/** One entry per calendar-period diagonal that has testable factors. */
|
|
238
|
+
diagonals: {
|
|
239
|
+
label: string;
|
|
240
|
+
countLarge: number;
|
|
241
|
+
countSmall: number;
|
|
242
|
+
z: number;
|
|
243
|
+
expectedZ: number;
|
|
244
|
+
varianceZ: number;
|
|
245
|
+
}[];
|
|
246
|
+
totalZ: number;
|
|
247
|
+
expectedTotalZ: number;
|
|
248
|
+
varianceTotalZ: number;
|
|
249
|
+
/** Total Z outside the 95% confidence range indicates calendar-year effects. */
|
|
250
|
+
significant: boolean;
|
|
251
|
+
confidenceInterval: [number, number];
|
|
252
|
+
}
|
|
253
|
+
export interface DiagnosticsResult {
|
|
254
|
+
paidToIncurredRatios: (number | null)[][];
|
|
255
|
+
averageCaseReserves: (number | null)[][];
|
|
256
|
+
/** closed / reported counts by cell. */
|
|
257
|
+
closureRates: (number | null)[][];
|
|
258
|
+
calendarYearTest: CalendarYearDiagnostic | null;
|
|
259
|
+
/** Human-readable findings an actuary would care about. */
|
|
260
|
+
findings: DiagnosticFinding[];
|
|
261
|
+
}
|
|
262
|
+
export interface DiagnosticFinding {
|
|
263
|
+
severity: "info" | "warning" | "critical";
|
|
264
|
+
code: string;
|
|
265
|
+
message: string;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Every machine-readable code a ReservingError can carry. This registry is
|
|
269
|
+
* public contract: consumers may switch exhaustively on ReservingErrorCode,
|
|
270
|
+
* and test/registry.test.ts enforces that the list matches every constructor
|
|
271
|
+
* site in source. Add the code here when introducing a new throw.
|
|
272
|
+
*/
|
|
273
|
+
export declare const RESERVING_ERROR_CODES: readonly ["BAD_ADJ", "BAD_CAP", "BAD_CASHFLOWS", "BAD_CDF", "BAD_COUNTS", "BAD_DATE", "BAD_ELR", "BAD_FIT", "BAD_LIMIT", "BAD_LOSSES", "BAD_MARGIN", "BAD_ORIGIN", "BAD_PERCENTILE", "BAD_PREMIUM", "BAD_RATE", "BAD_RATE_CHANGE", "BAD_RATIO", "BAD_SEED", "BAD_SHAPE", "BAD_TABLE", "BAD_TAIL", "BAD_TREND", "BAD_WEIGHTS", "INFINITE_MEAN", "NO_APRIORI", "NO_BF_ROWS", "NO_CLAIMS", "NO_DATA", "NO_DEVELOPMENT", "NO_FACTOR", "NO_PROVENANCE", "NO_SELECTIONS", "SELECTION_SHAPE", "SHAPE", "TABLE_RANGE", "TOO_SMALL"];
|
|
274
|
+
export type ReservingErrorCode = (typeof RESERVING_ERROR_CODES)[number];
|
|
275
|
+
/** Thrown for invalid analysis input (all-missing selections, shape mismatches). */
|
|
276
|
+
export declare class ReservingError extends Error {
|
|
277
|
+
readonly code: ReservingErrorCode;
|
|
278
|
+
constructor(code: ReservingErrorCode, message: string);
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core domain types for the reserving engine.
|
|
3
|
+
*
|
|
4
|
+
* Triangle semantics (ground truth for the whole engine):
|
|
5
|
+
* - rows = origin periods, columns = development ages
|
|
6
|
+
* - cells not yet observable are null
|
|
7
|
+
* - every computation must be null-safe; division by a missing, zero, or
|
|
8
|
+
* negative denominator yields "no factor" (null), never an exception or NaN
|
|
9
|
+
*/
|
|
10
|
+
/** How a link-ratio average is computed for a development column. */
|
|
11
|
+
/**
|
|
12
|
+
* Keys of the standard averages menu (DEFAULT_AVERAGES). Custom AverageSpec
|
|
13
|
+
* keys remain legal; these are the ones every exhibit and consumer can rely
|
|
14
|
+
* on being present.
|
|
15
|
+
*/
|
|
16
|
+
export const AVERAGE_KEYS = [
|
|
17
|
+
"all-wtd",
|
|
18
|
+
"all-str",
|
|
19
|
+
"5-wtd",
|
|
20
|
+
"5-str",
|
|
21
|
+
"3-wtd",
|
|
22
|
+
"3-str",
|
|
23
|
+
"med-5x1",
|
|
24
|
+
"geo-all",
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* Every machine-readable code a ReservingError can carry. This registry is
|
|
28
|
+
* public contract: consumers may switch exhaustively on ReservingErrorCode,
|
|
29
|
+
* and test/registry.test.ts enforces that the list matches every constructor
|
|
30
|
+
* site in source. Add the code here when introducing a new throw.
|
|
31
|
+
*/
|
|
32
|
+
export const RESERVING_ERROR_CODES = [
|
|
33
|
+
"BAD_ADJ",
|
|
34
|
+
"BAD_CAP",
|
|
35
|
+
"BAD_CASHFLOWS",
|
|
36
|
+
"BAD_CDF",
|
|
37
|
+
"BAD_COUNTS",
|
|
38
|
+
"BAD_DATE",
|
|
39
|
+
"BAD_ELR",
|
|
40
|
+
"BAD_FIT",
|
|
41
|
+
"BAD_LIMIT",
|
|
42
|
+
"BAD_LOSSES",
|
|
43
|
+
"BAD_MARGIN",
|
|
44
|
+
"BAD_ORIGIN",
|
|
45
|
+
"BAD_PERCENTILE",
|
|
46
|
+
"BAD_PREMIUM",
|
|
47
|
+
"BAD_RATE",
|
|
48
|
+
"BAD_RATE_CHANGE",
|
|
49
|
+
"BAD_RATIO",
|
|
50
|
+
"BAD_SEED",
|
|
51
|
+
"BAD_SHAPE",
|
|
52
|
+
"BAD_TABLE",
|
|
53
|
+
"BAD_TAIL",
|
|
54
|
+
"BAD_TREND",
|
|
55
|
+
"BAD_WEIGHTS",
|
|
56
|
+
"INFINITE_MEAN",
|
|
57
|
+
"NO_APRIORI",
|
|
58
|
+
"NO_BF_ROWS",
|
|
59
|
+
"NO_CLAIMS",
|
|
60
|
+
"NO_DATA",
|
|
61
|
+
"NO_DEVELOPMENT",
|
|
62
|
+
"NO_FACTOR",
|
|
63
|
+
"NO_PROVENANCE",
|
|
64
|
+
"NO_SELECTIONS",
|
|
65
|
+
"SELECTION_SHAPE",
|
|
66
|
+
"SHAPE",
|
|
67
|
+
"TABLE_RANGE",
|
|
68
|
+
"TOO_SMALL",
|
|
69
|
+
];
|
|
70
|
+
/** Thrown for invalid analysis input (all-missing selections, shape mismatches). */
|
|
71
|
+
export class ReservingError extends Error {
|
|
72
|
+
code;
|
|
73
|
+
constructor(code, message) {
|
|
74
|
+
super(message);
|
|
75
|
+
this.name = "ReservingError";
|
|
76
|
+
this.code = code;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyDH,qEAAqE;AACrE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,SAAS;IACT,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,SAAS;IACT,SAAS;CACD,CAAC;AAyNX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,SAAS;IACT,SAAS;IACT,eAAe;IACf,SAAS;IACT,YAAY;IACZ,UAAU;IACV,SAAS;IACT,SAAS;IACT,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,gBAAgB;IAChB,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,WAAW;IACX,UAAU;IACV,WAAW;IACX,WAAW;IACX,UAAU;IACV,WAAW;IACX,aAAa;IACb,eAAe;IACf,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,SAAS;IACT,gBAAgB;IAChB,WAAW;IACX,eAAe;IACf,eAAe;IACf,iBAAiB;IACjB,OAAO;IACP,aAAa;IACb,WAAW;CACH,CAAC;AAIX,oFAAoF;AACpF,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,CAAqB;IAClC,YAAY,IAAwB,EAAE,OAAe;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/ulae.d.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ULAE reserving per Conger & Nolibos (2003), "Estimating ULAE Liabilities:
|
|
3
|
+
* Rediscovering and Expanding Kittel's Approach" (CAS Forum Fall 2003).
|
|
4
|
+
*
|
|
5
|
+
* The generalized framework splits ultimate ULAE into shares spent OPENING
|
|
6
|
+
* (u1), MAINTAINING (u2) and CLOSING (u3) claims, u1 + u2 + u3 = 1, and
|
|
7
|
+
* attaches each share to a calendar-period loss measure:
|
|
8
|
+
*
|
|
9
|
+
* - u1 <-> R: the ULTIMATE cost of claims REPORTED during the period,
|
|
10
|
+
* - u2 <-> P: the losses PAID during the period,
|
|
11
|
+
* - u3 <-> C: the ULTIMATE cost of claims CLOSED during the period.
|
|
12
|
+
*
|
|
13
|
+
* Core identity: M = W x B with loss basis B = u1 R + u2 P + u3 C, so the
|
|
14
|
+
* observed calendar-period ULAE ratio is W = M / B ("losses" always means
|
|
15
|
+
* losses + ALAE). The actuary reviews W by period, selects W*, and books one
|
|
16
|
+
* of the paper's three reserve forms (the Bornhuetter-Ferguson form is their
|
|
17
|
+
* recommended default).
|
|
18
|
+
*
|
|
19
|
+
* Special cases (see ULAE_WEIGHT_PRESETS): Kittel's refined method is
|
|
20
|
+
* u = (50%, 0, 50%) with R = reported and C = paid losses (its no-partial-
|
|
21
|
+
* payment / no-development assumptions); the classical paid-to-paid method
|
|
22
|
+
* adds the steady-state identity R = P = C, collapsing the basis to paid
|
|
23
|
+
* losses alone.
|
|
24
|
+
*
|
|
25
|
+
* Validation choices (documented per the phase plan):
|
|
26
|
+
* - weights must be finite, each within [0, 1], and sum to 1 (1e-6
|
|
27
|
+
* tolerance) -> BAD_WEIGHTS;
|
|
28
|
+
* - monetary amounts (M, R, P, C, L and their to-date counterparts) must be
|
|
29
|
+
* finite and non-negative -> BAD_LOSSES;
|
|
30
|
+
* - the selected ratio W* must be finite and non-negative -> BAD_RATIO;
|
|
31
|
+
* - a non-positive PER-PERIOD basis yields W = null with a warning (house
|
|
32
|
+
* null-safety: division by a non-positive denominator is "no factor",
|
|
33
|
+
* never an exception), but a reserve that cannot be formed at all (empty
|
|
34
|
+
* periods, missing measures for a positive weight, development form with
|
|
35
|
+
* a non-positive basis) throws NO_DATA.
|
|
36
|
+
*/
|
|
37
|
+
export interface UlaeWeights {
|
|
38
|
+
/** Share of ultimate ULAE spent opening claims (attaches to R). */
|
|
39
|
+
u1: number;
|
|
40
|
+
/** Share spent maintaining claims (attaches to paid losses P). */
|
|
41
|
+
u2: number;
|
|
42
|
+
/** Share spent closing claims (attaches to C). */
|
|
43
|
+
u3: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* How the calendar-period loss basis is formed:
|
|
47
|
+
* - "weighted": B = u1 R + u2 P + u3 C (the generalized framework);
|
|
48
|
+
* - "paid": B = P, the classical method's steady-state simplification
|
|
49
|
+
* (R = P = C for a book in steady state, pp. 98-99 of the paper).
|
|
50
|
+
*/
|
|
51
|
+
export type UlaeBasisKind = "weighted" | "paid";
|
|
52
|
+
/**
|
|
53
|
+
* Weight presets from the paper. The GENERALIZED method is any caller-chosen
|
|
54
|
+
* triple (there is no handbook of u-values; the paper develops them by
|
|
55
|
+
* interviewing claims personnel), so it deliberately has no preset entry.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ULAE_WEIGHT_PRESETS: {
|
|
58
|
+
/**
|
|
59
|
+
* Kittel's refined method: 50% opening / 50% closing, with the caller
|
|
60
|
+
* supplying R = reported losses and C = paid losses per Kittel's
|
|
61
|
+
* assumptions (no partial payments or reopenings, no future development).
|
|
62
|
+
* W = M / (50% x (paid + reported)).
|
|
63
|
+
*/
|
|
64
|
+
readonly kittel: {
|
|
65
|
+
readonly weights: {
|
|
66
|
+
readonly u1: 0.5;
|
|
67
|
+
readonly u2: 0;
|
|
68
|
+
readonly u3: 0.5;
|
|
69
|
+
};
|
|
70
|
+
readonly basis: "weighted";
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Classical paid-to-paid: the same 50/50 lifecycle assumption plus the
|
|
74
|
+
* steady-state identity R = P = C, which collapses the basis to paid
|
|
75
|
+
* losses: W = M / P. Reserve = W* x (IBNR + 50% x case reserves).
|
|
76
|
+
*/
|
|
77
|
+
readonly classicalPaidToPaid: {
|
|
78
|
+
readonly weights: {
|
|
79
|
+
readonly u1: 0.5;
|
|
80
|
+
readonly u2: 0;
|
|
81
|
+
readonly u3: 0.5;
|
|
82
|
+
};
|
|
83
|
+
readonly basis: "paid";
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
/** One calendar period's inputs (all amounts for the period, not cumulative). */
|
|
87
|
+
export interface UlaePeriodInput {
|
|
88
|
+
label: string;
|
|
89
|
+
/** M: ULAE paid during the period. */
|
|
90
|
+
ulaePaid: number;
|
|
91
|
+
/** R: ultimate cost of claims reported during the period. */
|
|
92
|
+
reportedUltimate: number;
|
|
93
|
+
/** P: losses paid during the period. */
|
|
94
|
+
paid: number;
|
|
95
|
+
/** C: ultimate cost of claims closed during the period. */
|
|
96
|
+
closedUltimate: number;
|
|
97
|
+
}
|
|
98
|
+
export interface UlaeRatioRow {
|
|
99
|
+
label: string;
|
|
100
|
+
ulaePaid: number;
|
|
101
|
+
/** B = u1 R + u2 P + u3 C (or P under the "paid" basis). */
|
|
102
|
+
basis: number;
|
|
103
|
+
/** W = M / B; null when the basis is not positive. */
|
|
104
|
+
ratio: number | null;
|
|
105
|
+
}
|
|
106
|
+
export interface UlaeRatiosResult {
|
|
107
|
+
weights: UlaeWeights;
|
|
108
|
+
basis: UlaeBasisKind;
|
|
109
|
+
rows: UlaeRatioRow[];
|
|
110
|
+
totals: {
|
|
111
|
+
ulaePaid: number;
|
|
112
|
+
basis: number;
|
|
113
|
+
ratio: number | null;
|
|
114
|
+
};
|
|
115
|
+
warnings: string[];
|
|
116
|
+
}
|
|
117
|
+
export type UlaeReserveForm = "expected" | "bornhuetterFerguson" | "development";
|
|
118
|
+
export interface UlaeReserveInput {
|
|
119
|
+
/** W*: the selected ratio of ultimate ULAE to the loss basis. */
|
|
120
|
+
selectedW: number;
|
|
121
|
+
/** L: independently estimated ultimate losses for the reserved group. */
|
|
122
|
+
ultimateLosses: number;
|
|
123
|
+
/** R(t): ultimate cost of claims reported as of the evaluation date. Required when u1 > 0. */
|
|
124
|
+
reportedToDate?: number;
|
|
125
|
+
/** P(t): losses paid as of the evaluation date. Required when u2 > 0. */
|
|
126
|
+
paidToDate?: number;
|
|
127
|
+
/** C(t): ultimate cost of claims closed as of the evaluation date. Required when u3 > 0. */
|
|
128
|
+
closedToDate?: number;
|
|
129
|
+
/** M(t): ULAE paid to date. Required for the expected and development forms. */
|
|
130
|
+
ulaePaidToDate?: number;
|
|
131
|
+
weights: UlaeWeights;
|
|
132
|
+
form: UlaeReserveForm;
|
|
133
|
+
}
|
|
134
|
+
export interface UlaeReserveResult {
|
|
135
|
+
form: UlaeReserveForm;
|
|
136
|
+
/** The indicated unpaid ULAE. */
|
|
137
|
+
unpaidUlae: number;
|
|
138
|
+
/** B(t) = u1 R(t) + u2 P(t) + u3 C(t); null when a needed measure was omitted. */
|
|
139
|
+
basisToDate: number | null;
|
|
140
|
+
/**
|
|
141
|
+
* The Bornhuetter-Ferguson form's split (opening = W* u1 (L - R(t)),
|
|
142
|
+
* maintaining = W* u2 (L - P(t)), closing = W* u3 (L - C(t))); null for
|
|
143
|
+
* the other forms.
|
|
144
|
+
*/
|
|
145
|
+
components: {
|
|
146
|
+
opening: number;
|
|
147
|
+
maintaining: number;
|
|
148
|
+
closing: number;
|
|
149
|
+
} | null;
|
|
150
|
+
warnings: string[];
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Calendar-period ULAE ratios W = M / B (the paper's Exhibits B-F machinery).
|
|
154
|
+
* Pass opts.basis = "paid" for the classical paid-to-paid collapse.
|
|
155
|
+
*/
|
|
156
|
+
export declare function ulaeRatios(periods: UlaePeriodInput[], weights: UlaeWeights, opts?: {
|
|
157
|
+
basis?: UlaeBasisKind;
|
|
158
|
+
}): UlaeRatiosResult;
|
|
159
|
+
/**
|
|
160
|
+
* The paper's three reserve forms (pp. 113-115), analogous to expected-loss /
|
|
161
|
+
* Bornhuetter-Ferguson / development loss reserving:
|
|
162
|
+
*
|
|
163
|
+
* - "expected": unpaid = W* L - M(t)
|
|
164
|
+
* - "bornhuetterFerguson": unpaid = W* [u1 (L - R(t)) + u2 (L - P(t)) + u3 (L - C(t))]
|
|
165
|
+
* = W* (L - B(t)) -- the paper's recommended default
|
|
166
|
+
* - "development": unpaid = M(t) (L / B(t) - 1)
|
|
167
|
+
*
|
|
168
|
+
* With Kittel's weights (50/0/50) and C(t) = P(t) the B-F form reduces to
|
|
169
|
+
* W* x (IBNR + 50% x case reserves) - the Kittel identity.
|
|
170
|
+
*/
|
|
171
|
+
export declare function ulaeReserve(input: UlaeReserveInput): UlaeReserveResult;
|
|
172
|
+
//# sourceMappingURL=ulae.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ulae.d.ts","sourceRoot":"","sources":["../src/ulae.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;IAC9B;;;;;OAKG;;;;;;;;;IAEH;;;;OAIG;;;;;;;;;CAEK,CAAC;AAEX,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,qBAAqB,GAAG,aAAa,CAAC;AAEjF,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAgCD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,EAAE,WAAW,EACpB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,aAAa,CAAA;CAAO,GACnC,gBAAgB,CAsClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CA6FtE"}
|