Skip to content

[FEAT] One-year claims development result (Merz–Wüthrich) for MackChainladder #1543

Open

Description

@scks1

Description

MackChainladder measures reserve uncertainty to ultimate: mack_std_err_ is the prediction error of the reserve for all future payments. Solvency II sets reserve capital over a one-year horizon, so it needs a different quantity: how far the estimate of ultimate could move over the next year, once one more diagonal is observed and the chain ladder is re-run. That change is the claims development result (CDR). chainladder-python has no way to estimate its uncertainty today. R's ChainLadder added CDR() for MackChainLadder and BootChainLadder in 0.2.0 (2015). In #30, Peter England wrote that, as far as he could see, chainladder-python computes Mack's standard errors but not the standard deviation of the CDR for a sequence of one-year views to ultimate, and that he dropped his chainladder-python example for that reason.

Merz & Wüthrich, "Modelling the claims development result for solvency purposes" (CAS E-Forum, Fall 2008), give closed-form estimators under Mack's distribution-free model. They need only the triangle and the factors and sigmas that MackChainladder already holds. The technique table in #680 lists "A Practical Way to Estimate One-year Reserve Risk" (Robbin, CAS E-Forum, Summer 2012). Section 6.2.1 of that paper reviews the Merz–Wüthrich estimators, and Robbin's own method builds one-year risk from an ultimate reserve-risk estimate plus payment and reporting patterns. MackChainladder already produces the ultimate estimate.

Is your feature request aligned with the scope of the package?

  • Yes, absolutely!
  • No, but it's still worth discussing.
  • N/A (this request is not a codebase enhancement).

Describe the solution you'd like, or your current workaround.

Two fitted attributes on MackChainladder, alongside mack_std_err_ and total_mack_std_err_, rather than a new estimator:

  • cdr_std_err_: the one-year CDR standard error by origin
  • total_cdr_std_err_: the same for all origins together, including the covariance between origins

A first PR would keep to the paper's setting:

  • volume-weighted development factors over all periods, with no exclusions
  • no tail beyond the default constant 1.0 (R's documentation says tail factors are not supported)
  • a square triangle, one diagonal ahead, which is one year when the development periods are annual

Other configurations would raise a ValueError.

I have a prototype that computes both quantities from a fitted MackChainladder's own ldf_, sigma_, std_err_, latest diagonal and ultimate_, vectorized over the index and column axes. Against R's CDR() on the two Merz–Wüthrich samples that already ship with the package:

sample one-year S.E., prototype one-year S.E., R Mack S.E., MackChainladder Mack S.E., R
mw2008 81,080.5468 81,080.5468 108,401.3875 108,401.3875
mw2014 1,842.8507 1,842.8507 3,233.6807 3,233.6807

Per origin, the prototype agrees with R to the last digit R prints (4 decimals for mw2008, 7 for mw2014). On the paper's own example it reproduces Table 2's factors exactly and its sigmas to within 0.015, the observable CDR of −40,075 in Table 3 (computed from the next diagonal the paper prints), and every entry of Table 4 to within 0.2%. The largest gap is one Mack figure, 1,563.8 against the paper's 1,566 (accident year 2 in the paper's numbering), and R gives 1,563.8 there too. On clrd grouped by LOB (paid and incurred, 12 triangles), the vectorized version matches the same formulas applied one triangle at a time to within 2e-12 relative.

These figures use Development(sigma_interpolation="mack"), which matches R's est.sigma="Mack". With the default "log-linear" the last sigma changes, and both results move with it: on mw2008 the one-year figure becomes 81,336.66 and total_mack_std_err_ 108,732.16.

Questions before a PR:

  1. Are attributes on MackChainladder the right home, and are these names acceptable? "CDR" is the paper's term and R's, though cdr_ sits close to cdf_; one_year_std_err_ is an alternative.
  2. Should unsupported configurations raise, or return NaN with a warning?
  3. Should the first PR stop at one year? The sequence Peter England was looking for is what R's CDR(dev="all") returns: one standard error per future calendar year, from Merz & Wüthrich, "Claims Run-Off Uncertainty: The Full Picture" (Swiss Finance Institute Research Paper No. 14-69, 2014). I'd start with the first year, which the 2008 paper's example checks, and add the later years in a follow-up checked against R's dev="all" output.

Do you have any additional supporting notes?

Would you be willing to contribute this ticket?

  • Yes, absolutely!
  • Yes, but I would like some help.
  • No.

(This issue was written with Árbol, an AI assistant, under my direction.)

Activity

  1. henrydingliu commented on Nov 9, 2026

    @henrydingliu
    Member

    great idea!

    i think all three questions are fairly open-ended. the specific choices matter less as long as the docstrings and tests support those choices.

    can't wait to see the PR.

  2. henrydingliu commented on Nov 9, 2026

    @henrydingliu
    Member

    logging a few enh to follow #1558

    • deciding whether we want to keep a dedicated summary_ under mack or add the mack statistics to model_diagnostics instead
    • adding the new cdr statistics to the mechanism above
    • expanding the newly added "one year view" section in the user guide with some numbers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Scope

    None yet

    Effort

    None yet

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions