Skip to content
Property-cat reinsurance analytics for software engineers

Financial Modelling · Section 4.3

Scaling

The term that multiplies every loss by a constant factor (a cession percentage or a participation share), preserving distribution shape and scaling every metric linearly.

Step 5 of the catastrophe excess of loss (CatXoL) walkthrough applied scaling as Caldera Re’s participation. The scaling term multiplies every loss by a constant factor ff:

Lj,t,egross=f⋅Lj,t,esubjectL^{\text{gross}}_{j,t,e} = f \cdot L^{\text{subject}}_{j,t,e}

It is pointwise: each row on its own, with no state across rows.

This single operation serves two distinct business purposes:

The mathematics are identical. The business context determines what the factor means, and where it is applied.

Where the factor is applied matters as much as its value. Scaling commutes with itself and with every pointwise term (scale(a)∘scale(b)=scale(ab)\text{scale}(a) \circ \text{scale}(b) = \text{scale}(ab), and a loss filter or contract period keeps the same rows on either side of it). It also distributes over the roll-up sum, which is why one participation can be applied to a contract’s whole gross loss rather than to each row. It does not commute with a limit: q⋅min⁡(L,ℓ)≠min⁡(q⋅L,ℓ)q \cdot \min(L, \ell) \ne \min(q \cdot L, \ell) unless the limit is rescaled with the loss, which is why a quota share’s event limit sits before the cession and a ceded-side limit converts as ℓe=ℓ/q\ell_e = \ell / q. The failure mode is the double count: a participation written into the composition as a second scaling and applied again at roll-up books p2p^2 of the layer, quietly. The composition page states the rule that prevents it.

Applied to Trial 9 at f=0.25f = 0.25, every occurrence shrinks to a quarter of its subject loss. The shape of the trial is unchanged, only the magnitude:

Earthquake Hurricane

Scaling Trial 9 by 0.25. Every bar is a quarter of its subject height; the $102.4M September hurricane becomes $25.6M, the $80.8M October storm $20.2M.

Occurrence / totalSubjectGross (×0.25)
Sep 6, FL hurricane$102.4M$25.6M
Oct 5, FL hurricane$80.8M$20.2M
28 other occurrences$89.0M$22.2M
Trial 9 total$272.1M$68.0M
caldera_re/scale.py Python
import pandas as pd

from caldera_re.data import cedents
from caldera_re.contract_period import contract_period
from caldera_re.report import table


def scale(
    loss: pd.DataFrame,
    factor: float,
    input_column: str = 'loss',
    output_column: str = 'gross_loss',
) -> pd.DataFrame:
    """Scale losses by a constant factor.

    Multiplies every row's loss by the factor. Used for cession
    percentages (quota share) and participation shares (XoL).

    Parameters
    ----------
    loss : pd.DataFrame
        YELT with the specified input column.
    factor : float
        Scaling factor (e.g. 0.25 for 25% cession).
    input_column : str
        Column to scale (default: 'loss').
    output_column : str
        Name for the scaled column (default: 'gross_loss').

    Returns a copy with the output column added.
    """
    result = loss.copy()
    result[output_column] = result[input_column] * factor
    return result


if __name__ == '__main__':
    # Demo: scale all SunCoast subject losses by 0.25, applied directly to
    # the subject (the building-block illustration on Trial 9 et al.).
    subject = contract_period(cedents.suncoast, '2024-01-01', '2024-12-31')
    result = scale(subject, factor=0.25)

    print("Scale(0.25) applied to SunCoast subject losses")

    lines = []
    for tid in sorted(result['trial_id'].unique()):
        rows = result[result['trial_id'] == tid]
        subj = rows['loss'].sum()
        gross = rows['gross_loss'].sum()
        lines.append((tid, subj, gross))
    table(['Trial', 'Subject', 'Gross'], lines,
          fmt=['{:.0f}', '{:.1f}M', '{:.1f}M'])

    total_subject = result['loss'].sum() / 20
    total_gross = result['gross_loss'].sum() / 20
    print(f"\nSubject EL: {total_subject:.2f}M")
    print(f"Gross EL:   {total_gross:.2f}M")
    print(f"Factor:     {total_gross/total_subject:.0%}")

The cost is one multiplication per row: O(R)O(R) over the RR input rows, with no sort, no grouping, and no state, and a cost that does not depend on where the term sits in a composition.

Across all 20 trials of the demo tier, the gross curve is the subject curve scaled vertically by 0.25 at every return period:

Scaling EP curves: SunCoast subject vs 25% of every loss. The gross curve is a vertical scaling of the subject: the distribution's shape is preserved.

The quota share page shows the cession scaling inside a composition, and the portfolio roll-up applies the participation scaling outside every composition. The next term, the occurrence excess, is where a limit placed before or after the cession stops giving the same answer.