The Underwriting data model

This lesson follows one real deal through the model, then states the general rule. Read it next to the live pages: every path below is a node you can open.

The deal: Alpina MTPL XL 2027 — a motor third-party liability excess-of-loss renewal, two layers, offered to us at 50 %, status Under assessment. Its numbers are worked through member by member in Pricing scopes and formulas.

1. Start at the submission

A submission is one cedent's programme offered to us for one underwriting year — the pre-contract workflow artifact (Underwriting/Source/Submission.cs, record Submission).

Open MTPL2027. Its content says:

Field Value on MTPL2027 What it is
cedent Reinsurance/Samples/AlpinaCedent a node path into Reinsurance — not a copy
broker Reinsurance/Samples/CartwrightBroker node path, empty when placed direct
lineOfBusiness Reinsurance/LineOfBusiness/Casualty node path; the §6 cap is looked up by its leaf
currency Reinsurance/Currency/EUR node path; every amount below is in EUR
programme MTPL key that joins the submission to its Claims/Claim records
inception, termMonths 2027-01-01, 12 first day on risk, contract term
subjectPremium 127,500,000 the cedent's GNPI on the subject business
layers 2 × SubmissionLayer the QUOTED tower the scopes evaluate
acceptances …/MTPL2027/Layer1, …/MTPL2027/Layer2 the REAL structure — Reinsurance/Acceptance nodes
statedLossRatio, brokerage, cedingCommission, expenseRatio 0.72, 0.10, 0, 0.06 the pack's treaty economics, each null when not on file
reportedClaims 5 claims the cedent's bordereau, reconciled against our claims
status Under assessment the STORED lifecycle — never derived on a page

Two rules make this record trustworthy:

2. Down to the layers and the quote options

The submission carries the offer twice, on purpose:

On MTPL2027 they match one to one:

Layer (layers[i]) Acceptance node Band Rate on line Our share
Layer 1 MTPL2027/Layer1 7m xs 3m 7.8 % 50 %
Layer 2 MTPL2027/Layer2 15m xs 10m 3.4 % 50 %

The acceptance spells the same band in Reinsurance's words — attachmentPoint, cover, premiumRate, share (Reinsurance/Acceptance/Source/Acceptance.cs) — and points to the treaty section it applies to through sectionIds (MTPL2027/MotorSection). Keeping the two consistent is the authoring side's job (the demo importer, an authoring UI); nothing derives one from the other.

Tower or options? SubmissionOptions.AreAlternatives (Underwriting/Source/SubmissionOptions.cs) decides. Ordered by attachment, if any layer attaches below the top of the one beneath it, the layers overlap and are alternative options — at most one binds. The per-option views (the Economics page, the offer, the per-option verdicts, all through SubmissionOptions.Of) then evaluate each option on its own. The desk ranks on the option flagged favorite; with no favourite, SubmissionOptions.Ranked returns the submission unchanged, so the desk's figures still sum every layer (section 3 and the exercise below). A medical stop-loss's options are alternatives even when they do not overlap. MTPL2027's layers stack (3m + 7m = 10m, where Layer 2 attaches), so it is one tower.

3. Under an option: the stop-loss model and its stored result

An option can be priced by our own simulation. The model is a LossModelling/StopLossModel node stored under the option, at {submission}/Option{n}/Pricing (DeskRanking.ModelPath, Underwriting/Source/DeskRanking.cs). The model reads its parent acceptance's terms; its own fields (deductible, maxReimbursement, annualPremium, share, cost ratios) only override them (LossModelling/StopLossModel/Source/StopLossModel.cs).

When it runs, the model stores its result on itself (StopLossPricingResult, LossModelling/StopLossModel/Source/StopLossPricing.cs): expectedLossRatio, lossRatioP10 / P50 / P90, probabilityOfRecovery, premium, recoveries, costs, technicalResult, margin, the simulations and seed, pricedAt and an input fingerprint.

The pricing operation copies that result upward:

  1. onto the option's acceptance as pricedLossRatio;
  2. onto the submission as pricedLossRatio and pricing (a SubmissionPricing: option, model paths, LR, P10/P90, chance of recovery, margin, when, fingerprint), together with deskScore, expectedProfit and deskScoreBasis (Underwriting/Submission/Source/SubmissionPricingPlane.cs).

A tower is priced only when every layer is; its ratio is then weighted by our premium on each layer. Alternatives are priced on their favourite alone. The full mechanics are in Desk ranking.

On MTPL2027: its options are named Layer1 / Layer2, not Option1 / Option2, and carry no pricing model. Its pricedLossRatio is therefore empty and the desk ranks it on the pack's own figures (basis stated).

To see a stored result you have to ask for a pricing run — opening a model prices nothing. The model type's demo, LossModelling/StopLossModel/Demo, is a stand-alone model (it does not sit under an acceptance) that ships with no result, no requestedAction and no previous attempt, and StopLossPricing.Decide leaves such a never-attempted model idle (LossModelling/StopLossModel/Source/StopLossPricing.cs). Its views (Cashflows, Result, …) are simulated live, not the stored result. So:

  1. open the model's Price page — the stored result and the button that asks for a run (StopLossPricing.PriceArea);
  2. press Price, which sets requestedAction: "Price". That is a write, so on a shipped, read-only node work on an editable copy of the model in your own partition;
  3. once the run is stored, the Price page shows result with its fingerprint and pricedAt.

4. The decision

A decision is our governed answer to a submission (Underwriting/Source/Decision.cs, record Decision). It stores facts only:

The rules about those facts live in the GovernanceRules scope (Underwriting/Source/Governance.cs): which sign-offs the guideline requires at the proposed lines, which recorded ones count (identity and timestamp mandatory; the four-eyes second-underwriter sign-off never counts when the deciding underwriter signs it — a CUO or Head-of-LoB sign-off is not checked against DecidedBy), and whether the decision is ready to bind.

MTPL2027 has no decision yet. A shipped one is Alpina Marine XL 2027 — decision: it decides MarineRenewal2027, proposes 35 % / 35 % / 30 % on Layers 1–3, verdict Write, status Proposed. Its live check is the Governance page.

5. The rulebook: a Guideline and four kinds of reference row

The Guideline node Group Underwriting Guidelines states only provenance — documentReference GUW-GL-2026-001, version 4.2, effectiveFrom 2026-01-01 (Underwriting/Guideline/Source/GuidelineNode.cs). The rules themselves are code: the Guideline scope in Underwriting/Source/GuidelineRules.cs.

The rulebook's reference data ships as one node per row (Underwriting/Source/RulebookData.cs):

Type Clause One shipped row What it holds
CapacityCap §6 Caps/Motor — max gross line 12m, net retention 4m, 12 months per-LoB caps; aliases match a submission's line of business ("motor", "motortpl", "mtpl")
AuthorityRung §4.2 Authority/SeniorUnderwriter — rung 2, up to 5m for 12 months the delegated-authority ladder; the lowest rung that covers a placement wins
AppetiteMetric §3 Appetite/CombinedRatioTarget — ≤ 95 %, Group net, across the cycle Board limits and targets
RegionalLimit §7 Regions/WesternEurope — max net aggregate EUR 450m, ≤ 35 % of GWP, Open regional limits; countries resolve a domicile to a region

The §6 caps and §4.2 rungs are what the compliance scopes evaluate. The §3 and §7 rows are reference data the pages render; they are not yet wired into verdicts (see the module guide).

Note the basis on the §3 target: it measures the Group's own book, net, across the cycle. The per-placement combined ratio of section 6 below is a different measure, and the two are never compared directly.

6. The lists: the desk and the submission book

The whole chain, in one line

SubmissionBook / Workbench  — list, derive, rank
        │
Submission ──references──▶ Cedent · Broker · LineOfBusiness · Currency   (Reinsurance)
   │  layers[]        (quoted view the scopes evaluate)
   │  acceptances[] ──▶ Reinsurance/Acceptance  (one per layer or option, a child node)
   │                        └─ {option}/Pricing : LossModelling/StopLossModel ─▶ result
   │                              (result.expectedLossRatio ─▶ acceptance.pricedLossRatio
   │                                                       ─▶ submission.pricedLossRatio, deskScore)
   ▲
