@actuarial-ts/core
v0.16.0
Published
Pure, zero-dependency P&C actuarial math for TypeScript: reserving, generalized definition-driven diagnostics, trends, limits, discounting, and seeded stochastic methods with published-value validation.
Maintainers
Readme
@actuarial-ts/core
Frozen prior-model forecasts and explicit scoring vintages are available through createModelForecast and scoreModelForecast. They preserve missingness and separate later restatements from actual emergence. Shared A/E arithmetic now lives in core. See docs/reference/review-forecasts.md in the private repository.
resolveHistoricalInformationSet selects declared immutable input versions using availability evidence and exact dependencies. Missing dates require an explicit retrospective policy or an unavailable result. Its catalog-level assurance does not certify a full historical fold; see docs/reference/historical-information.md in the private repository.
prepareHistoricalReview connects selected configuration to actual loss/exposure revision clocks and the existing recipe engine. runHistoricalFold and runHistoricalStudy compose dated policy/assumption bindings, explicit prior calibration, frozen forecasts and scoring. Tuning uses, unavailable folds and changes to fixed assumptions remain visible; holdout independence is not inferred.
Pure, framework-free P&C actuarial math for TypeScript. It includes triangles, deterministic and stochastic reserving, trends/on-leveling, limits and ILFs, discounting, and generalized definition-driven casualty diagnostics.
The SDK 0.16 selectDevelopmentPattern and replayDevelopmentSelection APIs
bind explicit averaging/tail intent to native calculations and versioned
assumptions. The same operation feeds review graphs and factor-intent
sensitivities, including monthly and quarterly origin windows. See
docs/reference/review-development-selection.md in the private repository.
The SDK 0.16 createSelectedEstimateRange and
replaySelectedEstimateRange APIs retain finite ordered endpoints with exactly
matching quantity semantics, exact supporting result references, rationale,
authorship and optional caller-declared materiality. The contract identifies a
human-selected nonprobabilistic range; it does not manufacture a predictive
interval or choose the actuarial judgment.
The SDK 0.16 tailFitting capability exposes fitDevelopmentPatternTail
through that same selection calculation and replay artifact. It requires an
explicit curve family, fit window, regular period-index convention and horizon.
Invalid fits keep the selected tail unavailable; truncated fits retain warnings.
Fitting does not invent adoption or predictive uncertainty.
The SDK 0.16 calculateReviewOnLevel API binds earned monetary premium to
explicit earning intervals, a target date and historically available rate
history. Its calculated factors feed BF/Cape Cod, selection, reconciliation,
sensitivity and historical scoring through the shared review graph. Annual
policy terms and uniform writing/earning remain required. Model-derived BF
prior calibration on adjusted premium needs a separate denominator contract
and is explicitly unsupported. See docs/reference/review-foundations.md in
the private repository for clocks, missingness and exact replay requirements.
The SDK 0.16 calculateReviewLayerApplication, calibrateReviewIlf and
applyReviewIlf APIs connect exact claim, occurrence or policy financial-term
evidence to fitted or versioned-table layer restoration and a broader-basis
origin series. Complete population and membership detail are required; an
aggregate triangle is not substituted. Calculated outputs can enter selection
through exact replay. Source authenticity and uncertainty propagation remain
explicitly unavailable. See docs/reference/review-capping-ilf.md in the
private repository.
The SDK 0.16 frequencySeverity model uses explicit reported-count and
loss-per-count patterns, tails, count definitions and paired source clocks.
Both component fits and actual observation maturities remain visible. A missing
current loss leaves current unpaid unavailable. Count/scaled severity quantities,
historical catalog bindings, graph selection/reconciliation and portable replay
use the same connected review contracts. Combined uncertainty is unavailable;
emergence forecasting requires an explicit pattern convention.
The SDK 0.16 connected munichChainLadder model binds exact paid and incurred
sources to the existing Quarg–Mack kernel. It requires identical dated grids and
missing masks, both source revisions, an explicit final-column sigma policy and
no tail. Both native projections and their factor/ratio/residual sample counts
remain visible; the declared primary basis feeds comparison, selection and
paid reconciliation. True cumulative age zero is always zero and stays outside
the fit. Prediction-error uncertainty is explicitly unavailable. See
docs/reference/review-munich-chain-ladder.md in the private repository.
The SDK 0.16 connected caseOutstanding model binds exact cumulative paid
and point-in-time case sources to an adopted complete case run-off,
paid-on-prior-case and terminal payout pattern. It projects from the latest
joint observation, keeps missing origins unavailable, qualifies negative case
or recovery positions under explicit policies and retains the native payment
path. True cumulative age zero is numeric zero by definition; origin ID "0"
is ordinary. Deterministic uncertainty remains unavailable. See
docs/reference/review-case-outstanding.md in the private repository.
The SDK 0.16 connected fisherLange model binds exact cumulative paid and
cumulative closed-count sources to adopted ultimate counts, a complete unit-sum
disposal pattern and a common annual severity trend. It requires a regular
contiguous origin/development cadence, projects from the latest joint maturity,
rejects count reversals and needed ages without observed severity, and governs
negative paid increments explicitly. True cumulative age zero is numeric zero
by definition; origin ID "0" remains an ordinary cohort label. The result
retains native age evidence and exact effective assumptions; deterministic
uncertainty remains unavailable. See docs/reference/review-fisher-lange.md in
the private repository.
The SDK 0.16 calibrateReviewUlae and calculateReviewUlaeReserve APIs bind
the native Conger–Nolibos calculations to exact calendar sources, disjoint loss
and expense bases, explicit populations, versioned activity weights and a
versioned selected ratio. Expected, Bornhuetter–Ferguson and development forms
preserve missing origin inputs and their native activity components. A replayed
expense reserve can enter selection as calculated evidence. Source membership
and uncertainty remain explicit limitations. See
docs/reference/review-ulae.md in the private repository.
The SDK 0.16 calculateReviewDiscounting API replays a nominal unpaid origin
series, ties explicit valuation-relative cash flows to every available amount,
and applies versioned annual-effective flat or spot rates through the native
present-value kernel. Intended purpose, discount/accounting dates, payout and
rate sources, timing convention, curve-horizon policy and risk-margin treatment
remain inspectable. Nominal and discounted quantities stay side by side; an
explicit risk margin stays outside every total. See
docs/reference/review-discounting.md in the private repository.
The package is designed to support the actuary's compliance with the ASOPs; it does not make a work product compliant and is not “ASOP-approved.” The credentialed actuary remains responsible for data, assumptions, selections, review, and communication.
The SDK 0.16 connected workflow has a tested public consumer at
examples/reserve-review in the private repository. It demonstrates annual
premium and quarterly vehicle-year inputs, raw-grid normalization inside the
replayed graph, CL/BF/Cape Cod/Mack comparison, explicit cohort weighting and
paid reconciliation. Its synthetic assumptions are separate from the existing
Mack literature example; unavailable evidence and blend uncertainty stay visible.
The source repository is private, so the guide and reference links below open only with repository access. The published package is unaffected and remains Apache-2.0.
SDK 0.8 adds versioned loss history, irregular period and exposure contracts,
population statistics, shared financial terms, and deterministic recipe and
scenario execution. See the 0.8 adoption guide (docs/migrations/0.8-reusable-customization.md)
and customization reference (docs/reference/reusable-customization.md).
Install
npm install @actuarial-ts/[email protected]ESM, TypeScript-first, zero runtime dependencies, Node 20+.
Reserving quick start
import { buildTriangles, computeDevelopmentFactors, runChainLadder, runMack } from "@actuarial-ts/core";
const { paid } = buildTriangles(claimSnapshots, { cadence: "annual", asOfDate: "2025-12-31" });
const selected = computeDevelopmentFactors(paid).averages.find((item) => item.spec.key === "all-wtd")!.values;
const chainLadder = runChainLadder(paid, { selected, tailFactor: 1.02 });
const mack = runMack(paid, { selected, tailFactor: 1.02 });Unobservable triangle cells are null. Volume-weighted factors are sum/sum over rows where both cells exist. CDFs multiply right-to-left, tail last. Missing, zero, or negative divisors yield null, never NaN.
Generalized diagnostics
The model deliberately separates five concerns:
- A measure declares source, quantity kind, unit, development semantics, sum aggregation, missingness, and its population/basis.
- A formula template declares reusable arithmetic over typed roles.
- An instance binds formula roles to measure expressions.
- Calculation identity covers arithmetic, bindings, and all dependent measure/population/basis semantics.
- Presentation and review rules remain visible in full definition identity without pretending to change the arithmetic.
import {
CASUALTY_FORMULA_TEMPLATES,
compileDiagnosticDefinition,
createCasualtyMetricInstances,
prepareDiagnosticData,
runMetricDiagnostics,
} from "@actuarial-ts/core";
const instances = createCasualtyMetricInstances({
counts: { reported: "reported", open: "open", closedNoPay: "closed-no-pay", closedWithPay: "closed-with-pay" },
exposure: "earned-vehicle-years",
amountBindings: [
{ id: "gross", paid: "gross-paid", incurred: "gross-incurred" },
{ id: "primary-250k", paid: "primary-paid", incurred: "primary-incurred" },
],
});
const compiled = compileDiagnosticDefinition({
diagnosticDefinitionVersion: "1.0.0",
id: "fleet-diagnostics",
version: "1.0.0",
lossRowGrain: "aggregate",
measures,
countPopulations,
exposureBases,
amountBases,
derivedMeasures: [],
formulas: CASUALTY_FORMULA_TEMPLATES,
instances,
reviewRules,
periodAxis,
});
const prepared = prepareDiagnosticData({ definition: compiled, losses, exposures });
const result = runMetricDiagnostics({ prepared, groupMap: { fleet: "all-fleet" } });Eager and compact paths
The example above uses the retained eager APIs. The additive compact APIs, introduced in 0.7.0, expose the same numeric views while retaining complete audit and identity evidence behind authenticated owners instead of eagerly expanding it. Choose matching preparation, calculation, and maturity functions:
| Operation | Eager | Compact |
|---|---|---|
| Prepare inputs | prepareDiagnosticData | prepareDiagnosticDataCompact |
| Calculate metric views | runMetricDiagnostics | runMetricDiagnosticsCompact |
| Select one development age | sameMaturity | sameMaturityCompact |
| Select the latest common age across output groups | commonMaturity | commonMaturityCompact |
The original maturity signatures remain unchanged; compact results use the
separately named helpers, not casts to eager results. Development ages use the
result's declared age unit. Review evaluations are available through
pageDiagnosticReviewEvaluations, with source references separately available
through pageDiagnosticReviewEvaluationSources. Passing and not-evaluated
evaluations remain available; paging is not sampling.
Use owner-controlled identity documents and iterateDiagnosticIdentityJson
when complete canonical text is needed. materializePreparedDiagnosticData and
materializeMetricDiagnosticsResult intentionally expand the eager evidence;
they are explicit compatibility choices, not a memory-saving export path.
Cloning or parsing an owner does not recreate its authority. Compact storage is
not a dataset-capacity or bounded-memory guarantee for an entire application.
SDK 0.8 adds authenticated compact selection helpers for metric, source-group,
whole-origin, and valuation/age scopes. Eligible clean aggregate preparations
share immutable cells while preserving the same fresh preparation and result
identities; an ineligible scope returns undefined so the data gateway can use
ordinary preparation. These functions do not issue review or execution receipts.
These are lower-level calculation APIs. For a host import or analysis boundary
that enforces both review and metric execution policy, use the validated gateway
in @actuarial-ts/data. The runnable compact adoption guide (docs/migrations/0.7-compact-diagnostics.md)
covers the complete workflow and streamed replay (docs/reference/diagnostic-replay-stream.md).
The six built-in formulas are basis-independent. The factory creates ten count instances plus six per amount basis (10 + 6 × basisCount): one basis produces 16, two produce 22. A $250K, primary, gross, net, or ceded calculation is represented by caller-declared amount measures and a structured AmountBasisDefinition; it does not need a separate capped formula. Claim-level caps use claim-layer derivations before aggregation. Pre-limited external values record their source/transformation instead of implying the SDK recreated an unavailable claim-level operation.
All metrics are ratio-of-sums: measures are aggregated at source-group/origin/valuation, groups are mapped and merged, then division happens once. Measure-local missing: "unknown" | "zero" is explicit. Exposure timing is either origin-static or valuation-specific. Calendar and ordered axes derive normalized origins, valuations, development ages, and units; input rows cannot assert a trusted age.
Exposure reconciliation accepts at most 250,000 observations per call. Collection capacity is independent of optional source-file/sheet/cell metadata: each record retains the JSON depth (256 including the outer array) and one-million-node resource guards, while the owned result is frozen by observation/cohort rather than rechecked against a single collection-wide JSON node budget. Malformed arrays, accessors, non-JSON metadata, and cycles still produce typed validation errors. Nonfinite exposure values remain supported audited inputs, not usable numeric exposure values. This is a bounded capacity, not an unlimited scale claim.
Compilation validates the whole graph atomically: IDs, sources, role types, compatibility groups, development semantics, derivation acyclicity, expression limits, rule operands, basis/population references, and period coordinates. Authentic compiled/prepared objects are owner-branded and frozen. Formula, calculation, definition, preparation, and result identities are deterministic FNV-1a/JCS integrity aids—not cryptographic signatures.
See the generated formula and instance catalog (docs/reference/diagnostic-formulas.md) and 0.6 migration guide (docs/migrations/0.6-generalized-diagnostics.md).
Main method families
- Reserving: chain ladder, Mack, Bornhuetter-Ferguson, Benktander, Cape Cod/Gluck, Expected Claims, frequency-severity, Fisher-Lange, Munich chain ladder, Clark, ODP bootstrap, and Merz-Wüthrich one-year risk.
- Adjustments: Berquist-Sherman, salvage/subrogation, ULAE, tails, trends, premium on-leveling, discounting, capping, severity models, and ILFs.
- Infrastructure: triangle algebra, seeded RNG, RFC 8785 canonical JSON, integrity tags, traditional triangle diagnostics, and generalized metric diagnostics.
Published-value tests are the numerical contract. A reserving math change is not acceptable until those fixtures still pass.
License
Apache-2.0. See LICENSE and NOTICE.
SDK 0.9 adds native post-aggregation formulas and correct financial currency units.
See the 0.9 migration guide (docs/migrations/0.9-analysis-expressions.md).
Composite history sources
SDK 0.10 adds multiple original artifacts within one claim namespace, explicit
composite identity selectors and complete input-artifact membership checks.
Upgrade the five SDK packages together and preserve the producing runtime
with archived evidence. See the 0.10 migration guide (docs/migrations/0.10-composite-history.md).
Connected reserve review
SDK 0.16 adds the typed source-to-publication review contracts. Development age
zero is the structural cumulative origin and always has value 0; a nonzero first
observation must use its positive elapsed age. Upgrade all five SDK packages
together and retain earlier runtimes with archived evidence. See the 0.16
migration guide (docs/migrations/0.16-connected-reserve-review.md).
