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-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On Behalf Of Adrian Ng Sent: Wednesday, August 25, 2010 8:39 AM To: r-help@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@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. ______________________________________________ R-help@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.