Skip to contents

Clark's LDF and Cape Cod methods (Clark 2003), as R ChainLadder's ClarkLDF() and ClarkCapeCod() with adol = TRUE: a growth curve G and either each origin's expected ultimate (clark_ldf()) or one expected loss ratio times each origin's exposure (clark_cape_cod()) are fitted to the incremental losses by over-dispersed Poisson maximum likelihood. Ages are measured from the average date of loss, the middle of the origin period, and development stops at max_age. Results match R ChainLadder and chainladder-python (validation/reference/reserving_clark_r.csv), except that the Weibull parameter risk uses the correct second derivative of the curve, where R's has an error (knowledge/references/r-chainladder-clark.md).

Usage

clark_fit(ptr)

clark_ldf(
  triangle,
  column = NULL,
  curve = c("loglogistic", "weibull"),
  max_age = Inf
)

clark_cape_cod(
  triangle,
  column,
  exposure,
  curve = c("loglogistic", "weibull"),
  max_age = Inf
)

growth(fit, age)

Arguments

ptr

A ClarkFit pointer; used internally.

triangle

A cumulative triangle with at least four development ages, with any number of segments.

column

Name of the loss column to fit; for clark_ldf() by default the only one.

curve

The growth curve: "loglogistic", G(x) = x^omega / (x^omega + theta^omega), or "weibull", G(x) = 1 - exp(-(x / theta)^omega).

max_age

Age in months at which development stops, at least the triangle's last age; Inf (or NULL) develops to infinity.

exposure

Name of the exposure column, such as premium; each origin's latest observed value is its exposure, which must be positive.

fit

A clark_fit with one segment.

age

Development ages in months, before the shift to the average date of loss.

Value

clark_ldf() and clark_cape_cod(): a clark_fit object. growth(): a numeric vector, one value per age.

Details

clark_ldf()'s reserve is the latest value developed by the fitted curve, latest * (G(max_age) / G(age) - 1); clark_cape_cod()'s is the fitted elr * exposure * (G(max_age) - G(age)). Process risk is the square root of scale times the fitted reserve, parameter risk the delta method on the parameter covariance (the scale times the inverse Fisher information), and standard_error the root of their squares' sum. A singular Fisher information gives NaN parameter risk, as R gives NA.

Every segment of the triangle is fitted on its own. Properties of the fit, per origin (named as a chain_ladder_fit's): latest, expected_ultimate (the fitted U, or elr * exposure, developed to infinity), ultimate, reserve, process_risk, parameter_risk, standard_error and, for Cape Cod, exposure (NULL for the LDF method); and chain_ladder (the volume-weighted chain_ladder_fit of the same column), keys, index, origins, development, method ("ldf" or "cape_cod"), curve, max_age, origin_width (the origin period in months), total_ultimate and total_reserve (summed over segments). The fitted omega, theta, scale (the over-dispersion sigma^2), elr (Cape Cod; NULL for the LDF method, with any number of segments), covariance (of the expected ultimates or the ELR, then omega and theta), n_observations (the incremental values fitted; scale divides by this less the number of parameters), total_process_risk, total_parameter_risk and total_standard_error need a single-segment fit: with several segments use totals_frame(), which has them per segment (except covariance and n_observations), or segment(). growth(fit, age) gives the share of the expected ultimate developed by each development age in months (Inf gives 1). These are Python's ClarkLdf, ClarkCapeCod and ClarkFit.

Examples

long <- data.frame(year = rep(2020:2024, 5:1),
                   age = c(12, 24, 36, 48, 60, 12, 24, 36, 48, 12, 24, 36, 12, 24, 12),
                   paid = c(110, 290, 370, 420, 440, 95, 300, 390, 425, 130, 320, 410,
                            105, 305, 120),
                   premium = 800)
tri <- triangle(long, "year", "age", c("paid", "premium"))
ldf <- clark_ldf(tri, "paid", curve = "weibull", max_age = 120)
c(omega = ldf@omega, theta = ldf@theta)
#>     omega     theta 
#>  1.201876 17.440363 
ldf@reserve
#>       2020       2021       2022       2023       2024 
#>   9.153632  25.358597  70.466767 167.042556 375.383602 
ldf@total_standard_error
#> [1] 80.78376
growth(ldf, c(12, 24, 120))
#> [1] 0.2422193 0.6460821 0.9999287

cc <- clark_cape_cod(tri, "paid", "premium")
cc@elr
#> [1] 0.6440832
as.data.frame(cc)
#>   origin latest ultimate   reserve exposure expected_ultimate process_risk
#> 1   2020    440 498.8564  58.85640      800          515.2666     7.799155
#> 2   2021    425 506.8206  81.82065      800          515.2666     9.195645
#> 3   2022    410 533.2524 123.25243      800          515.2666    11.286219
#> 4   2023    305 513.9496 208.94962      800          515.2666    14.695066
#> 5   2024    120 523.4539 403.45389      800          515.2666    20.419622
#>   parameter_risk standard_error
#> 1       9.547571       12.32814
#> 2      11.723280       14.89950
#> 3      14.546333       18.41126
#> 4      17.335742       22.72604
#> 5      16.774655       26.42631