Decision ──submission──┘   lines[] join layers[] by name; signOffs[] checked by GovernanceRules
   │
Guideline scope + CapacityCap · AuthorityRung  (graded)   ·   AppetiteMetric · RegionalLimit (reference)

The platform's diagrams

The class diagrams below are drawn by the platform's data-model explorer from the compiled types, so they cannot drift from the code.

Prerequisite: these three embeds come from the Data Modelling plugin (/DataModelling/Explorer), which Underwriting does not require. On an installation without it they render nothing. Every submission carries its own data-model view, which needs no other plugin: the Data model section of its Formulae page, e.g. MTPL2027 → Formulae (Underwriting/Submission/Source/SubmissionDataModel.cs).

The whole module:

The submission and its neighbours:

The decision and its neighbours:

The Reinsurance side of the picture — cedent, treaty, section, acceptance — is the Reinsurance data model; how the cash flows behind a treaty are modelled is the cash-flow model; and what each kind of cover does to one loss distribution is Ceding a distribution.

Check yourself

Question. MTPL2027's Layer 1 is 7m xs 3m. Suppose the cedent re-quotes Layer 2 as 15m xs 8m instead of 15m xs 10m. What changes in how the desk treats the deal?

Answer. Layer 2 would then attach at 8m, below the 10m where Layer 1 is exhausted, so the layers overlap. SubmissionOptions.AreAlternatives turns true: the two layers become alternative options, at most one of which binds. Two things then differ:

Reference

Entity NodeType Record / source Key References
Submission Underwriting/Submission Submission · Underwriting/Source/Submission.cs node path, e.g. ReinsuranceDemo/Submissions/MTPL2027 cedent, broker, lineOfBusiness, currency → Reinsurance; acceptances[] → Reinsurance/Acceptance
Layer value record inside a submission SubmissionLayer · same file name, unique within the submission joined by ProposedLine.layer
Quote option Reinsurance/Acceptance Acceptance · Reinsurance/Acceptance/Source/Acceptance.cs child path of the submission sectionIds[] → treaty sections; carries favorite, pricedLossRatio
Stop-loss model LossModelling/StopLossModel StopLossModel · LossModelling/StopLossModel/Source/StopLossModel.cs {submission}/Option{n}/Pricing parent acceptance (terms); assumptions → a health assumption set
Stored result value record on the model StopLossPricingResult · …/StopLossPricing.cs content.result copied to pricedLossRatio / pricing
Decision Underwriting/Decision Decision · Underwriting/Source/Decision.cs node path submission → Submission; decidedBy, signOffs[].signedBy → Reinsurance/Underwriter
Guideline Underwriting/Guideline GuidelineReference · Underwriting/Guideline/Source/GuidelineNode.cs Underwriting/Rulebook — (rules are the Guideline scope)
Capacity cap Underwriting/CapacityCap CapacityCapContent · Underwriting/Source/RulebookData.cs Underwriting/Rulebook/Caps/{id} aliases[] match a line of business
Authority rung Underwriting/AuthorityRung AuthorityRungContent · same file Underwriting/Rulebook/Authority/{id} level, ordered by rung
Appetite metric Underwriting/AppetiteMetric AppetiteMetricContent · same file Underwriting/Rulebook/Appetite/{id} —
Regional limit Underwriting/RegionalLimit RegionalLimitContent · same file Underwriting/Rulebook/Regions/{id} countries[] match a domicile
Workbench Underwriting/Workbench Workbench · Underwriting/Workbench/Source/WorkbenchAreas.cs Underwriting/Desk — (derives live)
Submission book Underwriting/SubmissionBook SubmissionBook · Underwriting/SubmissionBook/Source/SubmissionBook.cs in a cedent partition partitions[], brokers[] by name
Reconnecting…
The connection to the server was interrupted. Trying to restore it…
Trying again…
The connection could not be restored. Reloading the page…
The server was updated. Reloading the page to pick up the latest version.