Introduction

These study notes are based on the Exam 9 syllabus reading Pricing Insurance Policies: The Internal Rate of Return Model by Sholom Feldblum. The paper describes the mechanics of the Internal Rate of Return (IRR) method for assessing insurance company profitability, and assesses the strengths and weaknesses of the method. This paper corresponds to learning objective D1 on the syllabus.

easypackages::packages("dplyr", "ggplot2")
options(scipen = 999)

Mechanics of the Method

Calculation of Equity Flows

The IRR method is based on assessing profitability from the perspective of the equity-holder. A comparison of the interaction between the product market and the financial market is summarized in the following table.
Product market Financial market
Party interacting with insurer Policyholder Equity provider
Cash flow to insurer Premium Invested funds
Cash flow from insurer Incurred losses Capital accumulation or dividends
Impact on other party Expected returns based insurance risk and customer demand Insurance supply based on cost of capital

Calculating the equity flows between the insurer and the equity provider is the first step in the IRR method. The general frame work is as follows, assuming that investment income is calculated each time the losses are paid:

  1. When an insurer writes a policy, deduct acquisition, underwriting, and administrative expenses from the premium. The net premium becomes the initial assets support reserves (initially unearned premium reserves, becoming loss reserves over time).

  2. Based on the loss amount and payout pattern, determine the amount of loss that needs to be paid in each year.

  3. Calculate theamount of surplus required in each time period based on a specified rule (e.g. target reserve-to-surplus ratio). Add this to the reserve to get the total required assets.

  4. The initial equity flow is the amount needed to bring the net premium amount up to the total required assets.

  5. Each time a claim payment is made:

  • Calculate the investment income on the current assets and add it

  • Deduct the claim payment amount from the assets

  • Based on the required assets in the next time period, determine how much surplus can be released to equityholders

  • Subtract the amount of surplus released from the assets

The example in the reading illustrates the above under the following assumptions:

  • A premium of $1000 is collected at time 0

  • Claims of $500 are paid at times 1 and 2

  • The company’s policy is to maintain a 2:1 undiscounted reserve-to-surplus ratio

  • The investment return is 10%.

premium = c(1000, 0, 0)
claims = c(0, 500, 500)
reserve.to.surplus = 2
investment.return = 0.1

Calculate the undiscounted reserve and surplus requirement. Then, each time a claim payment is made, calculate the investment income, deduct the claim payment, and determine the equity flows:

equity.flow.example = data.frame(time = 0:2, premium = premium, claims = claims)
total.claims = sum(claims)
equity.flow.example = equity.flow.example %>% mutate(undiscounted.reserve = total.claims - cumsum(claims), surplus.required = undiscounted.reserve / reserve.to.surplus, assets = undiscounted.reserve + surplus.required, investment.income = investment.return * lag(assets, default = 0), surplus.flow = -(lag(assets, default = 0) + investment.income + premium - claims - assets))
equity.flow.example
##   time premium claims undiscounted.reserve surplus.required assets
## 1    0    1000      0                 1000              500   1500
## 2    1       0    500                  500              250    750
## 3    2       0    500                    0                0      0
##   investment.income surplus.flow
## 1                 0          500
## 2               150         -400
## 3                75         -325

IRR Model Calculations

The IRR method involves determining the discount rate for which the net present value of equity flows is zero. In other words, if \(s_t\) is the equity flow at time \(t\), determine \(v\) such that \[ 0 = \sum_{0 \leq t \leq n} s_t v^t \] The discount rate can be converted to a rate of return via the relationship \[ v = \frac{1}{1+r} \] which is equivalent to \[ r = \frac{1}{v}-1. \]

In R, the roots of a polynomial can be found using the “polyroot” function. The input to this function is a vector of coefficients of the polynomial, starting with the constant term.

discount.rate = polyroot(equity.flow.example$surplus.flow)
discount.rate
## [1]  0.7692308+0i -2.0000000+0i

Negative values don’t correspond to valid discount rates:

v = discount.rate[1]
v
## [1] 0.7692308+0i

Convert to a rate of return:

r = 1/v - 1
r
## [1] 0.3+0i

