-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIBNR.Rmd
193 lines (161 loc) · 6.4 KB
/
IBNR.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
---
title: "IBNR"
author: "Dan Murphy"
date: "May 26, 2018"
output:
html_document: default
pdf_document: default
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Prediction is hard. Especially of the future.
\~ Old Danish Proverb
It is in the public interest for insurance companies
to have sufficient assets to make all claim payments
owed in the future on policies purchased in the past.
The estimated total future value owed on behalf of policyholders
as of any given financial statement date is called the company’s
“Liability for Claims”
(technically that’s not the NAIC’s word for it,
but close enough).
Estimating this liability, usually the largest on a company's balance sheet,
falls under the purview of two company departments:
Claims and Actuarial.
When a policyholder files a claim,
it is the responsibility of the Claims Department
to estimate the total amount likely to be paid out.
These claim-level estimates are called "case reserves."
Case reserves reflect the value of a claim from the company’s standpoint.
But the total value of case reserves usually falls short of the company’s
true Liability for Claims for two reasons:
A. Updated claims: as claims stay open and
new facts are discovered,
values tend to rise
B. Delayed claims: new, as-yet-unknown
claims are often filed after a financial statement date
The estimate of the total shortfall (A+B) is called the
“Incurred But Not Reported” (IBNR) reserve.
It is the responsibility of the Actuarial Department to estimate IBNR.
Most actuarial techniques for estimating IBNR actually
estimate the ultimate value of claims first,
then subtract paid-to-date to get total reserves,
and finally subtract case reserves to get IBNR.
```{r, echo = FALSE}
plot(c(-3,10), c(-3,10), type = "n", xlab = "", ylab = "",
bty = "n", axes = FALSE)
rect(0,0,2,5, col = "blue")
rect(0,5,2,8, col = "green")
rect(0,8,2,10, col = "yellow")
text(1, 2.5, "Paid", pos = 3, col = "white")
text(1, 6.5, "Case\nReserves", col = "black")
text(1, 9, "IBNR", col = "black")
library(pBrackets)
brackets(2, 8, 2, 0, h = NULL, ticks = 5/8, curvature =.2, type = 2,
col = 1, lwd = 1, lty = 1, xpd = TRUE)
text(x=2.5, y=3,"Case Incurred = Paid + Case Reserves", pos = 4)
brackets(2.5, 10, 2.5, 5, ticks = .4, curvature = .2, type = 2,
col = 1, lwd = 1, lty = 1)
text(x=3, y=8,"Total Reserves = Case Reserves + IBNR", pos = 4)
brackets(0, 0, 0, 10, ticks = .5, curvature = .2, type = 2,
col = 1, lwd = 1, lty = 1, h=1)
text(x=-1, y=5,"Ultimate", pos = 2)
```
Actuaries have many techniques for estimating the ultimate value of claims,
and thus IBNR.
One of the simplest techniques is called the Loss Development Method.
# The Loss Development Method
In a nutshell,
the Loss Development Method multiplies the total current value of
a cohort of claims by a factor.
called a "development factor,"
the product of which is called the "ultimate" value of
total Liability for Claims
the Chain Ladder method looks at ratios of
total claim values as of
The purpose of this paper is
to investigate the mathematics behind the Chain Ladder Method.
We start this investigation with summarized claim data
as displayed in triangular format
in Schedule P of the U.S. *Annual Statement*.
## Annual Statement: Schedule P
For the benefit of US regulators,
as of every December 31st every insurance company must file a
set of reports called the *Annual Statement*.
This report, a.k.a the "Yellow Book,"
is a thick compendium
of statistics describing all aspects of an insurance company's business:
from premium to claims to investments and well beyond
deep into the bowels of an insurance company.
One of the key aspects monitored in the yellow book is
the company's Liability for Claims.
Not only is the size of that liability important,
but changes in that liability are important too because
changes can directly impact the
company's bottom line.
We will see how that works with two tables in
**Schedule P** of the yellow book,
**Part2** and **Part3**.
Changes in that liability are closely scrutinized because they directly
flow through to the bottom line.
year over year directly impact the
company's net income that year. over time is illuminated from various perspectives.
The data that we will poke and prod in this paper is called GenIns.
## GenIns
The ChainLadder package describes GenIns as a
"run off triangle of accumulated general insurance claims data."
GenIns is a real, not simulated, cumulative paid loss was created by the Australian actuary Greg Taylor.
egins with its representation in Schedule P - Part 3, meticulously named “Cumulative Paid Net Loss and Defense and Cost Containment Expenses Reported at Year End ($000 omitted)”:
```{r, echo = FALSE}
#setwd("C:/Users/Dan/Desktop/GenIns")
library(knitr)
library(kableExtra)
suppressPackageStartupMessages(library(ChainLadder))
suppressPackageStartupMessages(library(mondate))
df <- as.data.frame(GenIns, na.rm = TRUE)
df$Accident_Year <- as.numeric(df$origin) + 2007 # give labels to the origin's
df$Evaluation_YearEnd <- df$Accident_Year + df$dev - 1
df[["Evaluation_Date"]] <- mondate.ymd(df$Evaluation_YearEnd)
tri <- as.triangle(df, origin = "Accident_Year",
dev = "Evaluation_YearEnd", value = "value")
#tri
#round(tri)
#noquote(format(round(tri / 1000), big.mark = ","))
class(tri) <- "matrix"
options(knitr.kable.NA = '')
kable(round(tri / 1000), align = 'r', row.names = TRUE,
format.args = list(big.mark = ','),
caption = "GenIns in Sch P part 3 format") %>%
kable_styling(font_size = 8, full_width = FALSE)
###
## ignore below
###
tri2 <- as.triangle(df, origin = "Accident_Year",
dev = "Evaluation_Date", value = "value")
#tri2
#round(tri2)
#noquote(format(round(tri2/1000), big.mark = ","))
m <- round(tri2/1000)
names(dimnames(m))[2L] <- "Evaluation_Date ($000 omitted)"
#noquote(format(m, big.mark = ","))
mf <- format(m, big.mark = ",")
nams <- names(dimnames(m))
dimnms <- dimnames(m)
mfp <- paste(" ", mf)
dim(mfp) <- dim(mf)
dimnames(mfp) <- dimnms
#noquote(mfp)
mfp[is.na(m)] <- " XXX"
#noquote(mfp)
mfp2 <- rbind(Prior = c(" 000", rep("", 9)), mfp)
#print(noquote(mfp2))
```
Then plain ol' GenIns by kable:
```{r}
G <- GenIns
class(G) <- "matrix"
kable(G, row.names = TRUE,
format.args = list(big.mark = ','),
caption = "GenIns in triangle format")%>%
kable_styling(font_size = 8, full_width = FALSE)
```