CLRS 2016 Reserve Example

Executive Summary

SFR consulting was retained by the CLRS 2016 R Workshop participants to prepare this analysis of unpaid claims and claims expenses. In this document, we present a analysis of unpaid claims and claim expenses. We developed this analysis using R and used R Markdown to create this document.

The relevant dates for our analysis are as follows:

  • Accounting date: 1997-12-31
  • Valuation date: 1997-12-31
  • Information date: 1997-12-31

The scope of our analysis is to estimate the unpaid claims and claims expenses for the automobile liability coverage for CLRS Insurance Company.

Findings

Acknowledgement

Any questions related to this report should be directed to:

Rajesh Sahasrabuddhe, FCAS, MAAA
(215) 246-1028
rajesh_saharabuddhe@oliverwyman.com

Brian A. Fannin, ACAS

BFannin@RedwoodsGroup.com

Emma Ran Li
(814) 753-0321
ril5077@gmail.com

Setting up the R Environment

We used several R packages to prepare this analysis.

# load packages

my_packages <- list("dplyr", "magrittr", "lubridate", "htmlTable", "knitr", 
  "xtable", "ChainLadder", "scales", "highcharter", "ggplot2")
sapply(X = my_packages, FUN = library, character.only = TRUE)

Data

The data underlying this analysis was provided by the Casualty Actuarial Society (CAS) which was available at http://www.casact.org/research/reserve_data/ppauto_pos.csv. We downloaded the data on Sunday, Sep 18, 2016 at 3:52:09 PM.

We summarize that data in the table below:

Data Summary as of 1997-12-31
Year Premium Incurred Paid Case
1988 7,922,457 6,826,501 6,815,646 10,855
1989 8,893,210 7,733,559 7,712,077 21,482
1990 9,948,988 8,405,128 8,364,955 40,173
1991 10,803,190 8,291,065 8,215,810 75,255
1992 11,690,069 9,060,858 8,876,813 184,045
1993 12,533,746 9,714,779 9,337,099 377,680
1994 13,590,797 10,462,749 9,640,098 822,651
1995 14,401,255 10,612,837 9,006,113 1,606,724
1996 14,900,682 10,479,410 7,486,113 2,993,297
1997 15,065,713 10,648,978 4,344,144 6,304,834
Total 119,750,107 92,235,864 79,798,868 12,436,996

Loss Development

Incurred Loss Development Experience

We present incurred loss development experience in the triangle below:

Obseravtions and Comments

In our review of the development experience, we noted the following:

  • Paid development patterns have been generally lengthening particularly at intermediate maturities such as 2:3 and 3:4
  • Incurred development experience indicates that a negative IBNR is most likely appropriate. More recent accident years have exhibited more favorable incurred development that older accident years.

Ultimate Loss Projections

We used the R package ChainLadder to project ultimate losses using the following methods:

  • Mack Chain-Ladder Model applied to paid and incurred losses
  • Bootstrap-Chain-Ladder Model applied to paid and incurred losses
  • The Munich Chain-Ladder Model
  • Traditional incurred and paid loss development Models

Mack-Chain-Ladder Model

mcl_paid <- MackChainLadder(Triangle = my_triangles$paid)
mcl_paid
## MackChainLadder(Triangle = my_triangles$paid)
## 
##         Latest Dev.To.Date   Ultimate      IBNR Mack.S.E CV(IBNR)
## 1988 6,815,646       1.000  6,815,646         0        0      NaN
## 1989 7,712,077       0.999  7,719,821     7,744    1,549   0.2000
## 1990 8,364,955       0.996  8,396,601    31,646    5,103   0.1613
## 1991 8,215,810       0.991  8,288,545    72,735    6,042   0.0831
## 1992 8,876,813       0.982  9,043,728   166,915   10,809   0.0648
## 1993 9,337,099       0.962  9,702,726   365,627   26,568   0.0727
## 1994 9,640,098       0.925 10,422,621   782,523   45,702   0.0584
## 1995 9,006,113       0.852 10,571,471 1,565,358   71,775   0.0459
## 1996 7,486,113       0.714 10,490,872 3,004,759  146,538   0.0488
## 1997 4,344,144       0.397 10,933,658 6,589,514  508,516   0.0772
## 
##                  Totals
## Latest:   79,798,868.00
## Dev:               0.86
## Ultimate: 92,385,689.36
## IBNR:     12,586,821.36
## Mack.S.E     549,869.43
## CV(IBNR):          0.04
plot(mcl_paid)

mcl_incurred <- MackChainLadder(Triangle = my_triangles$incurred)
mcl_incurred
## MackChainLadder(Triangle = my_triangles$incurred)
## 
##          Latest Dev.To.Date   Ultimate     IBNR Mack.S.E CV(IBNR)
## 1988  6,826,501        1.00  6,826,501        0        0      NaN
## 1989  7,733,559        1.00  7,730,688   -2,871    1,399   -0.487
## 1990  8,405,128        1.00  8,402,250   -2,878    2,975   -1.034
## 1991  8,291,065        1.00  8,285,251   -5,814    5,140   -0.884
## 1992  9,060,858        1.01  9,013,604  -47,254    7,495   -0.159
## 1993  9,714,779        1.01  9,611,411 -103,368   32,760   -0.317
## 1994 10,462,749        1.02 10,254,451 -208,298   62,572   -0.300
## 1995 10,612,837        1.03 10,268,035 -344,802   95,934   -0.278
## 1996 10,479,410        1.06  9,903,561 -575,849  170,716   -0.296
## 1997 10,648,978        1.09  9,739,379 -909,599  272,002   -0.299
## 
##                  Totals
## Latest:   92,235,864.00
## Dev:               1.02
## Ultimate: 90,035,131.06
## IBNR:     -2,200,732.94
## Mack.S.E     370,195.79
## CV(IBNR):         -0.17
plot(mcl_incurred)

Bootstrap-Chain-Ladder Model

bcl_paid <- BootChainLadder(Triangle = my_triangles$paid, R = 999, 
  process.distr = "gamma")
bcl_paid
## BootChainLadder(Triangle = my_triangles$paid, R = 999, process.distr = "gamma")
## 
##         Latest Mean Ultimate Mean IBNR IBNR.S.E  IBNR 75%  IBNR 95%
## 1988 6,815,646     6,815,646         0        0         0         0
## 1989 7,712,077     7,720,017     7,940   11,095    12,928    29,469
## 1990 8,364,955     8,396,876    31,921   19,050    42,268    65,947
## 1991 8,215,810     8,288,992    73,182   24,734    88,695   117,596
## 1992 8,876,813     9,043,419   166,606   37,424   190,405   228,953
## 1993 9,337,099     9,702,904   365,805   56,433   402,836   465,502
## 1994 9,640,098    10,429,620   789,522   82,693   843,737   933,537
## 1995 9,006,113    10,575,586 1,569,473  119,093 1,651,655 1,770,856
## 1996 7,486,113    10,496,129 3,010,016  168,483 3,124,542 3,284,932
## 1997 4,344,144    10,950,888 6,606,744  347,976 6,848,884 7,151,304
## 
##                     Totals
## Latest:         79,798,868
## Mean Ultimate:  92,420,077
## Mean IBNR:      12,621,209
## IBNR.S.E           469,377
## Total IBNR 75%: 12,936,532
## Total IBNR 95%: 13,391,252
plot(bcl_paid)

bcl_incurred <- BootChainLadder(Triangle = my_triangles$incurred, R = 999, process.distr = "gamma")
bcl_incurred
## BootChainLadder(Triangle = my_triangles$incurred, R = 999, process.distr = "gamma")
## 
##          Latest Mean Ultimate Mean IBNR IBNR.S.E  IBNR 75% IBNR 95%
## 1988  6,826,501     6,826,501         0        0  0.00e+00        0
## 1989  7,733,559     7,729,945    -3,614   30,266  4.97e+00   20,848
## 1990  8,405,128     8,401,645    -3,483   35,647  1.34e+02   28,106
## 1991  8,291,065     8,287,959    -3,106   42,575  8.45e+02   43,282
## 1992  9,060,858     9,019,090   -41,768   71,322 -2.00e+03   34,741
## 1993  9,714,779     9,617,239   -97,540   93,176 -3.07e+04    8,478
## 1994 10,462,749    10,258,152  -204,597  134,185 -1.03e+05  -32,799
## 1995 10,612,837    10,284,705  -328,132  166,827 -2.09e+05  -97,298
## 1996 10,479,410     9,915,060  -564,350  214,457 -4.13e+05 -265,696
## 1997 10,648,978     9,775,586  -873,392  249,031 -6.96e+05 -492,919
## 
##                     Totals
## Latest:         92,235,864
## Mean Ultimate:  90,115,883
## Mean IBNR:      -2,119,981
## IBNR.S.E           532,978
## Total IBNR 75%: -1,758,975
## Total IBNR 95%: -1,296,160
plot(bcl_incurred)

Munich-Chain-Ladder Model

munich <- MunichChainLadder(Paid = my_triangles$paid, Incurred = my_triangles$incurred, 
  est.sigmaP = 0.1, est.sigmaI = 0.1)