As a variation, suppose we are not provided with the initial premium, and we want to determine the premium which provides an internal rate of return equal to 30%. As long as the surplus requirement is defined in terms of reserve, note that the surplus requirement and total assets are independent of premium; the only equity flow that is premium-dependent is the first one. Therefore, we can discount all future equity flows at the target rate of return, and then determine the premium net of expenses. Perform this calculation using target rates of both 30% and 25%:

premium.calculation = equity.flow.example %>% filter(time > 0) %>% mutate(discount_30 = 1 / 1.3^time, discount_25 = 1 / 1.25^time)
premium.calculation
##   time premium claims undiscounted.reserve surplus.required assets
## 1    1       0    500                  500              250    750
## 2    2       0    500                    0                0      0
##   investment.income surplus.flow discount_30 discount_25
## 1               150         -400   0.7692308        0.80
## 2                75         -325   0.5917160        0.64

For the target rate of 30%:

initial.equity.30 = - sum(premium.calculation$surplus.flow * premium.calculation$discount_30)
premium.required.30 = equity.flow.example %>% filter(time == 0) %>% select(assets) - initial.equity.30
print(paste0("The required premium is ", premium.required.30))
## [1] "The required premium is 1000"

For the target rate of 25%:

initial.equity.25 = - sum(premium.calculation$surplus.flow * premium.calculation$discount_25)
premium.required.25 = equity.flow.example %>% filter(time == 0) %>% select(assets) - initial.equity.25
print(paste0("The required premium is ", premium.required.25))
## [1] "The required premium is 972"

IRR Decision rule

An insurance policy is viewed as being sufficiently profitable to justify writing it if and only if its internal rate of return exceeds the cost of equity capital. In the example above, provided the cost of equity capital is below 30%, the insurer is incentivized to write the policy.

Surplus Considerations

The IRR requires the specification of an explicit surplus policy. The rationale for this is that the actual surplus held by the insurer may result from happenstance rather than deliberate strategy — so the method is based on the amount of surplus that the insurer “should” have based on assumptions made by the actuary.

Considerations in selecting a surplus policy include:

  1. What measure is the basis for determining surplus? Premium, reserves, or future losses?

  2. When is the surplus allocated and when is it released?

  1. Should the amount of surplus change based on the type of policy?

In general, if the surplus allocation is higher, then the internal rate of return will decrease, moving closer to the after-tax investment rate.

Suppose that in the previous example, we specified a premium-to-surplus ratio of 2, rather than a reserve-to-surplus ratio. Here’s how the required surplus would change:

premium.to.surplus = 2

We can repeat the example with this new requirement:

equity.flow.example = data.frame(time = 0:2, premium = premium, claims = claims)
total.claims = sum(claims)
equity.flow.example = equity.flow.example %>% mutate(undiscounted.reserve = total.claims - cumsum(claims), surplus.required = premium / premium.to.surplus, assets = undiscounted.reserve + surplus.required, investment.income = investment.return * lag(assets, default = 0), surplus.flow = -(lag(assets, default = 0) + investment.income + premium - claims - assets))
equity.flow.example
##   time premium claims undiscounted.reserve surplus.required assets
## 1    0    1000      0                 1000              500   1500
## 2    1       0    500                  500                0    500
## 3    2       0    500                    0                0      0
##   investment.income surplus.flow
## 1                 0          500
## 2               150         -650
## 3                50          -50

Calculate the corresponding IRR:

discount.rate = polyroot(equity.flow.example$surplus.flow)
v = discount.rate[1]
r = 1/v - 1
r
## [1] 0.3728416+0i

The faster return of surplus produces a higher IRR.

Suppose instead that the company specifies a loss reserve to surplus ratio of 0.5. In the above example, we are assuming that the “reserve” is an unearned premium reserve in the first year, and a loss reserve in subsequent years. Repeat the example with this new requirement:

loss.res.to.surplus = 0.5
equity.flow.example = data.frame(time = 0:2, premium = premium, claims = claims)
total.claims = sum(claims)
equity.flow.example = equity.flow.example %>% mutate(undiscounted.reserve = total.claims - cumsum(claims), surplus.required = ifelse(time > 0, undiscounted.reserve / loss.res.to.surplus, 0), assets = undiscounted.reserve + surplus.required, investment.income = investment.return * lag(assets, default = 0), surplus.flow = -(lag(assets, default = 0) + investment.income + premium - claims - assets))
equity.flow.example
##   time premium claims undiscounted.reserve surplus.required assets
## 1    0    1000      0                 1000                0   1000
## 2    1       0    500                  500             1000   1500
## 3    2       0    500                    0                0      0
##   investment.income surplus.flow
## 1                 0            0
## 2               100          900
## 3               150        -1150

Calculate the corresponding IRR:

discount.rate = polyroot(equity.flow.example$surplus.flow)
v = discount.rate[2]
r = 1/v - 1
r
## [1] 0.2777778+0i

Potential Pitfalls in IRR Analyses

The IRR method is essentially the inverse problem of a net present value (NPV) analysis, in which the discount rate is fixed and the net present value is calculated.

Sign Reversals

A key drawback of the IRR is that there may not be a unique positive real root for the cash flow polynomial. Descartes’ rule of signs states that the number of positive real roots is at most the number of sign reversals in the sequence of coefficients of the polynomials. Therefore, the IRR will not necessarily give a unique result when cash flows alternate between positive and negative, as illustrated in this example:

ambiguous.IRR = polyroot(c(-7200, 17000, -10000))
ambiguous.IRR
## [1] 0.8-0i 0.9+0i
1 / ambiguous.IRR - 1
## [1] 0.2500000+0i 0.1111111-0i

In this example, a cash outflow of $7200 followed by an inflow of $17,000 and then another outflow of $10,000 produces two different internal rates of return: 25% and 11%. The problem can be visualized by calculating the net present value of the cash flow pattern at various interest rates.

NPV.example = function(interest.rate) {
  discount.factor = 1 / (1 + interest.rate)
  return(-7200 + 17000 * discount.factor - 10000 * discount.factor^2)
}
ambiguous.IRR.table = data.frame(interest_rate = 1:30 * 0.01)
ambiguous.IRR.table$NPV = apply(ambiguous.IRR.table, 1, function(y) {NPV.example(y['interest_rate'])})
ggplot(data = ambiguous.IRR.table, aes(x = interest_rate, y = NPV)) + geom_hline(yintercept = 0, colour = "red") + geom_line()

The NPV approach shows that there is a positive return whenever the rate of return is between 11.1% and 25%.

In an insurance context, multiple sign reversals are unlikely to occur when dealing with expected cash flows; if they do occur, then projections should be re-examined. Multiple sign reversals may occur in actual cash flows due to unanticipated IBNR that causes an increase in required surplus.

Mutually Exclusive Projects

When comparing two or more projects, an NPV analysis will provide a more accurate ranking of the projects. Feldblum provides an example of two projects with the same initial outflow:
  • Project A requires an initial investment of $12,000, then produces $10,000 of revenue at time 1 and $6500 at time 2
  • Project B requires an initial investment of $12,000, then produces $5000 of revenue at time 1 and $12,500 at time 2

The IRR for Project A is:

project.A.discount = polyroot(c(-12000, 10000, 6500))
1/project.A.discount[1] - 1
## [1] 0.2624076+0i
project.B.discount = polyroot(c(-12000, 5000, 12500))
1/project.B.discount[1] - 1
## [1] 0.25+0i

Based on the IRR analysis, Project A looks like the better project.

Next, compare to an NPV analysis.

project.A.NPV = function(interest.rate) {
  discount.factor = 1 / (1 + interest.rate)
  return(-12000 + 10000 * discount.factor + 6500 * discount.factor^2)
}
project.B.NPV = function(interest.rate) {
  discount.factor = 1 / (1 + interest.rate)
  return(-12000 + 5000 * discount.factor + 12500 * discount.factor^2)
}
mutually.exclusive.NPV = data.frame(interest_rate = 1:30 * 0.01)
mutually.exclusive.NPV$project_A = apply(mutually.exclusive.NPV, 1, function(y) {project.A.NPV(y['interest_rate'])})
mutually.exclusive.NPV$project_B = apply(mutually.exclusive.NPV, 1, function(y) {project.B.NPV(y['interest_rate'])})
ggplot(data = mutually.exclusive.NPV, aes(x = interest_rate, y = project_A)) + geom_line(colour = "blue") + geom_line(aes(y = project_B), colour = "green")

