(11C) TVM for HP-11C - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: HP Software Libraries (/forum-10.html) +--- Forum: General Software Library (/forum-13.html) +--- Thread: (11C) TVM for HP-11C (/thread-12941.html) |
(11C) TVM for HP-11C - Gamo - 05-09-2019 01:15 AM TVM program that work just like HP-12C. Program credit to Gene Wright's website https://www.rskey.org/gene/hpgene/tvm19c.htm As mentioned in Gene Wright page this program originally appeared in the May 1980 PPC Journal written by Robert Meyer. The program will run as written on an HP-19C/29C Since 19C doesn't have specific Labels. I modify this program so that Labels A to E located at the same position as on HP-12C With added-on Labels and use many Store Registers this took me awhile to make this program work since 11C got limited program space when use a lot of store memory registers. Finally I have successfully fit this program to work on 11C at which it use 111 program lines at its maximum limit. Lastly this might be an excellent TVM program for 11C compare to that of the more sophisticated TVM program available in the 15c advanced functions handbook that use SOLVE function to solve for unknown interest. TVM for HP-11C program: [attachment=7223] Gamo RE: (11C) TVM for HP-11C - Gamo - 12-03-2019 10:12 AM Last post I didn’t give an example on how to use this TVM program. These two example are from the HP-12C User’s Handbook. —————————————————————————————- USER mode with FIX 2 What annual interest rate must be obtained to accumulate $10,000 in 8 years on an investment of $6,000 with quarterly compounding? 8 [ENTER] 4 [x] [A] display 32.00. // Calculates and stores n. 6000 [CHS] [C] display –6,000.00 // Stores PV (with minus sign for cash paid out). 10000 [E] display 10,000.00 // Stores FV. [B] [R/S] display 1.61 // Periodic (quarterly) interest rate. 4 [x] display 6.44 Annual interest rate. Remark: This problem is in END mode the default setting with 0 on Register .0 —————————————————————————————— If you deposit $50 a month (at the beginning of each month) into a new account that pays 6 1/4% annual interest compounded monthly, how much will you have in the account after 2 years? Beginning Mode set 1 on Register .0 // ( 1 [STO] .0 ) 2 [ENTER] 12 [x] [A] display 24.00 // Calculates and stores n. 6.25 [ENTER] 12 [÷] display 0.52 // Calculates and stores i. 50 [CHS] [D] display –50.00 // Stores PMT (with minus sign for cash paid out). [E] [R/S] display 1,281.34 // Balance after 2 years. —————————————————————————————- Gamo RE: (11C) TVM for HP-11C - Gamo - 02-13-2020 06:14 AM Interest Rate Solver Solutions for 1. Direct Reduction Loan Interest Rate with known [n, PV and PMT] 2. Sinking Fund Interest Rate with known [n, FV and PMT] This program is adapted form the HP-55 Mathematic Programs ---------------------------------------- Procedure: [USER] mode [FIX] 2 Input n [A] PV or FV [ENTER] PMT [R/S] Your Guess [R/S] For Suggested Guess Problem with PV use [B] Problem with FV use [D] [C] Solve for Direct Reduction (Problem involve PV and PMT) [E] Solve for Sinking Fund (Problem involve FV and PMT) ------------------------------------------- Example: 1. Problem involve: n, PV and PMT n=12 PV=5,000 PMT=500 12 [A] 5000 [ENTER] 179.86 [R/S] display 27.80 Use Suggested Guess: [B] display 3.06% [C] display answer: 2.92% ---------------------------------------- 2. Problem involve: n, FV and PMT n=12 FV=5,000 PMT=400 12 [A] 5000 [ENTER] 400 [R/S] display 8.33 Use Suggested Guess [D] display 0.75% [E] display answer: 0.74% --------------------------------------- Program: Code:
RE: (11C) TVM for HP-11C - bshoring - 12-02-2020 09:02 PM Thank you for this great program. It works extremely well. Can you tell me what method it uses to solve for “i” (interest)? It works well, but anything you can tell me about how it works would be appreciated. Thanks, Bob RE: (11C) TVM for HP-11C - Gamo - 12-03-2020 08:23 AM Bob thanks for the interest of this wonderful TVM program for the HP-11C I solely adapted this program from May 1980 PPC Journal written by Robert Meyer and I do not know the algorithm use to find the interest in this program. If anyone know please share your experience in this very excellent program. Gamo RE: (11C) TVM for HP-11C - Dave Britten - 12-03-2020 01:48 PM The May 1980 PPC Journal has a brief description of how the original 29C version works. A short excerpt: Quote:All calculations call on LBL 6 placing the following results in the stack: X: PV, Y: -(BAL or FV)(1+i)^-N, L: PMT(A)[1-(1+i)^-N]/i. I(%) = 100i is found by a rearranged version of the John Kennedy and Chris Stevens Newton's method program (V6N5P10) and may take up to a couple of minutes to solve. Also, I've used this on my 11C a couple of times. It's an excellent program. RE: (11C) TVM for HP-11C - bshoring - 12-03-2020 05:53 PM Dave, Thanks. Any idea where I can get the original article. If I understand correctly, this program uses a modified Newton method to solve. Thanks, Bob RE: (11C) TVM for HP-11C - Dave Britten - 12-03-2020 06:08 PM (12-03-2020 05:53 PM)bshoring Wrote: Dave, Thanks. Any idea where I can get the original article. If I understand correctly, this program uses a modified Newton method to solve. Jake Schwartz's PPC Archive has all issues of the PPC Journal - as well as numerous other publications and materials from around the world - and is well worth the small price: http://www.pahhc.org/ppccdrom.htm There are tens of thousands of pages on this thing, so clear your schedule. RE: (11C) TVM for HP-11C - Albert Chan - 12-03-2020 08:53 PM (12-03-2020 05:53 PM)bshoring Wrote: If I understand correctly, this program uses a modified Newton method to solve. Yes ! Let a = (PV+FV)/(-PMT), using cash-flow sign-convention (results of post#3, LBL A) We can interpret it as number of payments, if interest rate is zero. Case FV=0: a*i/(1-k) = 1 → f(i) = a*i - (1-k) = 0 → f'(i) = a - k*n/(1+i) Code: function pv_i(n, a, i) Case PV=0: a*i/(K-1) = 1 → f(i) = a*i - (K-1) = 0 → f'(i) = a - K*n/(1+i) Code: function fv_i(n, a, i) Iterations were setup with Newton's method. But, denominator is not quite f'(i), resulting in better correction. lua> g = pv_i(12, 5000/500) -- guess_i = 0.030555555555555558 lua> g(), g(), g() 0.02922075497755343 0.02922854050171087 0.029228540769134212 lua> g = fv_i(12, 5000/400) -- guess_i = 0.00749063670411985 lua> g(), g(), g() 0.007390656157378769 0.007390622804155507 0.007390622804147247 RE: (11C) TVM for HP-11C - Albert Chan - 12-04-2020 08:01 PM (12-03-2020 08:53 PM)Albert Chan Wrote: Iterations were setup with Newton's method. More important reason for modified denominator is safety. Note: below proofs required Bernoulli inequality, i>-1, n ≤ 0, or n ≥ 1: \(\quad(1+i)^n ≥ 1 + n\,i\) Quote:Case FV=0: a*i/(1-k) = 1 → f(i) = a*i - (1-k) = 0 → f'(i) = a - k*n/(1+i)If we use f'(i) for Newton's denominator, and f'(i) ≤ 0, it is likely it would converge to trivial solution, i=0 Replacing with modified slope, (1-k)/i - k*n/(1+i), we remove this problem. Proof: Let K = 1/k = (1+i)^n ≥ 1 + n*i → (K-1)/i ≥ n Modified slope = \(\large {1-k \over i} - {k\,n \over 1+i} = k \left({K-1 \over i} - {n \over 1+i}\right) ≥ k \left(n - {n \over 1+i}\right) = {k\,n\,i \over i+1} \) If i > 0, n ≥ 1, then modified slope will be positive. Quote:Case PV=0: a*i/(K-1) = 1 → f(i) = a*i - (K-1) = 0 → f'(i) = a - K*n/(1+i) Same issue as above. But, this time we wanted negative "slope". Replacing with modified slope, (K-1)/i - K*n/(1+i), we remove this problem. Proof: Modified slope = \(\large{(K-1)(1+i)\;-\;K\,n\,i \over i\,(1+i)} = {K\over i\,(1+i)} \normalsize (1+(1-n)\,i - (1+i)^{1-n} )\) Applying Bernoulli inequality, last term is non-positive. If i > 0, n ≥ 2, then modified slope will be negative. RE: (11C) TVM for HP-11C - Albert Chan - 12-05-2020 01:05 AM From thread: Fun math algorithms: (10-19-2020 11:05 PM)Albert Chan Wrote: We can use \(C_±\) to solve Time value of money problem, if I is small, and N not too big. XCas> factor(symb2poly(eqn,I)); // quadratic coefficients, for I [N^2*(FV+PV)/12 , (-FV*N+N*PV+FV+PV)/2 , N*PMT+FV+PV] Divide coefficiens by (FV+PV): [N^2/12 , (1 - N*(FV-PV)/(FV+PV))/2, PMT*N/(FV+PV) + 1] Solving the quadratic, for the "small" root of I, we have: Code: function guess_i(n, pv, pmt, fv) -- cash-flow sign convention (12-03-2020 08:53 PM)Albert Chan Wrote: lua> g = pv_i(12, 5000/500) -- guess_i = 0.030555555555555558 For above examples, guess_i() gives about 3 good digits. lua> guess_i(12, 5000, -500, 0) 0.02919560045657818 lua> guess_i(12, 0, -400, 5000) 0.007391943630478942 RE: (11C) TVM for HP-11C - Albert Chan - 12-05-2020 03:46 AM A faster version of guess_i(), replaced sqrt() by its Pade approximation This is also safer, avoided sqrt of negative number issue. Code: function guess_i(n, pv, pmt, fv) -- cash-flow sign convention lua> guess_i(12, 5000, -500, 0) 0.029199705714052143 lua> guess_i(12, 0, -400, 5000) 0.007391911604953607 Update: formula adjusted so fv+pv=0 will give i = pmt/fv, instead of NaN RE: (11C) TVM for HP-11C - Albert Chan - 12-06-2020 02:32 PM pv_i() and fv_i() are similar, we can combine them. Just keep pv_i(), using previous post guess_i() for the guess. Code: function pv_i(n, a, i) -- a = -pv/pmt lua> g = pv_i(12, 5000/500) lua> g(), g() 0.029228537101221044 0.029228540769133633 For fv_i() problems, where PV=0, add negative sign for the input. In other words, fv_i(n, a) ≡ pv_i(-n, -a) lua> g = pv_i(-12, -5000/400) lua> g(), g() 0.007390622809688779 0.007390622804149185 This setup has another advantage, with invariant: sign(i) = sign(n-a) For above examples, 12 > 10, -12 > -12.5, thus positive interest rate. Update: numbers adjusted with updated guess_i() RE: (11C) TVM for HP-11C - Albert Chan - 12-06-2020 04:41 PM (12-06-2020 02:32 PM)Albert Chan Wrote: For fv_i() problems, where PV=0, add negative sign for the input. Proof: Let K = (1+I)^N. TVM equation (NFV = 0): PV*K + PMT*(K-1)/I + FV = 0 Travel backward in time: (N, PV, PMT, FV) := (-N, FV, -PMT, PV) FV/K - PMT*(1/K-1)/I + PV = 0 Multiply by K, we recover the original TVM equation. ⇒ fv_i(n, a) = fv_i(n, FV/-PMT) = pv_i(-n, PV/PMT) = pv_i(-n, -a) Since guess_i() is based on TVM, it can travel backward in time too. Example taken from Fun Math Algorithms, car lease APR estimate. lua> n, pv, pmt, fv = 36, 30000, -550, -15000 lua> guess_i(n, pv, pmt, fv) * 1200 6.9657545218584485 lua> guess_i(-n, fv, -pmt, pv) * 1200 6.9657545218584485 Update: numbers adjusted with updated guess_i() RE: (11C) TVM for HP-11C - Albert Chan - 12-07-2020 06:55 PM For getting interest rate for the general case, npmt() is very nice formula. TVM equation, for "net payment", NPMT = NFV * i/(K-1): Code: require 'mathx' lua> n, pv, pmt, fv = 36, 30000, -550, -15000 lua> i1 = guess_i(n, pv, pmt, fv) lua> p1 = npmt(n, i1, pv, pmt, fv) lua> i1, p1 0.005804795434882038 -0.006442911074373114 lua> i2 = 1.001*i1 -- p1<0, i1 is a bit low lua> p2 = npmt(n, i2, pv, pmt, fv) lua> i2, p2 0.005810600230316919 0.12838859778003098 lua> i1 - p1/(p2-p1) * (i2-i1) -- secant's method 0.005805072816490459 For comparison, with same i1, i2, and secant's method, for other TVM formula: 0.005805072843740277 -- NPV formula 0.005805072788863714 -- NFV formula Solve npmt()=0, using Newton's method, we have: (guess_i code here) Code: function loan_rate(n, pv, pmt, fv, i) lua> g = loan_rate(n, pv, pmt, fv) lua> g(), g() 0.005805072819567153 0.005805072819420132 lua> g = loan_rate(-n, fv, -pmt, pv) -- time symmetric, as expected lua> g(), g() 0.005805072819567159 0.005805072819420132 Update: numbers adjusted with updated guess_i() RE: (11C) TVM for HP-11C - Albert Chan - 12-08-2020 03:05 PM (12-07-2020 06:55 PM)Albert Chan Wrote: lua> i2 = 1.001*i1 -- p1<0, i1 is a bit low We can avoid thinking about direction, and how much adjustment, for i2 If zero interest, npmt = (pv+fv)/n + pmt, we can use this to get i2 lua> n, pv, pmt, fv = 36, 30000, -550, -15000 lua> i1 = guess_i(n, pv, pmt, fv) lua> p1 = npmt(n, i1, pv, pmt, fv) lua> function secant(x1,y1,x2,y2) return x1 - y1/(y2-y1)*(x2-x1) end lua> i2 = secant(i1, p1, 0, (pv+fv)/n + pmt) lua> p2 = npmt(n, i2, pv, pmt, fv) lua> i3 = secant(i2, p2, i1, p1) lua> table.foreachi({i1,i2,i3}, print) 1 0.005804795434882038 2 0.005805075946792827 3 0.005805072819418476 RE: (11C) TVM for HP-11C - Albert Chan - 05-10-2022 09:35 PM (12-05-2020 01:05 AM)Albert Chan Wrote: From thread: Fun math algorithms: I noticed exact definition of C, if we take away N*I/2, it turned to even function (of N) XCas> C := I*N/(1 - (1+I)^-N) XCas> simplify(C - C(N=-N)) → N*I XCas> series(C - N*I/2, I, 0, 3, polynom) // even powers of N, as expected 1 + I/2 + (-1+N^2)/12*I^2 + (1-N^2)/24*I^3 If we define Ce = C - I*N/2, we avoided thinking of "backward in time" with negative (N,PMT) Quoted C(d) dropped the term I^2/12, we might as well put it back in. XCas> Ce := 1 + I/2 + (N^2-1)/12*I^2 // truncated O(I^3) terms XCas> NPMT := (Ce+N*I/2)*PV + (Ce-N*I/2)*FV + N*PMT XCas> factor(e2r(NPMT,I)); // quadratic coefficients, for I [(N^2-1)*(FV+PV)/12, (-FV*N+N*PV+FV+PV)/2 , N*PMT+FV+PV] Only difference with previous version is N^2 replaced by (N^2-1) Code: function guess_i(n, pv, pmt, fv) -- cash-flow sign convention Examples shown in this thread, estimated rate slightly improved. With updated guess_i(n, pv, pmt, fv): lua> guess_i(12, 5000, -500, 0) -- OP example 0.029209500177242102 lua> guess_i(12, 0, -400, 5000) -- OP example 0.007391057003072031 lua> guess_i(36, 30000, -550, -15000) -- car lease example 0.0058048457798059476 RE: (11C) TVM for HP-11C - Albert Chan - 05-11-2022 01:07 PM We can estimate rate using simple formula, by "setting" PV=0, or FV=0 NPMT = (Ce+N*I/2)*PV + (Ce−N*I/2)*FV + N*PMT = (Ce+N*I/2)*(PV+FV) + N*(PMT−FV*I) // (PV,FV,PMT) → (PV+FV, 0, PMT−FV*I) = (Ce−N*I/2)*(PV+FV) + N*(PMT+PV*I) // (PV,FV,PMT) → (0, PV+FV, PMT+PV*I) (05-10-2022 09:35 PM)Albert Chan Wrote: lua> guess_i(36, 30000, -550, -15000) -- car lease example I = guess_i(36, 30000, -550, -15000) = guess_i(36, 15000, -550+15000*I, 0) // "set" FV=0 N = 36 P = 15000 / (550-15000*I) = 1 / (11/300 - I) → I = 11/300 - 1/P (04-09-2022 12:50 PM)Albert Chan Wrote:(10-16-2020 04:02 PM)Albert Chan Wrote: XCas> C := I*N / (1 - (1+I)^-N) // C = |N*PMT/PV|, "compounding factor" We can solve I = 2*(N-P)/(P*(N+1)) for I, but there is no need. For this formula, we had already done the work, when builiding guess_i() guess_i() I coefs: [(N^2-1)*(FV+PV)/12, (-FV*N+N*PV+FV+PV)/2 , N*PMT+FV+PV] Drop I^2 terms, solve for I, we have Dieter's formula I ≈ 2*(PV+FV + N*PMT) / (FV*(N-1) - PV*(N+1)) = 2*(30000-15000 + 36*-550) / (-15000*35 - 30000*37) ≈ 0.005872 (04-09-2022 05:47 PM)Albert Chan Wrote: \(\displaystyle I ≈ \frac{1}{P} - \frac{P}{N^2}\) I ≈ (11/300 - I) - 1/(11/300 - I) / 36^2 (2*I - 11/300)*36^2 * (I - 11/300) ≈ 1 2592*I^2 - 142.56*I + 0.7424 ≈ 0 Solve quadratics, for the small root, we have I ≈ 0.005824 Or, we can solve symbolically: XCas> ICOEFS := [n^2*pv*fv, n^2*pmt*(-pv+fv), -(n*pmt-pv-fv)*(n*pmt+pv+fv)] XCas> proot(ICOEFS(n=36, pv=30000, pmt=-550, fv=-15000)) [0.00582443202789,0.0491755679721] // keep the small root. RE: (11C) TVM for HP-11C - Albert Chan - 05-14-2022 12:26 PM (05-11-2022 01:07 PM)Albert Chan Wrote: XCas> ICOEFS := [n^2*pv*fv, n^2*pmt*(-pv+fv), -(n*pmt-pv-fv)*(n*pmt+pv+fv)] There is a weakness with I ≈ 1/P - P/N^2, extended with non-zero FV For guess_i(), to avoid solving quadratics with "√", I use pade approximation. (it is not just for speed, we simply don't want complex rate guess) [b/3/c, -2, 4c] → "small" root = 4c/(1+√(1-4b/3)) ≈ c*(b-3)/(b-1.5) Updated guess_i() coefs (there was an eariler version with (N^2-1) replaced with N^2) [(N^2-1)*(FV+PV)/12, (-FV*N+N*PV+FV+PV)/2 , N*PMT+FV+PV] Above pade approx won't work if linear term goes 0, or FV = PV*(N+1)/(N-1) With N≥1, this implied PV and FV have same sign, and FV bigger in size. For rate with unique solution, this almost never happen (*) Now, compare I ≈ 1/P - P/N^2 derived rate coefs: [PV*FV, -PMT*(PV-FV), ((PV+FV)/N+PMT)*((PV+FV)/N+PMT)] If PMT=0 or PV=FV, linear term goes 0 Even if linear term is nonzero (but small, relative to others), pade approximation may fail. Example: N=32, PV=-6000, PMT=1, FV=10000, True Rate = 0.016223 With guess_i() coefs: [341000,-254000,4032] --> roots = [0.016228, 0.728640] --> paded = 0.016227 With "1/P-P/N^2" coefs: [-60000000,16000,15876] --> roots = [-0.016134, 0.016400] --> paded = -0.488317 ? "Small" root is the wrong root. How to pick ? Apply pade on wrong root make it worse c = -0.4796125 b = -11162.8125 c*(b-3)/(b-1.5) ≈ c*b/b = c Normally, we expected c*(b-3)/(b-1.5) ≈ c*3/1.5 = 2c Example, for guess_i(), with n,pv,pmt,fv = N,P,-1,0 c = (N-P)/(P*(N+1)) b = (1-N)*c 2c matched a good rate guess formula (04-09-2022 12:50 PM)Albert Chan Wrote:(10-16-2020 04:02 PM)Albert Chan Wrote: XCas> C := I*N / (1 - (1+I)^-N) // C = |N*PMT/PV|, "compounding factor" (*) Rate is unique if 1 sign change: (PV, PMT+FV) with opposite sign. (01-06-2020 01:57 PM)Albert Chan Wrote: Some real roots for rate are meaningless, say with r ≤ -100%. |