munich
## MunichChainLadder(Paid = my_triangles$paid, Incurred = my_triangles$incurred, 
##     est.sigmaP = 0.1, est.sigmaI = 0.1)
## 
##      Latest Paid Latest Incurred Latest P/I Ratio  Ult. Paid Ult. Incurred
## 1988   6,815,646       6,826,501            0.998  6,815,646     6,826,501
## 1989   7,712,077       7,733,559            0.997  7,719,654     7,730,629
## 1990   8,364,955       8,405,128            0.995  8,392,987     8,401,359
## 1991   8,215,810       8,291,065            0.991  8,277,687     8,282,288
## 1992   8,876,813       9,060,858            0.980  9,007,620     9,004,087
## 1993   9,337,099       9,714,779            0.961  9,594,069     9,576,316
## 1994   9,640,098      10,462,749            0.921 10,201,439    10,171,389
## 1995   9,006,113      10,612,837            0.849 10,142,317    10,095,103
## 1996   7,486,113      10,479,410            0.714  9,616,895     9,547,866
## 1997   4,344,144      10,648,978            0.408  9,335,620     9,266,960
##      Ult. P/I Ratio
## 1988          0.998
## 1989          0.999
## 1990          0.999
## 1991          0.999
## 1992          1.000
## 1993          1.002
## 1994          1.003
## 1995          1.005
## 1996          1.007
## 1997          1.007
## 
## Totals
##              Paid Incurred P/I Ratio
## Latest:   8.0e+07  9.2e+07      0.87
## Ultimate: 8.9e+07  8.9e+07      1.00
plot(munich)

Incurred Loss Development Method with Selected Factors

In the chart below, we first present the observed incremental development factors.

paid_dev_analysis <- dev_factor_df(my_triangles$paid)
## Joining, by = c("acc_yr", "lag")
paid_dev_analysis$gg

We then select the following development factors:

paid_dev_analysis$sel_ldf_df$sel_ldf = c(
  1.72, 1.18, 1.08, 
  1.04, 1.02, 1.01,
  1.00, 1.00, 1.00)

paid_dev_analysis$sel_ldf_df$sel_cldf <- paid_dev_analysis$sel_ldf_df$sel_ldf %>% 
  rev() %>% 
  cumprod() %>% 
  rev()

paid_tail <- 1.02

paid_dev_analysis$sel_ldf_df$sel_cldf <- 
  paid_dev_analysis$sel_ldf_df$sel_cldf * paid_tail


paid_dev_analysis$sel_ldf_df
## # A tibble: 9 × 3
##     lag sel_ldf sel_cldf
##   <dbl>   <dbl>    <dbl>
## 1     1    1.72 2.395462
## 2     2    1.18 1.392710
## 3     3    1.08 1.180263
## 4     4    1.04 1.092836
## 5     5    1.02 1.050804
## 6     6    1.01 1.030200
## 7     7    1.00 1.020000
## 8     8    1.00 1.020000
## 9     9    1.00 1.020000

We now add our selected incremental loss development factors (in red) to the chart.

Comparison of Methods

We now compare estimates by method

ultimates <- data_frame(acc_yr = row.names(summary(bcl_incurred)$ByOrigin),
  bcl_incurred = summary(bcl_incurred)$ByOrigin$'Mean Ultimate',
  bcl_paid = summary(bcl_paid)$ByOrigin$'Mean Ultimate',
  mcl_incurred = summary(mcl_incurred)$ByOrigin$'Ultimate',
  mcl_paid = summary(mcl_paid)$ByOrigin$'Ultimate',
  munich_incurred = summary(munich)$ByOrigin$'Ult. Incurred',
  munich_paid = summary(munich)$ByOrigin$'Ult. Paid',
  incurred = summary(munich)$ByOrigin$'Latest Incurred',
  paid = summary(munich)$ByOrigin$'Latest Paid')


ultimates
## # A tibble: 10 × 9
##    acc_yr bcl_incurred bcl_paid mcl_incurred mcl_paid munich_incurred
##     <chr>        <dbl>    <dbl>        <dbl>    <dbl>           <dbl>
## 1    1988      6826501  6815646      6826501  6815646         6826501
## 2    1989      7729945  7720017      7730688  7719821         7730629
## 3    1990      8401645  8396876      8402250  8396601         8401359
## 4    1991      8287959  8288992      8285251  8288545         8282288
## 5    1992      9019090  9043419      9013604  9043728         9004087
## 6    1993      9617239  9702904      9611411  9702726         9576316
## 7    1994     10258152 10429620     10254451 10422621        10171389
## 8    1995     10284705 10575586     10268035 10571471        10095103
## 9    1996      9915060 10496129      9903561 10490872         9547866
## 10   1997      9775586 10950888      9739379 10933658         9266960
## # ... with 3 more variables: munich_paid <dbl>, incurred <dbl>, paid <dbl>

R packages

We used the following R packages to develop this analysis:

  • Base R: R Core Team (2016). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.

We used rmdformats to produce this report.

