On 2000-01-03, the New York Mets released aging slugger Bobby Bonilla. He was still under (guaranteed) contract for the 2000 season, so the team owed Bonilla $5.9 million in salary, that was due on July 1st of that year.
Bonilla and his agent worked out a deal where he would receive a 25-year ordinary annuity, deferred by an additional ten years, in lieu of the $5.9 million upfront. That means that, on every July 1st from 2011-35 inclusive, Bonilla’s annuity pays him $1,193,248.20.
Fred Wilpon, who owned the Mets at the time, was a key investor in one of Bernie Madoff’s Ponzi schemes, which was promising very high returns in perpetuity; so the Mets were happy to defer Bonilla’s salary into the distant future.
R does not have inbuilt “financial calculator” functions for time value of money, but there are several libraries (e.g. FinCal) that can give you those functions. The challenge is to solve Bonilla’s rate of return in base R, without calling any libraries like Fincal.
Since we aren’t using a financial calculator, we first need to come up with our own function that defines net present value.
my_npv <- function(rate, pmts, times){
return(sum(pmts/(1+rate)^times))
}
Now we need to model the cash flows:
in period 0, Bonilla defers $5,900,000.00
in periods 1-10, Bonilla receives nothing
in periods 11-35, Bonilla receives $1,193,248.20
CF <- rep(c(-5.9E6, 0, +1193248.20), c(1, 10, 25)) # cash flows
t <- seq(0,35) # time to each cash flow
Bonilla’s internal rate of return (IRR) is the discount that makes the net present value of his cash flows equal zero. Because there is no closed-form expression for a the roots of a polynomial equation of degree >4 (and our equation is of degree 35), there is no way to do this algebraically; it can only be approximated by iterative methods.
The nlm() function (non-linear minimization) can work. We don’t want to minimize NPV itself, because NPV can be negative. But if we minimize the SQUARE of NPV, we’re basically finding the zero.
r <- nlm(function(rate){my_npv(rate,CF,t)^2}, p = 0.10)$estimate
r
## [1] 0.0800001
Bonilla got 8% as his rate of return.
Let’s use the irr() function from the FinCal library and make sure we got the same answer.
FinCal::irr(CF)
## [1] 0.08000084