[R] Secant Method Convergence (Method to replicate Excel XIRR/IRR)

Ravi Varadhan rvaradhan at jhmi.edu
Wed Aug 25 23:10:18 CEST 2010


Hi Adrian,

Your code for the secant method is correct.

I just tweaked it a bit w/o the calendar time feature (assuming that the
cash flows will be available on an annual basis) as follows:

ANXIRR <- function (cashFlow, guess, tol=1.e-04){

npv <- function (cashFlow, irr) {
	n <- length(cashFlow)
	sum(cashFlow / (1 + irr)^{0: (n-1)})
	}

        irrprev <- c(0)
	  irr <- guess
        pvPrev <- sum(cashFlow)
        pv <- npv(cashFlow, irr)
	eps <- abs(pv-pvPrev)

while (eps >= tol) {
        tmp <- irrprev 
	 irrprev <- irr
        irr <- irr - ((irr - tmp) * pv / (pv - pvPrev))
        pvPrev <- pv
        pv <- npv(cashFlow, irr)
	 eps <- abs(pv - pvPrev)
        }
	list(irr = irr, npv = pv)
}

# example from Wikipedia enntry
cashflow <- c(-4000, 1200, 1410, 1875, 1050)

ANXIRR(cashflow, guess=0.05)  

> ANXIRR(cashflow, guess=0.05)
$irr
[1] 0.1429934

$npv
[1] 1.705303e-12


Hope this helps,
Ravi.

-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On
Behalf Of Adrian Ng
Sent: Wednesday, August 25, 2010 8:39 AM
To: r-help at r-project.org
Subject: [R] Secant Method Convergence (Method to replicate Excel XIRR/IRR)

Hi,

I am new to R, and as a first exercise, I decided to try to implement an
XIRR function using the secant method.  I did a quick search and saw another
posting that used the Bisection method but wanted to see if it was possible
using the secant method.

I would input a Cash Flow and Date vector as well as an initial guess.  I
hardcoded today's initial date so I could do checks in Excel.  This code
seems to only converge when my initial guess is very close to the correct
IRR.

Maybe I have some basic errors in my coding/logic? Any help would be greatly
appreciated.

The Wikipedia article to secant method and IRR:
http://en.wikipedia.org/wiki/Internal_rate_of_return#Numerical_solution

Thanks!



ANXIRR <- function (cashFlow, cfDate, guess){
        cfDate<-as.Date(cfDate,format="%m/%d/%Y")
        irrprev <- c(0); irr<- guess


        pvPrev<- sum(cashFlow)
        pv<-
sum(cashFlow/((1+irr)^(as.numeric(difftime(cfDate,"2010-08-24",units="days")
)/360)))
        print(pv)
        print("Hi")


while (abs(pv) >= 0.001) {
        t<-irrprev; irrprev<- irr;
        irr<-irr-((irr-t)*pv/(pv-pvPrev));
        pvPrev<-pv;
 
pv<-sum(cashFlow/((1+irr)^(as.numeric(difftime(cfDate,"2010-08-24",units="da
ys"))/365)))
        print(irr);print(pv)
        }
}





Please consider the environment before printing this e-mail.

	[[alternative HTML version deleted]]

______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list