We used the following packages to prepare the analysis.

  • Hadley Wickham and Romain Francois (2016). dplyr: A Grammar of Data Manipulation. R package version 0.5.0. https://CRAN.R-project.org/package=dplyr
  • Stefan Milton Bache and Hadley Wickham (2014). magrittr: A Forward-Pipe Operator for R. R package version 1.5. https://CRAN.R-project.org/package=magrittr
  • Garrett Grolemund, Hadley Wickham (2011). Dates and Times Made Easy with lubridate. Journal of Statistical Software, 40(3), 1-25. URL http://www.jstatsoft.org/v40/i03/.
  • Max Gordon (2016). htmlTable: Advanced Tables for Markdown/HTML. R package version 1.6. https://CRAN.R-project.org/package=htmlTable
  • Yihui Xie (2016). knitr: A General-Purpose Package for Dynamic Report Generation in R. R package version 1.14.
  • Yihui Xie (2015) Dynamic Documents with R and knitr. 2nd edition. Chapman and Hall/CRC. ISBN 978-1498716963
  • Yihui Xie (2014) knitr: A Comprehensive Tool for Reproducible Research in R. In Victoria Stodden, Friedrich Leisch and Roger D. Peng, editors, Implementing Reproducible Computational Research. Chapman and Hall/CRC. ISBN 978-1466561595
  • David B. Dahl (2016). xtable: Export Tables to LaTeX or HTML. R package version 1.8-2. https://CRAN.R-project.org/package=xtable
  • 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 Insurance. R package version 0.2.2. https://CRAN.R-project.org/package=ChainLadder
  • Hadley Wickham (2016). scales: Scale Functions for Visualization. R package version 0.4.0. https://CRAN.R-project.org/package=scales
  • Joshua Kunst (2016). highcharter: A Wrapper for the ‘Highcharts’ Library. R package version 0.4.0. https://CRAN.R-project.org/package=highcharter
  • H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2009.

Session Information

## R version 3.3.1 (2016-06-21)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 7 x64 (build 7601) Service Pack 1
## 
## locale:
## [1] LC_COLLATE=English_United States.1252 
## [2] LC_CTYPE=English_United States.1252   
## [3] LC_MONETARY=English_United States.1252
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.1252    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] ggplot2_2.1.0.9000 highcharter_0.4.0  scales_0.4.0      
##  [4] ChainLadder_0.2.2  xtable_1.8-2       knitr_1.14        
##  [7] htmlTable_1.6      lubridate_1.6.0    magrittr_1.5      
## [10] dplyr_0.5.0       
## 
## loaded via a namespace (and not attached):
##  [1] tidyr_0.6.0        viridisLite_0.1.3  jsonlite_1.1      
##  [4] splines_3.3.1      shiny_0.14         assertthat_0.1    
##  [7] statmod_1.4.26     TTR_0.23-1         highr_0.6         
## [10] stats4_3.3.1       yaml_2.1.13        lattice_0.20-33   
## [13] quantreg_5.29      rlist_0.4.6.1      chron_2.3-47      
## [16] digest_0.6.10      minqa_1.2.4        colorspace_1.2-6  
## [19] sandwich_2.3-4     htmltools_0.3.5    httpuv_1.3.3      
## [22] Matrix_1.2-6       plyr_1.8.4         psych_1.6.9       
## [25] broom_0.4.1        biglm_0.9-1        SparseM_1.72      
## [28] questionr_0.5      bookdown_0.1       purrr_0.2.2       
## [31] lme4_1.1-12        MatrixModels_0.4-1 tibble_1.2        
## [34] mgcv_1.8-12        car_2.1-3          lazyeval_0.2.0    
## [37] nnet_7.3-12        pbkrtest_0.4-6     quantmod_0.4-6    
## [40] mnormt_1.5-4       mime_0.5           evaluate_0.9      
## [43] nlme_3.1-128       MASS_7.3-45        xts_0.9-7         
## [46] foreign_0.8-66     data.table_1.9.6   tools_3.3.1       
## [49] formatR_1.4        stringr_1.1.0      munsell_0.4.3     
## [52] systemfit_1.1-18   grid_3.3.1         nloptr_1.0.4      
## [55] rstudioapi_0.6     tweedie_2.2.1      htmlwidgets_0.7   
## [58] igraph_1.0.1       miniUI_0.1.1       labeling_0.3      
## [61] rmarkdown_1.0      codetools_0.2-14   gtable_0.2.0      
## [64] DBI_0.5-1          reshape2_1.4.1     R6_2.1.3          
## [67] cplm_0.7-4         zoo_1.7-13         actuar_1.2-2      
## [70] stringi_1.1.1      parallel_3.3.1     rmdformats_0.3    
## [73] Rcpp_0.12.7        coda_0.18-1        lmtest_0.9-34

SFR Actuarial Consulting, Inc.

2016-09-18