Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any r package available to calculate IRR from uneven payments on specific dates?

Tags:

r

finance

Are there any R packages available that have some form of function that can calculate IRR based on uneven payments on specific dates for a lump sum distribution.

Example:

df <- data.frame(date = c(as.Date("2010-1-24"), as.Date("2011-5-6"), as.Date("2012-3-24")), pmts=c(-2000,-1000,-800))
today <- as.Date("2012-7-25")
lumpsum <- 4580

I'm looking for an easy way to calculate the rate of return of $4580 received today in exchange for the payment schedule defined above.

Thanks in advance, --JT

like image 447
JimmyT Avatar asked Jul 25 '12 23:07

JimmyT


People also ask

Which is the correct Excel formula function for calculating IRR when time periods are uneven?

Excel allows a user to get an internal rate of return of an investment when the returns timing is uneven using the XIRR function. If we want to calculate an internal rate where returns occur at regular intervals, we need to use the IRR function.

How do you calculate IRR in R?

# To calculate IRR we will use the IRR formula from the jrvFinance library irr1 <- project1_cf %>% select(cf) %>% . [[1]] %>% irr() irr2 <- project2_cf %>% select(cf) %>% .

What is the difference between Xirr and IRR?

As we've explained, the key difference between IRR and XIRR is the way each formula handles cash flows. IRR doesn't take into account when the actual cash flow takes place, so it rolls them up into annual periods. By contrast, the XIRR formula considers the dates when the cash flow actually happens.


2 Answers

As already noted in the comments it would be easier to write something simple:

NPV<-function(paym,pdates,IRR){
   ptimes<-as.Date(pdates)-min(as.Date(pdates))
   ptimes<-as.numeric(ptimes,units="days")/365.25
   NPV<-sum(paym*(1+IRR)^{-ptimes})
   NPV
}

nlm(function(p){NPV(c(lumpsum,df$pmts),c(today,df$date),p)^2},p=0.1)

gives a IRR of 11.26%

EDIT:

after a quick scout around the lifecontingencies package has a present value function if you want to use that instead.

library(lifecontingencies)
capitals<-c(lumpsum,df$pmts)
times<-c(today,df$date)
times<-as.Date(times)-min(as.Date(times))
times<-as.numeric(times,units="days")/365.25
presentValue(cashFlows=capitals, timeIds=times,interestRates=0.03)
nlm(function(p){presentValue(capitals,times,p)^2},p=0.1)
like image 50
shhhhimhuntingrabbits Avatar answered Nov 14 '22 18:11

shhhhimhuntingrabbits


pmr started with a great answer in his code sample. Thanks!

The problem I have with that code, however, is that the question (and my need as well) is to calculate the IRR when the cash flows have arbitrary times. pmr's code needs to be modified to have the irr function take the time vector t as an arg just like his npv function does.

To make this explicit, my adaptation of that code is:

# Returns the Internal Rate of Return.
# See: https://www.investopedia.com/terms/i/irr.asp
irr = function(t, cf) {
    uniroot(f = npv, interval = c(0, 1), t = t, cf = cf)$root
}

# Returns the Net Present Value.
# See: https://www.investopedia.com/terms/n/npv.asp
npv = function(t, cf, i) {
    sum( cf / (1 + i)^t )
}

Note that I changed the arg order (e.g. t first). Also, there is no default value for t, but if you want an even sequence, I think that landroni's comment is correct: your initial capital invested is at time = 0, not 1, as is clear in that investopedia link above the irr function.

Below is an example of how to use those functions that I faced. I was offered an opportunity to invest in an ATM network. These feature high annual returns (paid out monthly), but also are a rapidly depreciating asset (maybe 2% of your principal comes out at a final liquidation).

Execute the following code after first defining the functions above.

# parameters:
numYears = 7
capitalInvest = 52000
retAnnual = 0.245
capitalLiquidation = 700

# convert yearly values to mpnthly:
numMonths = numYears * 12
retMonthly = retAnnual / 12    # assumes no compounding

# initialize the time to 0 and the cash flow to capital SPENT (so negative):
t = 0
cf = -capitalInvest

# add monthly returns:
for (m in 1:numMonths) {
    t = c(t, m / 12)    # divide the time by 12 to have units of year
    cf = c(cf, retMonthly * capitalInvest)
}

# add liquidation value also on the final year:
t = c(t, numMonths / 12)    # divide the time by 12 to have units of year
cf = c(cf, capitalLiquidation)

# calculate the IRR:
irr(t, cf)

That code returned a value of 0.1852015 ~= 18.5% which agrees fairly closely with the value that the operator quoted me of 18.6%.

like image 28
HaroldFinch Avatar answered Nov 14 '22 20:11

HaroldFinch