- The ChainLadder package
- The Triangle Class
- Models available in ChainLadder
- Other Topics
The ChainLadder package provides various statistical methods which are typically used for the estimation of outstanding claims reserves in general insurance, including those to estimate the claims development results as required under Solvency II.
library(ChainLadder)
citation('ChainLadder')$textVersion
[1] "Markus Gesmann, Daniel Murphy, Yanwei (Wayne) Zhang, Alessandro Carrato, Giuseppe Crupi, Mario Wuthrich and Fabio Concina (2015). ChainLadder: Statistical Methods and Models for Claims Reserving in General. R package version 0.2.2. https://CRAN.R-project.org/package=ChainLadder"
Github site:
Functions to ease the work with triangle shaped matrix data. A 'triangle' is a matrix with some generic functions. Triangles are usually stored in a 'long' format in data bases. The function as.triangle can transform a data.frame into a triangle shape.
head(GenInsLong)
## accyear devyear incurred claims ## 1 1 1 357848 ## 2 2 1 352118 ## 3 3 1 290507 ## 4 4 1 310608 ## 5 5 1 443160 ## 6 6 1 396132
class(GenInsLong)
## [1] "data.frame"
gen_ins_tri <- as.triangle(Triangle = GenInsLong, origin = "accyear", dev = "devyear", value = "incurred claims") class(gen_ins_tri)
## [1] "triangle" "matrix"
str(gen_ins_tri)
## triangle [1:10, 1:10] 357848 352118 290507 310608 443160 ... ## - attr(*, "dimnames")=List of 2 ## ..$ accyear: chr [1:10] "1" "2" "3" "4" ... ## ..$ devyear: chr [1:10] "1" "2" "3" "4" ... ## - attr(*, "class")= chr [1:2] "triangle" "matrix"
gen_ins_tri[,1:8]
## devyear ## accyear 1 2 3 4 5 6 7 8 ## 1 357848 1124788 1735330 2218270 2745596 3319994 3466336 3606286 ## 2 352118 1236139 2170033 3353322 3799067 4120063 4647867 4914039 ## 3 290507 1292306 2218525 3235179 3985995 4132918 4628910 4909315 ## 4 310608 1418858 2195047 3757447 4029929 4381982 4588268 NA ## 5 443160 1136350 2128333 2897821 3402672 3873311 NA NA ## 6 396132 1333217 2180715 2985752 3691712 NA NA NA ## 7 440832 1288463 2419861 3483130 NA NA NA NA ## 8 359480 1421128 2864498 NA NA NA NA NA ## 9 376686 1363294 NA NA NA NA NA NA ## 10 344014 NA NA NA NA NA NA NA
ChainLadder and raw packagesNJM_WC dataset:
R object with class triangle and matrix with the incurred loss dataDevelopmentYear greater than 1997R object with class data.frame or tbl_df with the observed development factors for further examinationlibrary(ChainLadder) library(raw) library(magrittr) library(tibble) library(tidyr) library(dplyr) library(ggplot2) class(NJM_WC)
## [1] "tbl_df" "tbl" "data.frame"
njm_wc_tri <- NJM_WC %>% dplyr::filter(DevelopmentYear <= 1997) class(njm_wc_tri)
## [1] "tbl_df" "tbl" "data.frame"
njm_wc_tri <- as.triangle(Triangle = njm_wc_tri, origin = 'AccidentYear', dev = 'Lag', value = 'CumulativeIncurred'); njm_wc_tri[,1:8]
## Lag ## AccidentYear 1 2 3 4 5 6 7 8 ## 1988 167087 166976 166458 170327 178065 179126 175786 176194 ## 1989 179470 185511 190758 202576 204649 201686 202141 204552 ## 1990 198993 215685 226829 228487 225776 226678 228830 228252 ## 1991 237457 245174 247201 247388 245651 249402 251541 NA ## 1992 256936 272664 272226 266570 263346 263655 NA NA ## 1993 273382 273792 266742 259781 261032 NA NA NA ## 1994 311979 290504 264756 263642 NA NA NA NA ## 1995 288726 265868 255992 NA NA NA NA NA ## 1996 258617 236631 NA NA NA NA NA NA ## 1997 216437 NA NA NA NA NA NA NA
class(njm_wc_tri)
## [1] "triangle" "matrix"
dim(njm_wc_tri)
## [1] 10 10
njm_wc_df <- njm_wc_tri[,2:10] / njm_wc_tri[,1:9] %>% as_tibble() njm_wc_df <- dplyr::mutate(njm_wc_df, accident_year = as.character(1988:1997)) names(njm_wc_df)[1:9] <- paste(1:9, "to", 2:10)
njm_wc_df <- gather(njm_wc_df, key = interval, value = development_factor, 1:9, na.rm = TRUE) head(njm_wc_df)
## accident_year interval development_factor ## 1 1988 1 to 2 0.9993357 ## 2 1989 1 to 2 1.0336602 ## 3 1990 1 to 2 1.0838823 ## 4 1991 1 to 2 1.0324985 ## 5 1992 1 to 2 1.0612137 ## 6 1993 1 to 2 1.0014997
ggplot(data = njm_wc_df, mapping = aes(x = interval, y = development_factor, color = accident_year)) + geom_point()
ChainLadder:
BootChainLadder (CDR)ClarkCapeCodClarkLDFglmReserveMackChainLadder (CDR)tweedieReserveMultiChainLadder (Join2Fits)MunichChainLadder (Requires Paid and Incurred)PaidIncurredChain (Requires Paid and Incurred)strsummaryplot[$BootChainLadder(Triangle, R = 999, process.distr=c("gamma", "od.pois"))
The BootChainLadder procedure provides a predictive distribution of reserves or IBNRs for a cumulative claims development triangle.
process.distr - character string indicating which process distribution to be assumed. One of "gamma" (default), or "od.pois" (over-dispersed Poisson), can be abbreviated
England, PD and Verrall, RJ. Stochastic Claims Reserving in General Insurance (with discussion), British Actuarial Journal 8, III. 2002
Run the following code to create a paid triangle for other liability:
liab_tri <- as.triangle(Triangle =
othliab[othliab$GRNAME == 'State Farm Mut Grp' &
othliab$DevelopmentYear <= 1997, ],
origin = 'AccidentYear', dev = 'DevelopmentLag', value = 'CumPaidLoss_h1')
For the ClarkLDF method estimate with a tail that is:
Provide the following:
clark <- ClarkLDF(Triangle = liab_tri, maxage = 20, adol = FALSE) clark$Total$FutureValue
## [1] 1141360
clark$Ldf[2]
## [1] 1.044781
clark$TruncatedLdf[2]
## [1] 1.040017
unname(1 + (clark$THETAG[2]/15)^clark$THETAG[1])
## [1] 1.010415
unname(1 + (clark$THETAG[2]/15)^clark$THETAG[1] /
1 + (clark$THETAG[2]/20)^clark$THETAG[1])
## [1] 1.014996
Both the ClarkCapeCod and ClarkLDF fit growth functions to extrapolate the development pattern.
tail ~ c("G", "maxage")
See the Clark paper for the forms of the extrapolation model.
The CLFMdelta function
init_df <- MackChainLadder(Triangle = liab_tri)$f sel_df <- init_df sel_df[3] <- 1.5 alphas <- CLFMdelta(Triangle = liab_tri, selected = sel_df[1:9]) full_tri <- predict(chainladder(liab_tri, delta = alphas))
full_tri[7:10,1:5]
## dev ## origin 1 2 3 4 5 ## 1994 9720 65339.0 130303.0 186750.0 213678.7 ## 1995 7171 82822.0 160302.0 240453.0 275125.5 ## 1996 16696 88800.0 175128.2 262692.3 300571.6 ## 1997 21098 161171.9 317857.5 476786.2 545537.1
full_tri[,4] / full_tri[,3]
## 1988 1989 1990 1991 1992 1993 1994 1995 ## 1.747868 1.397273 1.474309 1.410887 1.363125 1.308281 1.433198 1.500000 ## 1996 1997 ## 1.500000 1.500000
This has the potential to support the variability calculation from the CLFM paper
The qpaid and qincurred are included in ChainLadder to demonstrate how to deal with triangles with quarterly evaluations and annual periods.
# ?qpaid #not run dim(qpaid)
## [1] 12 45
## MackChainLadder expects a quadratic matrix so let's expand ## the triangle to a quarterly origin period. n <- ncol(qpaid) # Number of quarterly valuations Paid <- matrix(NA, n, n) # create a matrix with NAs Paid[seq(from = 1, to = n, by = 4),] <- qpaid # fill in every 4th row with the annual data
Rajesh Sahasrabuddhe
rajesh.sahasrabuddhe@oliverwyman.com