Analytics Toolkit · Section 2
The trial worldview
What trials, events, and occurrences are, why trial-based simulation is the foundation of catastrophe risk analytics, and how data is structured.
Foundations closed on the claim that reinsurance is a capital allocation problem driven by tail risk and structured through contracts. Quantifying that tail begins with a question: what could happen? Not what will happen (catastrophes are too rare and too variable for prediction) but what is the full range of plausible outcomes?
The answer comes from trial-based simulation: generate thousands of possible futures of catastrophe activity, compute the losses for each, and use the resulting distribution to make decisions.
What is a trial?
Section titled “What is a trial?”A trial is one complete picture of what might happen: a possible future of catastrophe activity. “In this future, a Category 4 hurricane hits Miami in August, and a magnitude 7.2 earthquake strikes Tokyo in March. Nothing else.” Another trial might have no hurricane season at all, but a devastating earthquake in California.
The major vendor models simulate one year at a time,1 though some produce multi-year forecasts (e.g. for long-term capital planning or climate-adjusted views). Either way, each trial captures the full set of loss-producing events, including the possibility of none.
A trial is often called by two other names, and neither fits. A year is the period most models make a trial span. A scenario is a state of the world that an analyst specifies by hand for a stress test.
| Trial | Year | Scenario | |
|---|---|---|---|
| What it is | One random draw from the loss model: a simulated future of catastrophe activity | A period of time: the horizon most models give a trial | A state of the world chosen by hand, such as “a Category 5 hurricane hits Miami” |
| Where it comes from | Monte Carlo sampling of an event catalog | The model’s horizon setting | An analyst’s assumptions |
| Probability | for each of equiprobable trials | None: a horizon has no probability | None: the simulation assigns it no probability |
| On this site | Every loss row belongs to one: trial_id in the schema, index in the math | The usual length of a trial, never its name | Reserved for stress testing and what-if analysis |
Where do trials come from? Catastrophe models, maintained by vendors like Moody’s RMS, Verisk, and Cotality (formerly CoreLogic), generate trials through Monte Carlo simulation. Each model maintains an event catalog: a database of tens of thousands of physically plausible catastrophes (specific hurricane tracks, earthquake ruptures, windstorm paths).2 Each has an estimated annual frequency and, for a given exposure, a loss distribution (a mean and a spread, not a single number). The simulation engine samples from these catalogs, respecting seasonality (North Atlantic hurricanes cluster from June to November; a January storm such as Alex in 2016 is rare, not impossible)3 and frequency distributions (how often does a Category 4 hit South Florida?), to produce thousands of synthetic futures.
The output is a set of trials, each containing zero or more loss-producing events. We identify a trial by its trial_id. A trial contains zero or more occurrences: instances of catalog events that produce losses.
A trial_id identifies a trial within the simulation that produced it and that simulation’s trial numbering; an event_id identifies an event within one event catalog. One simulation run over several cedents’ exposures gives each cedent a year event loss table (YELT). Trial is the same future in all of them: a hurricane that strikes Miami in trial 17 appears, on the same date, in the YELT of every cedent whose exposure it damages. That shared identity is why losses from different YELTs can be added trial by trial, and why two cedents’ losses are correlated at all: both rise in the trials whose events hit both. It holds within one simulation and one trial numbering only. A second vendor’s model is a separate simulation with its own trials and its own event catalog. A new model version or a climate-conditioned catalog usually is too, so its trial 17 has no relation to the first simulation’s, and its event_ids refer to a different catalog. Every Caldera Re YELT is sampled from one 10,000-trial simulation over one event catalog. Both demo tiers select the same trials for every cedent, which is what lets the portfolio roll-up sum losses per trial across cedents. The two demo tiers are numbered separately, so Trial 9 of the 20-trial tier is not Trial 9 of the 1,000-trial tier.
Trials are equiprobable and independent. In a simulation with trials, each represents a probability of occurring:
They are independent of each other: the outcome of one trial tells you nothing about another. With the total loss of trial , the expected loss is , and the exceedance probability at a threshold is the share of trials with .
A trial’s losses are recorded per occurrence, and an occurrence is not the same object as a catalog event.
Events and occurrences
Section titled “Events and occurrences”An event is a specific physical catastrophe in a model’s event catalog: a particular hurricane track, earthquake rupture, or windstorm path. Events have catalog IDs, annual frequencies (rates), and physical metadata (wind speed, magnitude, geographic footprint).
An occurrence is a loss instance within a trial: one catalog event producing a loss in one simulated future. Each occurrence is identified by the composite key (trial_id, timestamp, event_id). A trial may contain zero, one, or many occurrences, and one occurrence produces one row of loss data for each cedent, geography, and line of business it touches. That chain, from trial to occurrence to row, is what the primary key of the YELT encodes.
The distinction matters because different contract types operate at different levels:
- Occurrence contracts (catastrophe excess of loss, CatXoL) evaluate each occurrence independently
- Aggregate contracts (aggregate excess of loss, AggXoL) accumulate losses across all occurrences in a trial
This is the same occurrence-vs-aggregate distinction from the Products and contracts section. The Financial Modelling chapter formalises the difference as two distinct terms, occurrence excess and aggregate excess, that differ in what they group by before applying the attachment and limit.
The YELT
Section titled “The YELT”The Year Event Loss Table (YELT) is the canonical data structure for trial-based loss data.
At its smallest, a YELT is three columns: a trial identifier, an event reference, and the loss.7 That shape carries no explicit timing: the only within-trial ordering available is the event ids themselves, so aggregate analysis on a three-column YELT relies on a strict event-id ordering inside each trial. That ordering requires event ids to be distinct per trial, which means one event cannot occur twice in the same trial. Production YELTs add the occurrence date instead, which gives temporal sequencing directly and lets an event recur. Those four columns are the core:
| Column | Type | Description |
|---|---|---|
trial_id | integer | Which simulated future |
timestamp | date | When the occurrence happens within the trial |
event_id | integer | Which catalog event produced this loss |
loss | float | Subject loss amount |
That core is what makes a YELT a YELT, and it is enough to drive the trial-loss metrics in this chapter: exceedance probability (EP) curves, EL, VaR, and Tail Value at Risk (TVaR). (The damage ratio below is the exception: it needs the enrichment’s tiv.) The five remaining columns of this site’s schema are an enrichment this site adds (a convention of this site, not an industry standard) that makes the worked examples self-contained without joins back to an event catalog or an exposure schedule:
| Column | Type | Description |
|---|---|---|
peril | string | Peril type (HU hurricane, EQ earthquake, WS windstorm) |
geography_id | string | Geographic region of the loss |
lob_id | string | Line of business |
cedent_id | string | Which cedent’s book of business the loss belongs to |
tiv | float | Total insured value of the exposed risk |
Real schemas vary: vendors and in-house platforms differ in which of these columns they carry, what they call them, and whether the information is in the loss table at all or in tables it joins to. Treat the nine-column table as one concrete, workable design. The four-column core is the part you can rely on meeting everywhere.
The primary key of the enriched YELT is (trial_id, timestamp, event_id, cedent_id, geography_id, lob_id): the occurrence key plus the resolution columns and the cedent. timestamp is part of the key because event_id names a prototypical catalog event, not an instance: the same event can occur more than once within a trial, at different timestamps. And a single occurrence, identified by (trial_id, timestamp, event_id), can produce multiple rows if it affects more than one geography or line of business: a major hurricane might generate separate loss records for Florida and Texas, or for its residential and commercial lines.
The geography_id and lob_id columns define the resolution of the loss data. They determine how finely losses are broken down, and they matter because different contracts may cover different geographies or lines of business. A contract covering only Florida residential risk would filter to geography_id = 'FL' and lob_id = 'residential' before applying its terms.
peril is a property of the event, not of the individual loss record: a hurricane is a hurricane regardless of where it causes damage. The enrichment carries it so that filtering and analysis by peril need no join back to the event catalog.
TIV and the damage ratio
Section titled “TIV and the damage ratio”The last column, tiv, records the total insured value (TIV): the sum of insured values of the exposure this occurrence touched, at the row’s geography and line of business (LOB) resolution. Where loss says how much damage the event caused, tiv says how much insured value stood in its path.
TIV gives losses a denominator. The damage ratio of a set of YELT rows is the modelled loss per unit of exposed insured value:
In English: add up the losses, add up the exposed TIV, divide. In code, it is one line per slice: df.groupby(dim).apply(lambda g: g['loss'].sum() / g['tiv'].sum()). A damage ratio of 12% means the events that struck this slice destroyed, on average, 12% of the insured value they touched, weighted toward the larger exposures. For a single occurrence (the largest in the SunCoast YELT, a $174.1M Texas hurricane loss against $700.9M of exposed TIV), the damage ratio is 24.8%: a quarter of the insured value in the storm’s path was lost.
Trial 9 of SunCoast’s YELT shows the sequencing the column carries: 30 occurrences at their dates, with the two large Florida hurricanes in September and October arriving after a July hurricane and a year of small earthquakes. That order decides, for any aggregate term, how much cover remains for the October storm.
SunCoast Trial 9: one bar per occurrence at its timestamp. Height is the loss in $M, colour the peril. The $102.4M September and $80.8M October hurricanes are the trial's two largest occurrences; the Financial Modelling chapter dissects this trial term by term.
The YELT is both the input to and the output from every financial computation. Contract terms consume a YELT and produce a new YELT with transformed loss values. This symmetry (YELT in, YELT out) is a core design principle that enables composability, and the Financial Modelling chapter applies it.
Sign convention
Section titled “Sign convention”This site’s convention: the loss column stores losses as positive numbers: a $46.9M loss is recorded as 46.9, and both loss and tiv are strictly greater than zero in a valid base YELT (model output entering the pipeline). (Transformed YELTs, the outputs of contract terms, may legitimately contain zero losses, but never negative ones.) This is the site’s sign convention, and it must be settled before any metric is computed on this data, because the industry has two conventions, and they disagree.
Accounting and finance systems often represent losses as negative values. A loss is money flowing out, a premium is money flowing in, and the net position is a plain sum: no special-case arithmetic. The output formats do the opposite: the RMS event loss table and the Oasis open results data standard both carry a loss amount, not a signed cash flow, because risk analytics asks “how big?” far more often than “which direction?”.9
The choice looks cosmetic. It is not. It silently determines the orientation of every computation downstream:
| Consequence | Loss-positive (this site) | Loss-negative |
|---|---|---|
| The “worst” trial | Largest value | Smallest (most negative) value |
| EP-curve sort order | Descending | Ascending |
| The tail | Top of the sorted table | Bottom of the sorted table |
| 1-in-100 loss | 99th percentile | 1st percentile |
| Net of premium | Explicit subtraction: | Plain sum: |
We use loss-positive throughout, for two reasons. First, it matches how the domain speaks and how the data arrives: “a $100M loss” and “the 1-in-20 loss is $616.2M” state positive magnitudes, and vendor catastrophe model output ships losses as positive values. Second, it keeps the tail computations in the next two sections, exceedance probability curves and metrics, direct rather than mirrored: sort descending, the worst trials sit at the top, rank maps to exceedance probability with no negation anywhere.
The price is that losses and premiums no longer net by simple addition: combining them requires explicit subtraction. We consider that a feature. When financial record types beyond loss enter the schema (premiums, reinstatement premiums, expenses), each should be an explicit record type with explicit aggregation semantics, not a sign trick. This site models the loss side only; the conventions index states that boundary. Accordingly, a negative loss in a YELT is a validation error: not a recovery, not a premium, not a correction. Reject it at every ingestion boundary, along with a zero loss or tiv, which a base YELT cannot hold either. The check is written as “all positive” so that a missing value fails it too:
for column in ('loss', 'tiv'): if not (yelt[column] > 0).all(): raise ValueError(f"non-positive or missing {column}: base YELT violation")If your organisation uses the loss-negative convention, everything on this site still applies: the If your losses are negative page shows exactly what to flip.
The Caldera Re YELT
Section titled “The Caldera Re YELT”Each of Caldera Re’s cedents has its own YELT with 20 trials. The number of occurrences varies by cedent and trial: some trials contain a single event, while others contain a dozen. Every Caldera Re YELT is in one currency, with loss and tiv in millions of US dollars ($M), so losses add directly across cedents; the demo data carries no currency column. SunCoast Insurance’s YELT supplies most of this chapter’s worked examples. Its first three rows are one occurrence (catalog event 10474, an Arizona earthquake on 27 January of Trial 1) split across SunCoast’s three lines of business, which is the primary-key rule above in data (values as stored):
trial_id | timestamp | event_id | peril | geography_id | lob_id | cedent_id | loss | tiv |
|---|---|---|---|---|---|---|---|---|
| 1 | 2024-01-27 | 10474 | EQ | AZ | residential | SunCoast | 0.3117 | 0.7845 |
| 1 | 2024-01-27 | 10474 | EQ | AZ | commercial | SunCoast | 0.2425 | 0.753 |
| 1 | 2024-01-27 | 10474 | EQ | AZ | industrial | SunCoast | 0.1386 | 0.269 |
The runnable summary prints the first ten rows and the total loss of every trial:
"""Display a summary of SunCoast's 20-trial YELT."""
from caldera_re.aep import aep
from caldera_re.data import cedents
from caldera_re.utils import trial_count
df = cedents.suncoast
print(f"Rows: {len(df)}")
print(f"Trials: {trial_count(df)}")
print(f"Columns: {list(df.columns)}")
print()
print(df.head(10).to_string(index=False))
print()
curve = aep(df)
print("AEP (total loss per trial, sorted):")
for tid, loss in zip(curve["trial_id"], curve["loss"]):
print(f" T{tid}: {loss:.1f}M")
print(f"\nMean: {curve['loss'].mean():.1f}M") Twenty trials is far below production scale, and the gap limits the return periods the data can resolve.
Demo scale
Section titled “Demo scale”Every worked example on this site runs on the same dataset: the 20-trial demo tier of the Caldera Re YELT. The size is a deliberate choice. Twenty trials fit on one screen, every sort can be checked by hand, and any number in prose can be recomputed from the table it came from. It is also 500 to 50,000 times smaller than the 10,000 to 1,000,000+ trials of production practice,4 and that gap deserves precision about what it does and does not change.
The method changes nothing. Every operation in this chapter (group, sum, sort, rank) is identical at and ; no step in the computation depends on how many trials it processes. What changes is resolution: the finest exceedance probability a trial set can express is . At 20 trials that is 5%: the worst trial is the 1-in-20 loss, and no rarer quote exists in the data. At 100,000 trials it is 0.001%, and the 1-in-200 and 1-in-500 quotes that capital decisions use are each based on hundreds of trials. Extra trials add depth and stability to the tail metrics: quotes at deeper return periods exist at all, and each is based on enough trials that one simulated storm cannot move it.
For exactly this contrast, the demo data ships a second tier: a 1,000-trial YELT per cedent, same schema, same event catalog (suncoast_1000.csv beside suncoast_20.csv). Any runnable example on the site switches tiers by replacing cedents.suncoast with load_cedent("suncoast", 1000). (The 1,000-trial CSV is a few megabytes; the first run fetches it.)
from caldera_re.aep import aep
from caldera_re.data import cedents, load_cedent
from caldera_re.tvar import tvar
from caldera_re.utils import ep_index
from caldera_re.var import var
def tail_report(curve, alphas):
"""Print VaR/TVaR at each confidence level, or why the quote is absent.
The tail count k = ep_index(N, alpha) is the number of trials the
quote rests on. k = 0 means the trial set cannot resolve this
return period at all.
"""
N = len(curve)
for alpha in alphas:
rp = round(1 / (1 - alpha))
k = ep_index(N, alpha)
if k < 1:
print(f" 1-in-{rp:<4} -- no quote: needs at least "
f"{rp} trials, have {N}")
else:
print(f" 1-in-{rp:<4} VaR = {var(curve, alpha):6.1f}M "
f"TVaR = {tvar(curve, alpha):6.1f}M "
f"(tail of {k} trial{'s' if k > 1 else ''})")
if __name__ == '__main__':
alphas = [0.90, 0.95, 0.99, 0.995]
print("20-trial demo tier (suncoast_20.csv)")
tail_report(aep(cedents.suncoast), alphas)
print()
print("1,000-trial tier (suncoast_1000.csv)")
tail_report(aep(load_cedent("suncoast", 1000)), alphas) Compare the two reports. At 20 trials the 1-in-20 quote is based on a single trial and the 1-in-100 quote does not exist. At 1,000 trials the 1-in-100 quote is based on ten trials and the 1-in-200 on five.
The numbers do not agree across the two datasets, and they are not supposed to. Both are subsets of the same underlying 10,000-trial simulation, sampled with dense tail coverage and a sparse body (the 20-trial subset far more aggressively, so that hand-sized examples still exercise limits and reinstatements). Selecting trials by rank, densest at the worst trial, biases the mean upward by construction: a subset’s expected loss is higher than that of the simulation it was drawn from, and the 20-trial subset, sampled the more aggressively of the two, is biased the further. Resolution limits which return periods a subset can quote; the sampling means that neither subset reproduces the simulation’s numbers. SunCoast’s expected loss is $275.6M on 20 trials and $205.6M on 1,000; neither is a market-calibrated estimate of anything. The demo numbers demonstrate the method; none of them estimates a real loss.
The same calibration inflates the economics, and this deserves stating as plainly as the resolution gap. A dataset in which limits, reinstatements, and inuring all visibly fire within 20 trials is one where losses run far more frequent and severe, relative to the limits, than in any realistic book: C1’s expected loss is $17.39M against a $30M layer, a loss cost far beyond what a real catastrophe layer carries. And since a premium must clear its expected loss for any pricing story to cohere, the premiums are inflated with the losses: Caldera Re’s rates on line run at multiples of market rates. Switching tiers does not repair this (both subsample the same simulation), and no choice of premiums against the same losses could. The mechanisms and the arithmetic transfer to a production run unchanged; the amounts (expected losses, premiums, and every ratio built from them) do not.
When another page quotes a number computed from this dataset, it carries a link back to this section: the phrase “20-trial demo tier” is the site’s standing marker that the mechanics are exact and the resolution is not.
Trial count is a property of a YELT; the event loss table that some vendors deliver instead contains no trials at all.
Event Loss Tables
Section titled “Event Loss Tables”An ELT is a common output format from catastrophe model vendors. Each row pairs a single event from the model’s catalog with a loss estimate and an annual frequency:
| Column | Type | Description |
|---|---|---|
event_id | integer | Catalog event identifier |
rate | float | Annual frequency of occurrence |
loss | float | Mean loss if the event occurs |
A model’s event catalog might contain 50,000+ physically plausible hurricanes, earthquakes, and windstorms, each with its own rate.2 A rate of 0.002 means this event occurs on average 0.002 times per year (equivalently, once every 500 years). Note that rate is a frequency, not a probability: a rate of 2.0 means two expected occurrences per year, while, under a Poisson frequency model, the probability of at least one occurrence in a year is , where is the event’s annual rate (at , about 0.865).11 For rare events (rate ≪ 1), the distinction is negligible; for frequent perils, it matters.
One simplification in that core is deliberate and labelled here. A vendor ELT row carries a loss distribution, not a loss: alongside the mean, the RMS format ships an independent and a correlated standard deviation (Sdi, Sdc) and an exposure value, and drawing each occurrence’s loss from that distribution is part of generating a trial.7 The spread of loss given that the event occurs is secondary uncertainty; whether and how often the event occurs (the rate) is the primary uncertainty.12 A production YELT is post-sampling: the draw has already happened, so secondary uncertainty sits inside every loss value and the analytics downstream of the YELT never see the uncertainty columns. That is why this site, which starts at the YELT, shows the three-column core. The demo data is a step simpler still: each catalog event carries one loss, so the same event produces the same loss in every trial it appears in. Open a real ELT and expect the uncertainty columns; open ours and expect the mean.
What you can do with an ELT:
- Compute expected annual loss directly:
- Evaluate per-occurrence contracts (like CatXoL) on individual events
- Build OEP curves by treating events independently
- Assess contracts quickly: an ELT is compact and fast to process
What you cannot do with an ELT:
- Analyse aggregate contracts: there is no concept of which events happen together
- Capture temporal sequencing: events have no timestamps, so you cannot model how losses erode coverage over time
- Preserve co-occurrence patterns: a hurricane season with three landfalls looks the same as three independent hurricanes
A YELT groups events into trials, preserving which events co-occur and in what order.
From ELT to YELT: Converting an ELT to a YELT means running a Monte Carlo simulation. For each trial, sample events from the catalog according to their rates, draw each occurrence’s loss from the event’s distribution, assign timestamps based on each peril’s seasonality distribution, and record which events occurred together. Some vendors expose the YELT directly; others provide the ELT and expect the user (or their platform) to perform the simulation step.13
The reverse, collapsing a YELT back to an ELT, is simple but destructive. You aggregate across trials and discard the grouping. Information is lost.
| Property | YELT | ELT |
|---|---|---|
| Temporal sequencing | Preserved (timestamps within trials) | Absent |
| Co-occurrence | Preserved (events grouped into trials) | Lost (events are independent) |
| Aggregate analysis | Natural (sum within trial, respecting order) | Requires simulation |
| Data size | Larger ( trials × occurrences) | Smaller (unique events × rate) |
| Primary use case | Full financial modelling | Quick screening, single-event analysis |
The trial grouping an ELT lacks is what turns a loss table into an empirical distribution of trial losses.
From trials to distributions
Section titled “From trials to distributions”With a YELT, you have everything needed to build an empirical probability distribution over any quantity you can compute from a trial’s losses. The computation is a reduction: collapse each trial’s occurrences to one number, and the numbers are the distribution. The rest of this chapter uses two reductions of a trial’s occurrence losses , their sum and their maximum , which Exceedance probability curves defines. Both start from the occurrence losses, the rows summed by occurrence key: occurrences = yelt.groupby(['trial_id', 'timestamp', 'event_id'])['loss'].sum(). Trial 9 of SunCoast’s YELT, with its 30 occurrences, reduces to these two numbers:
| Reduction | One number per trial | pandas | SunCoast Trial 9 | Curve built from it |
|---|---|---|---|---|
| Sum over the trial’s occurrences | Total trial loss, | occurrences.groupby('trial_id').sum() | $272.1M | Aggregate exceedance probability (AEP) |
| Maximum over the trial’s occurrences | Largest occurrence loss, | occurrences.groupby('trial_id').max() | $102.4M | Occurrence exceedance probability (OEP) |
"""Reduce SunCoast's YELT to one number per trial, two ways.
Shown step by step for the page. The reusable versions are aep() and oep()
(caldera_re/aep.py, caldera_re/oep.py), which also rank the result.
"""
from caldera_re.data import cedents
from caldera_re.report import table
from caldera_re.utils import all_trials, trial_count
df = cedents.suncoast
N = trial_count(df)
# Rows to occurrences: one occurrence can span several geography/LOB rows.
occurrences = df.groupby(['trial_id', 'timestamp', 'event_id'])['loss'].sum()
# Occurrences to trials. A trial with no rows has no group, so all_trials()
# adds it back with a value of zero. (SunCoast has rows in all 20 trials;
# Trident Re's file does not.)
per_trial = occurrences.groupby('trial_id')
trial_sum = all_trials(per_trial.sum(), N) # total trial loss
trial_max = all_trials(per_trial.max(), N) # largest occurrence loss
n_occ = all_trials(per_trial.size(), N).astype(int)
print(f"Trial 9: {n_occ[9]} occurrences, "
f"sum {trial_sum[9]:.1f}M, largest {trial_max[9]:.1f}M")
print()
table(['trial', 'occurrences', 'sum', 'max'],
[(j, n_occ[j], trial_sum[j], trial_max[j]) for j in range(1, N + 1)],
fmt=['{}', '{}', '{:.1f}M', '{:.1f}M'])
print()
print(f"{N} trials, each with probability 1/{N} = {1 / N:.0%}") The maximum is taken over occurrences, not rows. Trial 9’s largest row is $66.6M, the Florida residential part of catalog event 10007, a hurricane on 6 September. That occurrence has a second row, $35.8M of Florida commercial loss, and totals $102.4M. A maximum over rows would report the largest piece of an occurrence, so the script sums rows to occurrences first. The timestamp alone is not the key either: a second, smaller hurricane (event 10187) falls on the same date in Trial 9, and grouping by date would merge the two. The sums give the aggregate exceedance probability (AEP) curve and the maxima give the OEP curve.
For equiprobable trials, each trial contributes equal probability mass. With the Caldera Re YELT (20 trials), each of the 20 values in either column represents a 5% probability.
Ranking the trial losses gives the exceedance probability curve, the chart property-cat analytics is organised around.
Footnotes
Section titled “Footnotes”-
Verisk, “Modeling Fundamentals: Combining Loss Metrics”, October 2012. A 10,000-year catalog contains “10,000 potential realizations of what an upcoming year of hurricane activity may look like”, and “each simulated year may have no U.S. hurricane landfalls, one, or multiple landfalls”. Impact Forecasting, Florida Hurricane (FCHLPM) Model Version 3.0, submission to the Florida Commission on Hurricane Loss Projection Methodology, May 2025, assigns event losses “into a year table with stochastic years and aggregates (sum and maxima) per year”. ↩
-
Dickie Whitaker, Catastrophe Modelling, Oasis Loss Modelling Framework, 2016. Stochastic event sets “start at a few thousand examples for a simple model in a small country up to half a million or more for earthquake or windstorm in the USA”. Impact Forecasting, Florida Hurricane (FCHLPM) Model Version 3.0, May 2025: one peril in one state gives “nearly 56,000 unique Florida loss-causing events, selected from more than 2.6 million tropical cyclones simulated for the North Atlantic Ocean”. ↩ ↩2
-
NOAA National Hurricane Center, “Tropical Cyclone Climatology”. The Atlantic hurricane season runs from June 1 to November 30 and peaks on September 10. Eric S. Blake, Hurricane Alex (AL012016), NOAA Tropical Cyclone Report, September 2016. Alex was “the first hurricane to form in the Atlantic basin in January since 1938, and the first hurricane to be ongoing in January since Alice in 1955”. ↩
-
Verisk, “Modeling Fundamentals: Combining Loss Metrics”. A 10,000-year catalog “contains 10,000 potential realizations of what an upcoming year of hurricane activity may look like”. Impact Forecasting, Florida Hurricane (FCHLPM) Model Version 3.0, May 2025, resamples 200,000 simulated years into a 300,000-year set. Aman Bahl, Oliver Baltzer, Andrew Rau-Chaplin, and Blesson Varghese, “Parallel Simulations for Analysing Portfolios of Catastrophic Event Risk”, Workshop at SC12, 2012 (co-authored by this site’s author), whose performance study varies the number of trials “from 200,000 to 1,000,000”, a range it describes as “expected to be observed in practice and … based on discussions with industrial practitioners”. No source states the bounds as one range, so the figure quoted here brackets what these three describe. ↩ ↩2
-
Moody’s RMS, “Understand Metrics”, Intelligent Risk Platform documentation. A period loss table “represents primary uncertainty using the weight field”: the weight “represents the likelihood that one period occurs when compared to the other periods”, and for a full weighted period event table “the weights sum to one”. ↩
-
Kirsten Mitchell-Wallace, Matthew Jones, John Hillier, and Matthew Foote (eds.), Natural Catastrophe Risk Management and Modelling: A Practitioner’s Guide, Wiley, 2017. The standard practitioner reference for catastrophe-model output structures, including ELTs and YLTs. ↩
-
David Homer and Ming Li, “Notes on Using Property Catastrophe Model Results”, Casualty Actuarial Society E-Forum, 2017. Describes the event loss table (ELT) and year event loss table (YELT) formats and how analytics consume them; its minimal YELT is the (year, event, loss) triple. ↩ ↩2 ↩3
-
Moody’s RMS, “Introduction to Metrics”, Risk Modeler documentation. Defines the period loss table (PLT): simulated event losses per period, each row a dated event within a simulation period. ↩
-
Homer and Li, “Notes on Using Property Catastrophe Model Results”, §1.1.2. The event loss table’s loss columns are amounts:
Meanis the “Average Loss if the event occurs” andExposurethe “Total amount of limits exposed to the event (Maximum loss)”. Oasis LMF, ORD Output Definitions defines the probability table’sLosscolumn as “Modelled loss”, and the standard’s field list definesImpactedExposureas “Exposure impacted by the event (where loss > 0)”. Neither states a sign convention explicitly; both treat a loss as a magnitude. ↩ -
Yuyu Chen, Paul Embrechts, and Ruodu Wang, “Risk exchange under infinite-mean Pareto models”, arXiv:2403.20171, 2024, revised 2025. Surveys the literature on extremely heavy-tailed losses and reports that Ibragimov, Jaffee and Walden (Review of Financial Studies, 2009) “used standard seismic theory to show that the tail indices α of earthquake losses lie in the range [0.6, 1.5]”: a Pareto tail heavy enough that, for α ≤ 1, the loss has no finite mean. ↩
-
Natalia Humphreys, “Exceedance Probability in Catastrophe Modeling”, Casualty Actuarial Society E-Forum, Winter 2021. Poisson claim counts are “a common assumption when modeling a number of catastrophes”, and the probability of no occurrence follows from the mass function as . Homer and Li, “Notes on Using Property Catastrophe Model Results”, §3.2.1: the number of events “can be simulated from a Poisson with mean λ set to the sum of the ELT rates”. ↩
-
CAS Reinsurance Boot Camp (Sigona), “Catastrophe Modeling Overview”, 2019. Defines primary uncertainty as the uncertainty in whether an event occurs and secondary uncertainty as the distribution of loss amounts given that it has; its RMS event-loss-table slide names the uncertainty columns. ↩
-
Homer and Li, “Notes on Using Property Catastrophe Model Results”, §§1.1.1 to 1.1.2 and §3. One platform’s output “is provided in the form of sample data” that the paper calls a year event loss table, while another’s “is provided in the form of a list of parameters for each event”, an event loss table from which “the capital model needs to use the parameter table to perform its own simulation”. The paper describes what the two platforms delivered in 2017; the period loss table above is a later format. ↩