TVM solve for interest rate, revisited
|
05-17-2022, 01:31 PM
(This post was last modified: 06-11-2022 08:14 PM by Albert Chan.)
Post: #6
|
|||
|
|||
RE: TVM solve for interest rate, revisited
Instead of cheap tricks to get good rate guess, why not start from the edge, and iterate with Halley's method ?
For NPMT=0 with 2 rate solutions, this picked the "smaller" edge. Note: NaN edge moved up front, for rate search early termination. Code: function edge_i(n,pv,pmt,fv) We solve NPMT=0, with PV=0, for rate x x = loan_rate(n, pv, pmt, fv) = loan_rate(n, 0, pv*x+pmt, pv+fv) f = (pv+fv)/n * g + pv * x + pmt = 0 // same formula used for Plus42 g = n*x / ((1+x)^n-1) g'/g = -(g-1+(n-1)*x) / (x+x^2) = -num / den g''/g = (g+n*x)*(2*(g-1)+(n-1)*x) / (x+x^2)^2 = (num+x+1)*(num+(g-1)) / den^2 Let k = (pv+fv)/n * g f = k + pv*x + pmt f' = k*(g'/g) + pv f'' = k*(g''/g) Using first derivative to get to second, Halley's correction is cheap. To make code more robust, we special cased with limits when rate goes 0 Code: function loan_rate2(n, pv, pmt, fv, i) Previous post example: lua> n, pv, pmt, fv = 10, 50, -30, 100 lua> g = loan_rate2(n,pv,pmt,fv) lua> g() -0.2844446981069045 0.015555301893095532 lua> g() -0.28443599888025756 8.699226646944535e-006 lua> g() -0.28443599888025595 1.6279605736411871e-015 Fun Math Algorithms, car lease APR example. lua> n, pv, pmt, fv = 36, 30000, -550, -15000 lua> edge_i(n,pv,pmt,fv) -- Note: 2nd edge can be removed 0.018333333333333333 0.03666666666666667 lua> lua> g = loan_rate2(n,pv,pmt,fv) lua> g() 0.005817405851432355 -0.012515927481900979 lua> g() 0.005805072819430545 -1.2333032001809594e-005 lua> g() 0.0058050728194201295 -1.0415537616188019e-014 Note sign of errors. Iteration does not over-shoot to the other side. Next iteration guaranteed better estimate (cubic convergence) Bonus: with one-sided convergence pattern, we can detect for no solution. If error sign changes is not due to simple rounding errors, no solution. lua> g = loan_rate2(10,50,-10,100) lua> g() 0.3175682256333693 0.4175682256333693 lua> g() -0.0740994732881643 -0.3916676989215336 --> no solution |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 1 Guest(s)