Motivation
find_ata_maturity() answers the question “from which
development period are link factors
reproducible across cohorts?”. That is necessary for chain-ladder
projection but not sufficient for declaring a portfolio’s projected loss
ratio converged: in long-duration health insurance both
and
arise mechanically from cumulative denominators growing, regardless of
whether the underlying experience has actually settled. A criterion
built on those quantities passes automatically with
,
not because of true convergence — what we have called the
inertia failure mode.
find_lr_convergence() detects the convergence
point
— the first valuation
at which the projected loss ratio has predictively converged. It is the
natural counterpart to
(maturity point, from find_ata_maturity()):
marks where link factors
become reproducible, while
marks where the projection itself stops moving with new data.
Long-duration health portfolios may cross
early yet remain far from
.
The detector combines two orthogonal conditions, both required to hold for consecutive valuations:
- Predictive revision is small relative to its parameter SE: , where is the change in the projected portfolio LR caused by adding one new calendar diagonal.
- Cross-cohort dispersion of incremental LR is small: , where .
Operating on incremental rather than cumulative loss ratio keeps it inertia-free — per-period quantities have no cumulative denominator to dampen them. The two clauses guard against complementary failure modes: checks that the model output has stopped revising, while checks that the raw period-by-period experience is genuinely consistent across cohorts at that dev. Either alone can be fooled — in chain-ladder projection the mechanical drift collapses regardless of true convergence, and cross-cohort agreement on a single period’s level need not imply that the projection has settled. The dual criterion closes both inertia-leakage paths.
Why two conditions
A denominator effect disables any single-criterion diagnostic.
In long-duration health insurance, cumulative LR = cumulative loss / cumulative risk premium. As dev grows, the denominator grows alongside the numerator, so a new calendar diagonal’s contribution to the overall ratio shrinks automatically — regardless of whether the underlying experience has actually changed. This is the inertia effect.
What each criterion guards against:
| Scenario | Result | ||
|---|---|---|---|
| True convergence (model + experience both stable) | small | small | PASS ✓ |
| Chain-ladder drift (inertia) | small (spurious) | large | FAIL — dispersion catches it |
| Coincidental cohort agreement at one period | large | small (snapshot) | FAIL — projection revision catches it |
- alone is fooled by chain ladder’s mechanical drift (): the cumulative product barely moves, the projection barely moves, and collapses to zero — a false convergence.
- uses incremental LR, so it inherits no cumulative denominator → immune to the inertia effect.
- Requiring both criteria simultaneously closes the principal inertia-leakage paths. That is the design intent of the dual criterion.
Notation
| Symbol | Meaning |
|---|---|
| cohort index (UY) | |
| valuation index — the calendar diagonal; “ diagonals observed” | |
| maximum observed valuation (max dev in the triangle) | |
maturity point (from find_ata_maturity()); lower bound
on candidate
|
|
convergence point — the value find_lr_convergence()
returns |
|
| projected ultimate LR using data through valuation | |
| revision: | |
| parameter-uncertainty SE of (Mack-style) | |
| incremental loss ratio of cohort at dev | |
| robust scale-invariant dispersion of across cohorts | |
multiplier on
for the revision gate (default 0.5) |
|
upper bound on
for the dispersion gate (default 0.15) |
|
required run length of consecutive passing valuations (default
3L) |
The constant inside is the standard MAD correction: with this scaling becomes a consistent estimator of the cross-cohort standard deviation under normality, so reads as a robust, outlier-resistant coefficient of variation of incremental LR.
Basic usage
library(lossratio)
data(experience)
exp <- as_experience(experience)
tri <- build_triangle(exp[cv_nm == "SUR"], cv_nm)
res <- find_lr_convergence(tri)
print(res)Mock output:
#> <LRConvergence>
#> k_conv : NA
#> k_star : 9
#> V (max dev) : 30
#> criterion : R_v < 0.5 * SE_param_v AND D_v < 0.15 (run M = 3)
#> fit_fn : fit_lr
#> v candidates : 19 ( 0 pass both clauses)
The returned LRConvergence object reports:
-
k_conv— the detected , orNAif no run of consecutive passing valuations is found. -
k_star— the maturity point used as the lower bound (computed internally viafind_ata_maturity()on a clr-based ATA, or supplied by the caller). -
V— the maximum observable dev in the triangle. -
v,R_v,SE_param_v,D_v,pass_v— per-valuation diagnostic sequences indexed by . -
c,tau,M,holdout_max,min_n_cohorts— settings used. - attributes
group_var,value_var,fit_fn_name,dev_var.
summary(res) returns a data.table with one
row per candidate valuation and an extra
R_over_SE = R_v / SE_param_v column for inspection:
#> v R_v SE_param_v R_over_SE D_v pass
#> 1: 9 NA NA NA 0.90 FALSE
#> 2: 10 NA NA NA 0.76 FALSE
#> 3: 11 NA NA NA 0.56 FALSE
#> 4: 12 NA NA NA 0.58 FALSE
#> 5: 13 NA NA NA 0.81 FALSE
#> 6: 14 NA NA NA 0.43 FALSE
How it works: multiple holdout refits
find_lr_convergence() refits the model at each candidate
valuation and tracks how the projection changes.
Example: with
,
,
and holdout_max = 6 — candidates are
(7 in total).
| holdout depth () | available? | |
|---|---|---|
| 30 | 0 | ✓ |
| 28 | 2 | ✓ |
| 24 (cutoff) | 6 | ✓ |
| 22 | 8 | NA |
| 18 | 12 | NA |
One refit per candidate
(7 total) plus
computed between adjacent
.
The cutoff holdout_max defaults to
floor((V - k_star) / 2); once holdout depth exceeds it the
refit data becomes too thin and
,
are masked to NA.
Increase holdout_max to diagnose deeper into the past —
at the cost of less data behind each refit, hence lower confidence.
Plot
plot(res)The diagnostic is two stacked panels: the upper panel shows against with a horizontal guide at ; the lower panel shows against with a horizontal guide at . A vertical dotted line marks , and a vertical solid line marks when one is detected. A point falling below both threshold lines passes the joint criterion.
This view is also a quick way to see which clause is binding. If the top panel hugs the threshold but the bottom is far above, the issue is cross-cohort heterogeneity; if the bottom is fine but the top is high, the model is still revising.
Threshold tuning
The defaults are deliberately conservative:
| Argument | Default | Meaning |
|---|---|---|
c |
0.5 |
Revision must be smaller than half the parameter SE. |
tau |
0.15 |
Cross-cohort dispersion must be below 15% of the median lr. |
M |
3L |
Both clauses must hold for at least 3 consecutive valuations. |
min_n_cohorts |
5L |
Below this cohort count,
is NA (insufficient sample). |
Tighter thresholds yield later (or no) ; sweep a range to inspect sensitivity:
sapply(
c(0.25, 0.5, 0.75, 1.0),
function(cc) find_lr_convergence(tri, c = cc)$k_conv
)Values of
below
are difficult to attain in real portfolios because of single-period
claim noise; values above
usually indicate genuine cohort heterogeneity that warrants
detect_cohort_regime() before further modelling.
Relation to k^* and
detect_cohort_regime()
The three diagnostics answer different questions and operate on different axes:
| Tool | Question | Result | Axis |
|---|---|---|---|
detect_cohort_regime() |
Are cohorts homogeneous? | cohort groups | underwriting period |
find_ata_maturity()
() |
When are link factors reproducible? | a dev value | development period |
find_lr_convergence()
() |
When does the LR estimate stop revising? | a dev value | development period |
A defensible workflow is:
- Run
detect_cohort_regime(). If multiple regimes exist, fit each group separately. - For each homogeneous group, compute
via
find_ata_maturity(). - Run
find_lr_convergence()to obtain . The reported is the LR averaged over (or projected viafit_lr()).
The sequence separates cohort homogeneity, link reproducibility, and level convergence — three properties that coincide in P&C run-off but must be verified independently in long-duration health insurance.
Limitations
find_lr_convergence() is a thin layer over repeated
backtest() calls and inherits their constraints:
-
Identifiability:
can be declared only when
;
short observation windows return
NA. -
Model conditioning:
is computed by
fit_fn(defaultfit_lr). Different fitters yield different . Reporting under multiplefit_fnis recommended for robustness. - Portfolio aggregation: and are exposure-weighted across cohorts assuming inter-cohort independence. Calendar-year shocks (regulatory, healthcare cost trend) violate this assumption; both clauses can move together for non-cohort reasons.
- Multi-group triangles: the helper currently collapses across groups by median; running each group separately is recommended when groups behave differently.
See also
-
?find_lr_convergence,?find_ata_maturity,?backtest,?detect_cohort_regime. - Vignette
regime-detection— cohort homogeneity diagnostics that feed step 1 of the workflow above.
