NPV & IRR Version 2.1beta1 (c) 1997 Bob Wolfson (bwolfson@myself.com) RPN.1.z [0]#'20'; [9]#'16'; [L]CA Ca0<; [l]CA CawCaC9=@ Ca1n> C01+Ca> &&!; [D]D'Illegal R; R>0 only.|OK|' d1; [d]D'Illegal N; Integer 0-20 only.|OK|' d1; [r]xz;[R]Xz; [n]xy;[N]Xy; [a]xx;[A]Xx; [b]xw;[B]Xw; [m]xv;[M]Xv; [v]0V0{v1+x@ + v1+V vCn>(B)}; [V]0V0{v1+x@ CrvP/+ v1+V vCn>(B)}; [P]Cr0C9=@(Cv:CV); [I]Cr#'.01'-CA {CrCa- CP CaCRCPCB Cb-r2/CM CaCm*Cb-Cm/CA CrCa=7(B)} CaCRCr1-; "NPV & IRR2.1beta1" "CA"#'20'V{0v1+X@ _v}; "NPV"CP; "IRR"CI; ~ "C0"Xa0CN1; "CN"r2Cl(Cd Car2;) CaCn>(CaCN) Ca1+X@ Ca1+; "N"Cl(Cd Ca:CaCN); "R"CL(CD Ca:Ca1+CR); ~ "Co"xa; "Cn"Cl(Cd Ca;) Ca1+x@; "n"Cn; "r"Cr1-; NPV & IRR Version 2.1beta1 Documentation (c) 1997 Bob Wolfson Email: bwolfson@myself.com *** Legal Matters ***************************************************************************** The NPV & IRR Version 2.1beta1 script and documenation is FREEWARE. You may use and distribute it freely provided that you do so without modification. The NPV & IRR script and documentation are provided with no expressed or implied warantees of any kind. You accept the script and documentation in "as is" condition, and agree to use them at your own risk and without attributing any liability to the author. *********************************************************************************************** *** INTRODUCTION The NPV & IRR script calculates Net Present Value and Internal Rate of Return from multiple cash flows, similar to the way an HP12C handles the process. Up to 11 flows, known as C0, C1, C2, ... , C20 can be handled. C0 occurs at time 0, and the remaining flows occur at regular intervals thereafter. NPV calculates the sum of the present values of the flows at some stated interest rate, R. IRR calculates the interest rate at which NPV would be zero. The script provides the following buttons: CA - zeroes out all entries NPV - invokes the NPV calculation and puts the result on the stack IRR - invokes the IRR calculation and puts the result both on the stack and in R. C0 - key the C0 value, and press C0 to enter it. You will see '1' appear on the top of the stack, representing the index of the next flow to be entered. CN - put an index on the stack (an integer, 0 through 20 inclusive), then key a value and press CN to set enter the value as the flow of the given index. You will see the index plus 1 appear on the stack, representing the index of the next flow to be entered. N - used to set the index of the highest flow. Not normally needed. N must be an integer between 0 and 20 inclusive. R - used to set the interest rate. Key a value as a decimal number, e.g. 12% is 0.12, and press R. R must be greater than or equal to zero. Co - used to recall the value of C0. Cn - used to recall the value of a flow. Key an index onto the stack (an integer, 0 through 20 inclusive) and press Cn to recall the corresponding flow value. n - used to recall the value of N. r - used to recall the value of R. *** ENTERING FLOWS The flow entry process is designed to allow you to easily enter C0, C1, ... in that order. In general, you enter C0 by keying its value and pressing C0. You enter another flow by entering an index value onto the stack, keying the flow value and pressing CN. However, any time you enter a flow, the script puts the index of the *next* flow onto the top of the stack. If you enter the flows in order, the process looks like: value C0 value CN value CN ... For example, the sequence: 111 C0 222 CN 333 CN breaks out as follows: 111 C0 Enters C0 as the value 111 (and puts 1 on the stack) 222 CN Enters C1 as the value 222 (and puts 2 on the stack) 333 CN Enters C2 as the value 333 (and puts 3 on the stack) If you need to go back and correct a flow, do the following: index Enter value CN Following from the example above, 1 Enter 666 CN would change C1 from 222 to 666, and leave 2 on the stack. Futhermore, N is set to 0 when C0 is pressed, and to the maximum of its current value or the current index value when CN is pressed. Therefore, even if you enter indexes out of order, N should be the index of the highest flow. To recall C0, press Co. To recall C1-C20, key its index and press Cn. Following from the above example, 3 Cn would put 333 on the stack. *** EXAMPLE You want to purchase a property for $79,000 and think you'll get around a 13.5% return. In 10 years the property should sell for $100,000. Meanwhile, you expect to realize yearly flows as follows: $14,000 $11,000 $10,000 $10,000 $10,000 $9,100 $9,000 $9,000 $4,500 What is the NPV and the IRR? Perform the following operations: CA (Clear everything to 0) 79000 +/- C0 (-$79,000 at time of purchase) 14000 CN (end of year 1) 11000 CN (end of year 2) 10000 CN (end of year 3) 10000 CN (end of year 4) 10000 CN (end of year 5) 9100 CN (end of year 6) 9000 CN (end of year 7) 9000 CN (end of year 8) 4500 CN (end of year 9) 100000 CN (sale value at end of year 10) .135 R (interest rate of 13.5%) NPV (puts 907.7689... on the stack) IRR (puts 0.137197... on the stack, 13.72%) *** IRR CALCUATIONS The process for calculating IRR involves finding a root of the equation NPV(R) = 0. To do so, the script uses an iterative process that starts with a guess which it refines in each loop. (FYI, it's a Newton-Raphson convergence algorithm.) You must provide the initial guess. This should not be too hard. Just find an R that brings NPV to a "low" value. Try to pin R down to "within reason" before pressing IRR. Note that the IRR result replaces your initial guess and is also put on the stack. The IRR calculation may take a little while. Ten seconds would not be unusual. Depending on the accuracy of your initial guess, it may take longer. Because the NPV function is pretty smooth, the iterative process *should* converge on a solution. As a result, NO PRECAUTIONS have been taken to avoid a runaway algorithm in this version of the script. Still, it's theoretically possible to encounter a situation where successive guesses are getting *worse* in each iteration and never settling down. If you suspect the IRR calculation is running away you can get out of it by turning off the Pilot. This will throw RPN into debug mode when you turn the Pilot back on, and you can press the Stop button in the RPN debug dialog. Please report any such problems to bwolfson@myself.com. *** CHANGES HISTORY * Version 2.1beta1: - Modified to be compatible with RPN 2.1. Some RPN 2.1 byte code changes make the code execute faster. - Increased allowed number of flows to 21 (C0 through C20.) - Added error messages for attempts to use illegal values of R and N. * Version 1.0beta1 - Initial release.