Skip to Content
Course content

178: Reserve Estimation Techniques

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When you're dealing with insurance or warranty data, you're often playing a guessing game with the future. Reserve estimation—specifically calculating IBNR (Incurred But Not Reported) claims—is all about using the past to predict how much money you need to set aside today for claims that haven't even hit your desk yet. I've spent years doing this, and the "Chain Ladder" method is still the bread and butter for most of us, even if it's simplistic.

Building a claims development triangle

Before we can estimate anything, we need a triangle. In R, the easiest way to represent this is a matrix where rows are the "accident year" (when the event happened) and columns are the "development year" (how long it took to report/pay). Let's build a small one for a hypothetical product liability line.

# Let's set up some cumulative loss data
# Rows: 2020, 2021, 2022, 2023
# Cols: 12m, 24m, 36m, 48m development
claims_matrix <- matrix(c(
  1000, 1500, 1800, 2000, # 2020
  1200, 1700, 2100, NA,    # 2021
  1100, 1600, NA,   NA,    # 2022
  1300, NA,   NA,   NA     # 2023
), nrow = 4, byrow = TRUE)

rownames(claims_matrix) <- 2020:2023
colnames(claims_matrix) <- c("12m", "24m", "36m", "48m")
print(claims_matrix)

Calculating the age-to-age factors

The core idea here is that claims develop at a predictable rate. We want to find the "link ratio"—the multiplier that takes us from one development period to the next. I usually calculate these by averaging the growth across all available years for that specific transition.

# Calculate factors for each column transition
# Factor = (Sum of Col n+1) / (Sum of Col n)
col_sums <- colSums(claims_matrix, na.rm = TRUE)
age_to_age_factors <- col_sums[2:4] / col_sums[1:3]
names(age_to_age_factors) <- c("12-24", "24-36", "36-48")
print(age_to_age_factors)

Correcting my mistake with incremental vs cumulative data

Here is where I usually trip up when I'm rushing: I sometimes forget that the Chain Ladder method requires cumulative losses. If I were to use incremental losses (just the new money paid in that window), these ratios would be meaningless. Let me show you the mistake I almost made just now.

# MISTAKE: Trying to apply factors to incremental differences
# I might accidentally do this:
incremental_claims <- claims_matrix
for(i in 2:4) {
  incremental_claims[,i] <- claims_matrix[,i] - claims_matrix[,i-1]
}
# If I apply my age_to_age_factors to these incremental numbers, 
# the projection will be wildly understated. 
# I'm calculating growth on the 'new' money, not the 'total' money.

I caught it because the numbers looked too small. The "growth" of a claim is relative to the total amount paid so far, not just what was paid last year. I'll stick with the claims_matrix as it is, since it's already cumulative. Always double-check your data source—if it's "incremental," you must cumsum() it across the rows first.

Projecting the ultimate losses

Now for the payoff. We take the latest known value for each year and multiply it by the remaining factors to find the "Ultimate Loss." To get the reserve, we just subtract the current known losses from that ultimate value.

# Find the most recent cumulative loss for each year
latest_losses <- apply(claims_matrix, 1, function(x) x[!is.na(x)][length(x[!is.na(x)])])

# Calculate Cumulative Development Factors (CDF)
# The CDF is the product of all remaining age-to-age factors
cdf <- c(
  prod(age_to_age_factors),               # From 12m to Ultimate
  prod(age_to_age_factors[2:3]),         # From 24m to Ultimate
  prod(age_to_age_factors[3]),           # From 36m to Ultimate
  1                                      # From 48m to Ultimate
)

# Match the CDF to the development stage of each year
# 2023 is at 12m, 2022 is at 24m, etc.
years_stages <- c(4, 3, 2, 1) # Reverse order of development
ultimate_losses <- latest_losses * cdf[years_stages]

reserves <- ultimate_losses - latest_losses
names(reserves) <- rownames(claims_matrix)
print(reserves)



📋 Practical Task

Exercise: Estimating IBNR for a Workers' Comp Portfolio

You have been handed a cumulative claims triangle for a Workers' Compensation line of business. The data is provided as a matrix below. Your task is to implement a Chain Ladder estimation to determine the total IBNR (the sum of all reserves) for the portfolio.

# Data provided
wc_claims <- matrix(c(
  5000, 7500, 9000, 10000,
  6000, 8800, 11000, NA,
  5500, 8000, NA,    NA,
  7000, NA,   NA,    NA
), nrow = 4, byrow = TRUE)

Write a script to:

  • Calculate the three age-to-age factors.
  • Compute the Cumulative Development Factors (CDF) for each stage.
  • Calculate the individual reserves for each accident year.
  • Print the total aggregate reserve (the sum of all individual reserves) for the entire portfolio.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.