This illustrates that Project B is preferred when the interest rate is below 20%, and Project A is preferred when the rate is above 20%.

The reason for the difference in the two approaches is that the IRR implicitly assumes that the revenue is being re-invested at the IRR, when in actuality, it can only be re-invested at the cost of capital. One way to address this is to assume that the first year cash flow is immediately re-invested for one year at the cost of capital. This produces an interest-rate sensitive IRR that now gives the same ranking of the projects as the NPV approach:

project.A.IRR = function(interest.rate) {
  cash.flow = c(-12000, 0, 6500 + 10000 * (1 + interest.rate))
  discount.rate = polyroot(cash.flow)[1]
  return(Re(1 / discount.rate - 1))
}
project.B.IRR = function(interest.rate) {
  cash.flow = c(-12000, 0, 12500 + 5000 * (1 + interest.rate))
  discount.rate = polyroot(cash.flow)[1]
  return(Re(1 / discount.rate - 1))
}
mutually.exclusive.IRR = data.frame(interest_rate = 1:30 * 0.01)
mutually.exclusive.IRR$project_A = apply(mutually.exclusive.IRR, 1, function(y) {project.A.IRR(y['interest_rate'])})
mutually.exclusive.IRR$project_B = apply(mutually.exclusive.IRR, 1, function(y) {project.B.IRR(y['interest_rate'])})
ggplot(data = mutually.exclusive.IRR, aes(x = interest_rate, y = project_A)) + geom_line(colour = "blue") + geom_line(aes(y = project_B), colour = "green")

Note that by shifting all cash flows to the final time period, the above approach essentially trivializes the IRR calculation. It’s effectively just an NPV analysis in the reverse direction: rather than discounting to time 0, we cumulate interest to time \(n\). In other words, this doesn’t give a method that’s materially different from the NPV apprach; it just explains the reason for the discrepancy between the NPV and IRR approaches.

The concerns about the re-investment rate assumption are generally not relevant to the insurance industry for two reasons:

  1. In many cases, the insurer can re-invest at the IRR by writing additional policies, provided it can maintain the same quality of risks.

  2. The typical use case for IRR analysis is to set premium rates such that the IRR equals the cost of equity capital. For this application, the IRR and NPV approaches give the same result.

Impact of Premium Inadequacy

The IRR approach can do a poor job of detecting premium inadequacy. In cases where the surplus requirement is based on reserves, higher losses will correspond to an assumption of a greater surplus commitment, with higher investment income partially offsetting the losses. The result is that the IRR can remain positive even in situations of extreme premium inadequacy.

Feldblum presents the following scenario:
  • Initial premium is $10,000
  • A single loss is paid at time 4
  • The loss is funded through the purchase of a 10% no-coupon bond
  • A 2:1 ratio of undiscounted reserves to surplus is assumed

The IRR can be calculated under a variety of assumptions about the undiscounted loss ratio:

inadequate.premium.IRR = function(undiscounted.LR) {
  loss.payment = undiscounted.LR * 10000
  surplus.required = loss.payment / 2
  equity.required = loss.payment + surplus.required - 10000
  bond.payment = (10000 + equity.required) * 1.1^4
  equity.released = bond.payment - loss.payment
  discount.rate = polyroot(c(equity.required, 0, 0, 0, -equity.released))
  IRR = Re(1 / discount.rate[4] - 1)
  return(IRR)
}
inadequate.premium.IRR(1.2)
## [1] 0.157362

By varying the undiscounted loss ratio assumption, we can see that the IRR remains positive even as the policy becomes extremely unprofitable:

inadequate.premium.data = data.frame(undiscounted_LR = 100:400)
inadequate.premium.data$IRR = apply(inadequate.premium.data, 1, function(y) {inadequate.premium.IRR(y['undiscounted_LR']/100)})
ggplot(data = inadequate.premium.data, aes(x = undiscounted_LR, y = IRR)) + geom_line()