Ten days ago I post my first project to RIAForge. Its a pretty simple project as it only consists of one CFC and I would appreciate some feed back on the code. Hence the request for a code review.
This CFC is based on research and work that I did to be able to create a finance calculator for a client and works quite nicely. I'm also pleased to see that at the time of writing this post my project has already been viewed 700 times and downloaded 23 times. I hope you're finding it useful.
The CFC is, as the title of this blog post suggests an APR and IRR calculator and you can download it from RIAForge here : http://aprcfc.riaforge.org/.
So down to the reason for this blog post and the code review request.... You may or may not be aware, but the process of calculating IRR, in order to work out the APR, is basically guess work.
You pick a number, try it with your cash flow. If the sum of the NPV is not zero then you got it wrong and you need to make another guess and try that value instead. If the the sum of NPV is less then zero you need to use a smaller IRR. If its greater than zero, then you need to use a bigger IRR. Eventually you'll get an IRR that gives you a NPV of zero and you can then use the IRR to calculate the APR.
To manage this guess work in my component I've broken it down into a binary search. I start with a previous IRR of zero and a current guess of one. I then split the difference between the previous and current guess and try again. I keep trying until I get a sum of the NPV that is equal to zero or I've made 25 guesses.
Why 25 guesses you might ask. Well in practice I found that often I couldn't get exactly zero for the sum of the NPV, which means that the function will keep going until the request times out. After testing with a bunch of values I found that mostly the IRR was calculated at between 10 and 20 iterations, but sometimes I'd have a value close enough to zero as to make it negligible at around 23 iterations, so 25 was just a nice round number in that area. I also found that after this point the process was starting to take a long time to run. Imagine paying a loan back over 60 months (5 years). For cashflow for this period I have to calculate the NPV for each month and sum it all up. 60 years at 25 iterations is 1525 calculations (if you include summing the array of NPV). Its not a huge number of calculations, but when you're calling the function from AJAX you're talking about response times that while not huge can make the display a little sluggish.
This is the reason why I'd appreciate some feedback. I'm not particularly happy with this hack of stopping at a particular iteration. I'm wondering if there is something that I've missed or misunderstood with regards calculating IRR. I'm also wondering if I could write this better.
Calculations and my understanding of NPV, APR and IRR are based on information from wikipedea and a spreadsheet that I was supplied by the client. Before anyone asks I can't give out the spreadsheet, plus it doesn't really help as Excel has functions for calculating NPV and IRR built into it.
The code is written for ColdFusion 8, so while I'll be interested to here any ColdFusion 9 solutions, I won't be able to use them.
Thank you in advance for reading this far and for taking a look at my code should you decide to.