Financial Modelling · Section 6
Financial perspectives
Subject, covered, gross, retained, and net: the same trial losses seen from each side of a contract, and which metrics decompose exactly across them.
Where the dollars go
Section titled “Where the dollars go”We have defined the financial terms and composed contracts from them, and every one of those contracts does the same thing: it turns a stream of subject losses into a gross loss. But that gross loss is only half of what a contract produces: the same transformation also fixes what the cedent retains. Foundations named these loss perspectives in business terms; here we attach the canonical notation and ask which of them we can actually compute with a single contract in hand.
| Perspective | Notation | Definition |
|---|---|---|
| Subject | The contract’s input: everything the cedent’s book presents in trial , before any term applies | |
| Covered | The covered, in-period slice left after the contract’s filter and contract period | |
| Gross | What the reinsurer assumes after the full composition | |
| Cedent retained | The part of the subject loss the contract did not absorb: what the cedent keeps |
Subject and covered differ whenever the filter is not the identity, and conflating them mislabels real dollars. On Trial 9, SunCoast presents a $272.1M subject, and Contract 1’s Florida-hurricane filter (SunCoast’s $30M xs $10M Florida-hurricane catastrophe excess of loss (CatXoL) contract) keeps $216.8M of it, the covered loss. Neither quantity is new: is the composition the dissection built up, its first two terms are the filter and the period, and the covered loss is their output, the point in the pipeline two terms short of the gross. Subtracting the gross from the subject gives the cedent’s retained loss, and the coverage boundary splits it in two:
Every trial’s subject loss splits, dollar for dollar, into three parts: what the contract never covered, what it covered but did not absorb, and what the reinsurer took. The first two together are the cedent’s retained loss . The never-covered part carries no information about the contract: the filter and period drop it by construction, whatever the amounts. What the transforming terms (the occurrence layer and the aggregate limit) did is recorded entirely in how the covered loss divides between kept and ceded. That division is measured on the covered loss (for Contract 1, SunCoast’s Florida-hurricane loss) and its kept part, written . The split is what shows what a contract does: how much of the risk it covers moved.
What the split gives you
Section titled “What the split gives you”Because the perspectives divide the same dollars, a metric on one constrains the others, but how it constrains them depends on the metric.
Contract 1 ($30M xs $10M, 1 reinstatement, Jan 1 to Dec 31) across the 20 trials: each trial's subject loss as what the reinsurer took (ceded), what the contract covered but did not absorb (kept), and what the filter and the period never covered. Outlined bars mark the covered stream's 4 worst trials at α = 80%: trials 2, 6, 9 and 19. Hover a bar for its parts. The sliders are shared by the three perspective charts on this page.
Expected loss splits exactly. Expected loss (EL) is an average, and averaging is linear, so the covered stream’s expected loss is precisely the sum of the ceded and kept expected losses:
For Contract 1 across SunCoast’s 20-trial demo tier, that is : the layer absorbs about 40% of SunCoast’s expected covered (Florida-hurricane) loss, and SunCoast keeps the rest, along with everything the filter never covered.
Expected loss under Contract 1 ($30M xs $10M, 1 reinstatement, Jan 1 to Dec 31): SunCoast's $275.6M subject splits into $231.7M never covered and $43.9M covered, and the covered loss into $17.4M ceded and $26.5M kept. Every flow adds up because the mean is linear. The sliders are shared by the three perspective charts on this page.
Tail risk does not.
The two tails are different sets of trials, and that is the whole argument. At the covered stream’s four worst trials are 2, 6, 9, and 19; the gross stream’s are 3, 6, 9, and 19. Trial 2 is a heavy Florida-hurricane year in which the layer paid $30M, and Trial 3 a lighter one in which it paid $34.6M across more storms. The gross ranks them the other way round from the covered loss.
The correct decomposition fixes one tail (the covered stream’s worst trials) and adds the ceded and kept losses within it. Conditioning on a single fixed set makes expectation linear again, so the split is exact. This is a Co-TVaR (Euler) allocation,1 the co-measure that portfolio capital attribution is built on, a subject the portfolio analytics story marks out and does not yet work through:
where averages its argument over the trials in the covered stream’s tail. The cedent’s residual tail risk on the covered stream, conditional on its own worst trials, is , exact, with nothing left over.
| On the covered tail | Own tail | |
|---|---|---|
| Covered | $132.2M | $132.2M |
| Ceded | $46.4M | $47.6M |
| Kept | $85.8M | $86.1M |
| Ceded + kept | $132.2M | $133.7M |
| Covered tail: trials 2, 6, 9 and 19. Ceded tail: 3, 6, 9 and 19. Kept tail: 2, 7, 9 and 19. | ||
Tail risk under Contract 1 ($30M xs $10M, 1 reinstatement, Jan 1 to Dec 31). Every figure is the stream's average over the covered stream's 4 worst trials at α = 80% (trials 2, 6, 9 and 19), a co-measure, so the flows add up: the covered stream's TVaR of $132.2M is $46.4M ceded plus $85.8M kept; the subject and never-covered figures are the same trials' averages, not those streams' own tails. The table sets each stream's own TVaR, on its own worst trials, beside it. The ceded stream's own worst trials are 3, 6, 9 and 19, and subtracting its TVaR, $47.6M, from the covered TVaR gives $84.6M against the exact $85.8M. The sliders are shared by the three perspective charts on this page.
A metrics store that keeps per-perspective summaries (EL, Value at Risk (VaR), and TVaR per contract per perspective) cannot produce the residual tail at all, because the co-measure needs the trial-aligned vectors of both streams: which trials are in the covered tail, and what the gross was in those trials. The covered and gross columns have to survive together, keyed by trial, to the point of measurement; summarise either one first and the split is gone.
At the demo tier’s , the tail is trials, which is why the subtraction happens to work there and fails one step lower. Production loss sets run 10,000 to 1,000,000+ trials, where the two tails routinely diverge; the 1,000-trial tier shows the same mechanism at a resolution closer to production.
A different but equally valid question is “how bad can the kept loss get on its own?” That is : the metrics from the toolkit applied to the kept distribution, whose tail is its own worst trials. For Contract 1 at that is , larger than the kept slice of the covered tail, because the kept loss peaks in different trials than the covered loss does. Each number has a job. The Co-TVaR slice attributes an agreed total: it says how much of the covered tail the contract removed and how much it left, and the parts reconcile exactly. It is the right frame for judging the contract’s tail relief, and the frame portfolio capital allocation builds on. The standalone figure sizes the retained position itself: the cedent’s balance sheet suffers the kept loss’s own worst trials whether or not the covered total was extreme in them, so capital and risk appetite for the retained loss are set from . Attribution takes the conditional number; holding the residual takes the standalone one.
The generator below reproduces every figure on this page (the per-trial covered split, the exact EL decomposition, and the Co-TVaR identity at both and ):
"""Derived loss perspectives for Contract 1 (SunCoast FL HU CatXoL).
Subject is everything the cedent presents; the contract's filter and contract
period select the COVERED loss, and the remaining terms produce the gross.
The interesting split is of the covered stream, trial by trial:
L_kept[s] = L_covered[s] - L_gross[s]
This is the reconciliation source for the "Financial perspectives" section of
the Financial modelling page. It shows two things:
* EL splits EXACTLY (expectation is linear):
EL(covered) = EL(gross) + EL(kept)
* TVaR does NOT subtract. TVaR(covered) - TVaR(gross) averages over two
DIFFERENT tail sets (each perspective's own worst trials). The cedent's
residual tail risk is a Co-TVaR (Euler) allocation conditioned on the
covered tail:
TVaR(covered) = Co-TVaR_cov(gross) + Co-TVaR_cov(kept)
Run with:
cd python && PYTHONPATH=. uv run --with numpy --with pandas --with pyyaml \
python3 caldera_re/perspectives.py
"""
import numpy as np
from caldera_re.catxol import catxol
from caldera_re.data import cedents
from caldera_re.loss_filter import loss_filter
from caldera_re.contract_period import contract_period
from caldera_re.report import fields, table
from caldera_re.utils import ep_index
PERIOD = ('2024-01-01', '2024-12-31')
N = 20
A, L, REINST = 10.0, 30.0, 1
CRIT = dict(peril='HU', geography_id='FL')
def trial_array(result, column, n=N):
"""Collapse a contract's YELT output to a length-n per-trial array
indexed by trial_id (1..n), filling absent trials with 0."""
arr = np.zeros(n)
for tid, value in result.groupby('trial_id')[column].sum().items():
arr[int(tid) - 1] = value
return arr
TIE_DECIMALS = 9
def tail_indices(values, alpha):
"""Indices of the worst k trials of `values`, k = ep_index(N, alpha).
Matches the site's VaR/TVaR convention (mean of the worst k).
Two trials whose values agree to TIE_DECIMALS are a tie, and a tie goes
to the later trial (stable ascending sort, last k taken). The rounding
is the tie rule: a layer that pays its limit in two trials can produce
30.0 in one and 29.999999999999996 in the other, and without it the
JavaScript twin (src/lib/perspectives.js) could pick a different trial.
"""
k = ep_index(len(values), alpha)
return np.argsort(np.round(values, TIE_DECIMALS), kind='stable')[len(values) - k:]
if __name__ == '__main__':
# Covered = the contract's covered, in-period loss per trial: the subject
# (everything SunCoast presents) after the filter and contract period.
covered_rows = contract_period(loss_filter(cedents.suncoast, **CRIT), *PERIOD)
cov_by_trial = covered_rows.groupby('trial_id')['loss'].sum()
covered = np.zeros(N)
for tid, v in cov_by_trial.items():
covered[int(tid) - 1] = v
# Gross = the contract output. Standalone gross is reported at 100%
# (participation applied at roll-up).
result = catxol(cedents.suncoast, attachment=A, limit=L,
reinstatements=REINST, **CRIT)
gross = trial_array(result, 'gross_loss')
# Kept = covered - gross, trial by trial: the covered loss the cedent
# keeps. (The cedent also keeps everything the filter never covered.)
kept = covered - gross
print("Contract 1 - per-trial perspectives (FL HU, 30M xs 10M, 1 reinst.)")
table(['Trial', 'Covered', 'Gross', 'Kept'],
[(s + 1, covered[s], gross[s], kept[s])
for s in range(N) if covered[s] > 0],
fmt=['{}', '{:.1f}M', '{:.1f}M', '{:.1f}M'])
# --- EL splits exactly (EL is linear) ---
el_covered, el_gross, el_kept = covered.mean(), gross.mean(), kept.mean()
print(f"\nExpected loss (mean over {N} trials):")
fields([
('EL(covered)', el_covered),
('EL(gross)', el_gross, f"{el_gross / el_covered:.0%} of the covered "
f"loss ceded in expectation"),
('EL(kept)', el_kept),
], indent=2, sep=' = ')
print(f" check: EL(gross) + EL(kept) = {el_gross + el_kept:.1f}M "
f"= EL(covered) -> exact (EL is linear)")
# --- TVaR does NOT subtract ---
for alpha in (0.90, 0.80):
k = ep_index(N, alpha)
cov_tail = tail_indices(covered, alpha)
gross_tail = tail_indices(gross, alpha)
tvar_covered = covered[cov_tail].mean()
tvar_gross = gross[gross_tail].mean()
tvar_kept = kept[tail_indices(kept, alpha)].mean()
# Co-TVaR conditioned on the COVERED tail (the correct additive split).
co_gross = gross[cov_tail].mean()
co_kept = kept[cov_tail].mean()
print(f"\nTail risk at alpha = {alpha:.0%} (k = {k} worst trials):")
print(f" covered tail = trials {sorted((cov_tail + 1).tolist())}")
print(f" gross tail = trials {sorted((gross_tail + 1).tolist())}"
f"{' (same set)' if set(cov_tail) == set(gross_tail) else ' (DIFFERENT set)'}")
fields([
('standalone TVaR(covered)', tvar_covered),
('standalone TVaR(gross)', tvar_gross),
('standalone TVaR(kept)', tvar_kept, "kept's OWN worst trials"),
], indent=2, sep=' = ')
print(f" WRONG TVaR(covered) - TVaR(gross) = "
f"{tvar_covered - tvar_gross:6.1f}M")
print(f" Co-TVaR split on the covered tail (exact):")
fields([('Co-TVaR_cov(gross)', co_gross),
('Co-TVaR_cov(kept)', co_kept)], indent=4, sep=' = ')
print(f" check {co_gross:.1f} + {co_kept:.1f} = {co_gross + co_kept:.1f}M"
f" = TVaR(covered) -> exact")
print(f" => cedent residual tail risk (in the covered stream's worst trials)")
print(f" = TVaR(covered) - Co-TVaR_cov(gross) = "
f"{tvar_covered - co_gross:.1f}M = Co-TVaR_cov(kept)") We have dissected one CatXoL, formalised the building blocks, recomposed the canonical contract types, and seen how a single contract partitions risk. The final step is to combine many contracts: the portfolio roll-up shows where diversification emerges, and the portfolio analytics story reads it as a business position.
Footnotes
Section titled “Footnotes”-
Dirk Tasche, “Capital Allocation to Business Units and Sub-Portfolios: the Euler Principle”, arXiv:0708.2542, 2008. Gives the Euler contribution to expected shortfall as the average of the component over the outcomes in which the portfolio total is in its own tail, an elementary conditional expectation whose contributions sum to the portfolio figure. Rodney Kreps, “Riskiness Leverage Models”, Proceedings of the Casualty Actuarial Society, 2005, names such additive components co-measures and derives TVaR’s as “the average value of the variable of interest in the situations where the total is greater than” the quantile. Gary G. Venter, “A Survey of Capital Allocation Methods with Commentary”, ASTIN Colloquium Berlin, 2003, Appendix 3, gives the name this site uses and the continuous form of the definition, “the mean loss for the ith unit in the case where total losses are over the qth quantile”; John A. Major and Stephen J. Mildenhall, Introduction to Capital Modeling and Portfolio Management, CAS Monograph 15, Casualty Actuarial Society, 2026, §3.3, gives the Euler gradient of TVaR and notes it is “often called the coTVaR”. Tasche derives the general form under smoothness conditions that imply a density; the rank-based version used here fixes the tail set instead, so the components add exactly on a discrete trial set. ↩