15
15
from decimal import Decimal
16
16
17
17
import numpy as np
18
+ from numpy .core .overrides import array_function_dispatch
19
+
18
20
19
21
__all__ = ['fv' , 'pmt' , 'nper' , 'ipmt' , 'ppmt' , 'pv' , 'rate' ,
20
22
'irr' , 'npv' , 'mirr' ]
@@ -36,6 +38,12 @@ def _convert_when(when):
36
38
except (KeyError , TypeError ):
37
39
return [_when_to_num [x ] for x in when ]
38
40
41
+
42
+ def _fv_dispatcher (rate , nper , pmt , pv , when = None ):
43
+ return (rate , nper , pmt , pv )
44
+
45
+
46
+ @array_function_dispatch (_fv_dispatcher )
39
47
def fv (rate , nper , pmt , pv , when = 'end' ):
40
48
"""
41
49
Compute the future value.
@@ -124,6 +132,12 @@ def fv(rate, nper, pmt, pv, when='end'):
124
132
(1 + rate * when )* (temp - 1 )/ rate )
125
133
return - (pv * temp + pmt * fact )
126
134
135
+
136
+ def _pmt_dispatcher (rate , nper , pv , fv = None , when = None ):
137
+ return (rate , nper , pv , fv )
138
+
139
+
140
+ @array_function_dispatch (_pmt_dispatcher )
127
141
def pmt (rate , nper , pv , fv = 0 , when = 'end' ):
128
142
"""
129
143
Compute the payment against loan principal plus interest.
@@ -216,6 +230,12 @@ def pmt(rate, nper, pv, fv=0, when='end'):
216
230
(1 + masked_rate * when )* (temp - 1 )/ masked_rate )
217
231
return - (fv + pv * temp ) / fact
218
232
233
+
234
+ def _nper_dispatcher (rate , pmt , pv , fv = None , when = None ):
235
+ return (rate , pmt , pv , fv )
236
+
237
+
238
+ @array_function_dispatch (_nper_dispatcher )
219
239
def nper (rate , pmt , pv , fv = 0 , when = 'end' ):
220
240
"""
221
241
Compute the number of periodic payments.
@@ -284,6 +304,12 @@ def nper(rate, pmt, pv, fv=0, when='end'):
284
304
B = np .log ((- fv + z ) / (pv + z ))/ np .log (1 + rate )
285
305
return np .where (rate == 0 , A , B )
286
306
307
+
308
+ def _ipmt_dispatcher (rate , per , nper , pv , fv = None , when = None ):
309
+ return (rate , per , nper , pv , fv )
310
+
311
+
312
+ @array_function_dispatch (_ipmt_dispatcher )
287
313
def ipmt (rate , per , nper , pv , fv = 0 , when = 'end' ):
288
314
"""
289
315
Compute the interest portion of a payment.
@@ -379,6 +405,7 @@ def ipmt(rate, per, nper, pv, fv=0, when='end'):
379
405
pass
380
406
return ipmt
381
407
408
+
382
409
def _rbl (rate , per , pmt , pv , when ):
383
410
"""
384
411
This function is here to simply have a different name for the 'fv'
@@ -388,6 +415,12 @@ def _rbl(rate, per, pmt, pv, when):
388
415
"""
389
416
return fv (rate , (per - 1 ), pmt , pv , when )
390
417
418
+
419
+ def _ppmt_dispatcher (rate , per , nper , pv , fv = None , when = None ):
420
+ return (rate , per , nper , pv , fv )
421
+
422
+
423
+ @array_function_dispatch (_ppmt_dispatcher )
391
424
def ppmt (rate , per , nper , pv , fv = 0 , when = 'end' ):
392
425
"""
393
426
Compute the payment against loan principal.
@@ -416,6 +449,12 @@ def ppmt(rate, per, nper, pv, fv=0, when='end'):
416
449
total = pmt (rate , nper , pv , fv , when )
417
450
return total - ipmt (rate , per , nper , pv , fv , when )
418
451
452
+
453
+ def _pv_dispatcher (rate , nper , pmt , fv = None , when = None ):
454
+ return (rate , nper , nper , pv , fv )
455
+
456
+
457
+ @array_function_dispatch (_pv_dispatcher )
419
458
def pv (rate , nper , pmt , fv = 0 , when = 'end' ):
420
459
"""
421
460
Compute the present value.
@@ -520,13 +559,20 @@ def _g_div_gp(r, n, p, x, y, w):
520
559
(n * t2 * x - p * (t1 - 1 )* (r * w + 1 )/ (r ** 2 ) + n * p * t2 * (r * w + 1 )/ r +
521
560
p * (t1 - 1 )* w / r ))
522
561
562
+
563
+ def _rate_dispatcher (nper , pmt , pv , fv , when = None , guess = None , tol = None ,
564
+ maxiter = None ):
565
+ return (nper , pmt , pv , fv )
566
+
567
+
523
568
# Use Newton's iteration until the change is less than 1e-6
524
569
# for all values or a maximum of 100 iterations is reached.
525
570
# Newton's rule is
526
571
# r_{n+1} = r_{n} - g(r_n)/g'(r_n)
527
572
# where
528
573
# g(r) is the formula
529
574
# g'(r) is the derivative with respect to r.
575
+ @array_function_dispatch (_rate_dispatcher )
530
576
def rate (nper , pmt , pv , fv , when = 'end' , guess = None , tol = None , maxiter = 100 ):
531
577
"""
532
578<
1241
/code>
Compute the rate of interest per period.
@@ -598,6 +644,12 @@ def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100):
598
644
else :
599
645
return rn
600
646
647
+
648
+ def _irr_dispatcher (values ):
649
+ return (values ,)
650
+
651
+
652
+ @array_function_dispatch (_irr_dispatcher )
601
653
def irr (values ):
602
654
"""
603
655
Return the Internal Rate of Return (IRR).
@@ -677,6 +729,12 @@ def irr(values):
677
729
rate = rate .item (np .argmin (np .abs (rate )))
678
730
return rate
679
731
732
+
733
+ def _npv_dispatcher (rate , values ):
734
+ return (values ,)
735
+
736
+
737
+ @array_function_dispatch (_npv_dispatcher )
680
738
def npv (rate , values ):
681
739
"""
682
740
Returns the NPV (Net Present Value) of a cash flow series.
@@ -722,6 +780,12 @@ def npv(rate, values):
722
780
values = np .asarray (values )
723
781
return (values / (1 + rate )** np .arange (0 , len (values ))).sum (axis = 0 )
724
782
783
+
784
+ def _mirr_dispatcher (values , finance_rate , reinvest_rate ):
785
+ return (values ,)
786
+
787
+
788
+ @array_function_dispatch (_mirr_dispatcher )
725
789
def mirr (values , finance_rate , reinvest_rate ):
726
790
"""
727
791
Modified internal rate of return.
0 commit comments