Loss Modelling — the data model
Start with one node. Open the demo stop-loss model. It is one quote option for an employer group of 1,000 members, with a deductible of 150k and a max reimbursement of 2m, on a 12/15 basis and a 90 % share. Everything the module computes for that option comes from a few fields on that node and three nodes it names by path:
| Field on the demo model | Value | What it points at |
|---|---|---|
assumptions |
LossModelling/HealthAssumptions/US2026Demo |
the health assumption set: mortality, high-cost shares, Pareto tail, trend, completion |
engine |
empty, so the default HighCost engine |
— |
census |
7 age bands, 1,000 lives | stored on the model itself |
lasers |
one claimant on a 400k deductible | stored on the model itself |
Its sibling DurationDemo names engine: "ConditionDuration"
and two more nodes: the condition set and the
mortality table.
That is the whole pattern of this module. A model names its assumptions by node path, and the
numbers are computed from them. Nothing derived is stored except what the pricing operation
(StopLossModel/Source/StopLossPricingPlane.cs) writes. It writes two things:
- the model's
result; - when the model's parent is a
Reinsurance/Acceptance, the first-year expected loss ratio aspricedLossRatioon that acceptance, where quote-option tables read it.
The acceptance keeps the figure only while the result is current: after a failed attempt the
operation writes pricedLossRatio: null. The formulas behind each engine are on the
Formulas page.
The picture, drawn by the platform
The diagram below is the platform's own drawing of every type in the module, read from the compiled content types. It stays correct when a type changes, because nobody draws it by hand.
Prerequisite: the class diagrams on this page are embedded from the Data Modelling plugin's explorer (/DataModelling/Explorer), which LossModelling does not require. On an installation without it they render nothing; each type's own page under /LossModelling still lists its properties.
The entities, one at a time
1. The loss-model family: what generates a loss
LossModel (LossModelling/Source/LossModel.cs) is the abstract base. It has two fields:
Id, an opaque identity. A Reinsurance contract binds to a loss model only by this string, never by C# type.Name.
It has two concrete models.
Frequency-Severity Loss Model
(LossModelling/FrequencySeverityLossModel/Source/FrequencySeverityLossModel.cs) is the compound
(collective-risk) model. Each simulated period draws a claim count from Frequency, then that many
independent claim sizes from Severity, and spreads each claim over development periods by TimeModel.
| Field | Type | Default |
|---|---|---|
Frequency |
FrequencyDistribution: Poisson, NegativeBinomial, Binomial, Panjer, DiscreteUniform, Logarithmic |
new Poisson() |
Severity |
SeverityDistribution: Pareto, ParetoLimited, TruncatedPareto, LogNormal, MixedExponential, Exponential, Gamma |
new Pareto() |
TimeModel |
TimeModel; the only concrete one is LinearTimeModel (NumberOfIncurredPeriods, NumberOfPaidPeriods) |
new LinearTimeModel() |
Instance: no frequency-severity instance node ships. The worked instance is the sampler test's
fixture in LossModelling/FrequencySeverityLossModel/Test/FrequencySeveritySamplerTests.cs:
Poisson λ = 3, Pareto x₀ = 1, α = 5, a linear time model of 3 incurred and 5 paid periods. Its mean
is E[S] = 3 × 1.25 = 3.75; see the Formulas page.
The sample pricing program binds the opaque id
property-cat-2024 to the type node LossModelling/FrequencySeverityLossModel.
Pre-Sampled Loss Model
(LossModelling/PreSampledLossModel/Source/PreSampledLossModel.cs) generates nothing. It is a
data carrier: it stores Losses, an array of TimeSeries. Each series is a per-period cumulative
vector with an AmountType path, a Periodicity, and optional SectionId / ClaimsId paths. Its
source describes it as the way to inject deterministic claims into pricing and cession tests. No
replay integration exists yet: neither Pricing nor Reinsurance reads this type. Its own tests
(PreSampledLossModel/Test/PreSampledLossModelTests.cs) check only that the record round-trips,
using the canonical fixture series [0,1,2,3].
Distributions is a content marker with no fields. It exists so the
distribution family has a node whose Tests area runs the moment, sampling and quantile suites.
2. Timing models: when a loss develops
Both timing models describe a segment by node-path strings into the Reinsurance partition:
LineOfBusiness, Region and RiskCategory, plus Currency on the claim-development model.
| Type | Fields | Source |
|---|---|---|
| Time Lags Model | Id, ValidAsOf, segment, DevelopmentLags (ReportingLag, IncurredLag, PaidLag, ClosureLag, MaxClosureLag) |
LossModelling/TimeLagsModel/Source/TimeLagsModel.cs, LossModelling/Source/DevelopmentLags.cs |
| Claim Development Model | segment, the same five lags inline, LambdaIncurred, LambdaPayments, CvOutstanding |
LossModelling/ClaimDevelopmentModel/Source/ClaimDevelopmentModel.cs |
Instance: no instance node of either type ships. Both are parameter carriers today.
3. Market models and exposure curves: severity by segment
MarketModel (LossModelling/Source/MarketModel.cs) is the abstract base. Its fields are Id,
ValidAsOf, Currency, LineOfBusiness, Region and RiskCategory (all node paths), plus
DisplayName and TimeLags, a reference to a timing model. It has three concrete types:
| Type | Its own fields | Meaning |
|---|---|---|
| Limit-Based Curve | UnlimitedMean, ParetoAlphaBody |
ground-up mean severity and the Pareto α of the body; together the increased-limits curve |
| Risk-Based Exposure Curve | LogTenOfBase, BaseCurve, DeltaCurvePerDecade, MaxCurve |
a curve on a log₁₀ loss scale: BaseCurve at 10^LogTenOfBase, plus DeltaCurvePerDecade per decade, capped at MaxCurve |
| Mixed Exponential Market Model | MixedExponential (Weights, Scales) |
the segment severity as a finite mixture of exponentials |
Instance: none ships. The source says the curve evaluation for the first two "ships with the sampler". No evaluator for them is in the module today, so they carry parameters only.
4. The medical stop-loss model and its three assumption sets
Stop-Loss Model (LossModelling/StopLossModel/Source/StopLossModel.cs)
is the cash-flow model behind one quote option. It sits under the option's
Reinsurance/Acceptance and reads its terms from it:
- attachment → deductible
- cover → max reimbursement
- cover × rate → premium
- share and cost ratios
A term set on the model overrides the acceptance's. The demo nodes set every term on the model.
| Group | Fields | Demo value |
|---|---|---|
| Basis | assumptions, engine, conditions, mortality |
see the table at the top |
| Population | census (CensusBand: fromAge, toAge, male, female), lasers (Laser: label, deductible, condition, age, sex) |
7 bands / 1,000 lives; one laser at 400k |
| Run | paidMonths (12/N), years, renewalIncrease, simulations, seed |
15, 3, 0.10, 400, 2026 |
| Term overrides | deductible, maxReimbursement, annualPremium, share, externalCostRatio, internalCostRatio |
150,000 · 2,000,000 · 768,768 · 0.9 · 0.18 · 0.05 |
| Written by the pricing operation only | result (StopLossPricingResult), requestedAction, pricingNote, lastAttemptFingerprint |
absent on the shipped nodes, so not priced yet |
Health Assumptions (LossModelling/Source/HealthAssumptions.cs)
are the basis of the default engine.
Bands:HealthAgeBandrows, each withFromAge,ToAge, mortality by sex and the stationary high-cost share by sex.HighCostThreshold,ParetoAlpha,Persistence,HighCostMortalityMultiplier,MedicalTrend,Turnover,Completion,OnsetShare,ReimbursementLagMonths.
Instance: US2026Demo. Its values are threshold 100,000, α 2.2, persistence 0.21, multiplier 4, trend 8.5 %, turnover 17 %, onset share 0.7, lag 0 and 8 age bands. The band for ages 40–49 has high-cost shares of 1.15 % (male) and 0.99 % (female).
Condition Assumptions (LossModelling/Source/ConditionAssumptions.cs)
are the basis of the duration engine.
Groups:ConditionGrouprows. Each hasId,Name,Keywords,Incidence(age bands by sex),OnsetCost,MonthlyCost,CostVariation,CostTrend,ContinuationS(d) andExcessMortality.MortalityTable: a path.DefaultGroup,DefaultClaimantAge,Completion,ReimbursementLagMonths.
Instance: US2026Demo has eight groups: Cancer,
Cardiovascular, Transplant, Renal, Neonatal, Neuro, Specialty and Other. Its default group is Other,
its default claimant age 50, and its mortality table LossModelling/MortalityTable/US2024. The
Transplant group has an onset cost of 250,000, a monthly cost of 12,000, a continuation that falls
by 20 % a month, and an excess mortality of 10.
Mortality Table (LossModelling/Source/MortalityTable.cs) holds
q(x) by sex from MinAge, plus optional Improvement rates and its provenance: Source,
Publication, BasisYear, TableType, Population, SelectYears, Basis and Synthetic. Past
the last age the table closes at q = 1.
Instance: US2024 is the NCHS United States Life Tables, 2024, at ages 0–99 plus the closing "100 and over". For example, q(58, male) = 0.0090678.
How they relate: keys and references
Every cross-node reference in this module is a node-path string, never a C# reference. That is what keeps the dependency one-way: LossModelling → Reinsurance, and Pricing → LossModelling.
| From | Field | To | Fallback when empty |
|---|---|---|---|
| StopLossModel | assumptions |
LossModelling/HealthAssumptions/* |
the built-in demo set |
| StopLossModel | conditions |
LossModelling/ConditionAssumptions/* |
the module's demo set (ConditionAssumptions.Demo) |
| StopLossModel | mortality |
LossModelling/MortalityTable/* |
the condition set's mortalityTable, else LossModelling/MortalityTable/US2024 (StopLossEngines.MortalityPath) |
| ConditionAssumptions | mortalityTable |
LossModelling/MortalityTable/* |
US2024 |
| StopLossModel | its parent node | Reinsurance/Acceptance: the terms |
the model's own term fields |
| Market and timing models | currency, lineOfBusiness, region, riskCategory |
Reinsurance dimension nodes | — |
| MarketModel | timeLags |
a timing model | — |
| A Reinsurance section | models[].lossModel (LossModelMap, Reinsurance/Source/LossModelMap.cs) |
an opaque id such as property-cat-2024, never a path |
— |
Pricing Program |
lossModelsById[id] |
resolves that opaque id to a LossModelling node path | — |
The last two rows are the bridge. A contract says only "this section is modelled by
property-cat-2024". The Pricing program says which model that is. The
contract side is described in the Reinsurance data model.
Check yourself
Q. You change paretoAlpha on US2026Demo from 2.2
to 2.4. The demo model already has a stored result. What happens to it, and why does the pricing
operation not loop on its own write?
A. The result goes stale. StopLossPricing.Fingerprint hashes the model's inputs, the
effective terms and the assumption set's content, and the test TheDecision_RepricesStaleResults
pins exactly this case ("an assumption change moves the fingerprint"). The operation then re-prices
the model. Its own write cannot change the fingerprint, because result, requestedAction,
pricingNote, lastAttemptFingerprint and the name are excluded from the hash.
Reference
| Type | Path | Source | Shipped instance |
|---|---|---|---|
| FrequencySeverityLossModel | /LossModelling/FrequencySeverityLossModel | FrequencySeverityLossModel/Source/ |
— (test fixture) |
| PreSampledLossModel | /LossModelling/PreSampledLossModel | PreSampledLossModel/Source/ |
— |
| Distributions | /LossModelling/Distributions | Distributions/Source/, Source/*.cs |
— |
| TimeLagsModel | /LossModelling/TimeLagsModel | TimeLagsModel/Source/ |
— |
| ClaimDevelopmentModel | /LossModelling/ClaimDevelopmentModel | ClaimDevelopmentModel/Source/ |
— |
| LimitBasedCurve | /LossModelling/LimitBasedCurve | LimitBasedCurve/Source/ |
— |
| RiskBasedExposureCurve | /LossModelling/RiskBasedExposureCurve | RiskBasedExposureCurve/Source/ |
— |
| MixedExponentialMarketModel | /LossModelling/MixedExponentialMarketModel | MixedExponentialMarketModel/Source/ |
— |
| StopLossModel | /LossModelling/StopLossModel | StopLossModel/Source/ |
Demo, DurationDemo |
| HealthAssumptions | /LossModelling/HealthAssumptions | Source/HealthAssumptions.cs |
US2026Demo |
| ConditionAssumptions | /LossModelling/ConditionAssumptions | Source/ConditionAssumptions.cs |
US2026Demo |
| MortalityTable | /LossModelling/MortalityTable | Source/MortalityTable.cs |
US2024 |
Next: the formulas · claim duration in prose · one distribution ceded through QS, XL, tower and stop-loss · the Reinsurance cash-flow model.