comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/lib/financial.py @ 87:2a2c65a20a8b

Add Python libs and headers
author Chris Cannam
date Wed, 25 Feb 2015 14:05:22 +0000
parents
children
comparison
equal deleted inserted replaced
86:413a9d26189e 87:2a2c65a20a8b
1 """Some simple financial calculations
2
3 patterned after spreadsheet computations.
4
5 There is some complexity in each function
6 so that the functions behave like ufuncs with
7 broadcasting and being able to be called with scalars
8 or arrays (or other sequences).
9
10 """
11 from __future__ import division, absolute_import, print_function
12
13 import numpy as np
14
15 __all__ = ['fv', 'pmt', 'nper', 'ipmt', 'ppmt', 'pv', 'rate',
16 'irr', 'npv', 'mirr']
17
18 _when_to_num = {'end':0, 'begin':1,
19 'e':0, 'b':1,
20 0:0, 1:1,
21 'beginning':1,
22 'start':1,
23 'finish':0}
24
25 def _convert_when(when):
26 #Test to see if when has already been converted to ndarray
27 #This will happen if one function calls another, for example ppmt
28 if isinstance(when, np.ndarray):
29 return when
30 try:
31 return _when_to_num[when]
32 except (KeyError, TypeError):
33 return [_when_to_num[x] for x in when]
34
35
36 def fv(rate, nper, pmt, pv, when='end'):
37 """
38 Compute the future value.
39
40 Given:
41 * a present value, `pv`
42 * an interest `rate` compounded once per period, of which
43 there are
44 * `nper` total
45 * a (fixed) payment, `pmt`, paid either
46 * at the beginning (`when` = {'begin', 1}) or the end
47 (`when` = {'end', 0}) of each period
48
49 Return:
50 the value at the end of the `nper` periods
51
52 Parameters
53 ----------
54 rate : scalar or array_like of shape(M, )
55 Rate of interest as decimal (not per cent) per period
56 nper : scalar or array_like of shape(M, )
57 Number of compounding periods
58 pmt : scalar or array_like of shape(M, )
59 Payment
60 pv : scalar or array_like of shape(M, )
61 Present value
62 when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
63 When payments are due ('begin' (1) or 'end' (0)).
64 Defaults to {'end', 0}.
65
66 Returns
67 -------
68 out : ndarray
69 Future values. If all input is scalar, returns a scalar float. If
70 any input is array_like, returns future values for each input element.
71 If multiple inputs are array_like, they all must have the same shape.
72
73 Notes
74 -----
75 The future value is computed by solving the equation::
76
77 fv +
78 pv*(1+rate)**nper +
79 pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
80
81 or, when ``rate == 0``::
82
83 fv + pv + pmt * nper == 0
84
85 References
86 ----------
87 .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
88 Open Document Format for Office Applications (OpenDocument)v1.2,
89 Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
90 Pre-Draft 12. Organization for the Advancement of Structured Information
91 Standards (OASIS). Billerica, MA, USA. [ODT Document].
92 Available:
93 http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
94 OpenDocument-formula-20090508.odt
95
96 Examples
97 --------
98 What is the future value after 10 years of saving $100 now, with
99 an additional monthly savings of $100. Assume the interest rate is
100 5% (annually) compounded monthly?
101
102 >>> np.fv(0.05/12, 10*12, -100, -100)
103 15692.928894335748
104
105 By convention, the negative sign represents cash flow out (i.e. money not
106 available today). Thus, saving $100 a month at 5% annual interest leads
107 to $15,692.93 available to spend in 10 years.
108
109 If any input is array_like, returns an array of equal shape. Let's
110 compare different interest rates from the example above.
111
112 >>> a = np.array((0.05, 0.06, 0.07))/12
113 >>> np.fv(a, 10*12, -100, -100)
114 array([ 15692.92889434, 16569.87435405, 17509.44688102])
115
116 """
117 when = _convert_when(when)
118 (rate, nper, pmt, pv, when) = map(np.asarray, [rate, nper, pmt, pv, when])
119 temp = (1+rate)**nper
120 miter = np.broadcast(rate, nper, pmt, pv, when)
121 zer = np.zeros(miter.shape)
122 fact = np.where(rate == zer, nper + zer,
123 (1 + rate*when)*(temp - 1)/rate + zer)
124 return -(pv*temp + pmt*fact)
125
126 def pmt(rate, nper, pv, fv=0, when='end'):
127 """
128 Compute the payment against loan principal plus interest.
129
130 Given:
131 * a present value, `pv` (e.g., an amount borrowed)
132 * a future value, `fv` (e.g., 0)
133 * an interest `rate` compounded once per period, of which
134 there are
135 * `nper` total
136 * and (optional) specification of whether payment is made
137 at the beginning (`when` = {'begin', 1}) or the end
138 (`when` = {'end', 0}) of each period
139
140 Return:
141 the (fixed) periodic payment.
142
143 Parameters
144 ----------
145 rate : array_like
146 Rate of interest (per period)
147 nper : array_like
148 Number of compounding periods
149 pv : array_like
150 Present value
151 fv : array_like (optional)
152 Future value (default = 0)
153 when : {{'begin', 1}, {'end', 0}}, {string, int}
154 When payments are due ('begin' (1) or 'end' (0))
155
156 Returns
157 -------
158 out : ndarray
159 Payment against loan plus interest. If all input is scalar, returns a
160 scalar float. If any input is array_like, returns payment for each
161 input element. If multiple inputs are array_like, they all must have
162 the same shape.
163
164 Notes
165 -----
166 The payment is computed by solving the equation::
167
168 fv +
169 pv*(1 + rate)**nper +
170 pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
171
172 or, when ``rate == 0``::
173
174 fv + pv + pmt * nper == 0
175
176 for ``pmt``.
177
178 Note that computing a monthly mortgage payment is only
179 one use for this function. For example, pmt returns the
180 periodic deposit one must make to achieve a specified
181 future balance given an initial deposit, a fixed,
182 periodically compounded interest rate, and the total
183 number of periods.
184
185 References
186 ----------
187 .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
188 Open Document Format for Office Applications (OpenDocument)v1.2,
189 Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
190 Pre-Draft 12. Organization for the Advancement of Structured Information
191 Standards (OASIS). Billerica, MA, USA. [ODT Document].
192 Available:
193 http://www.oasis-open.org/committees/documents.php
194 ?wg_abbrev=office-formulaOpenDocument-formula-20090508.odt
195
196 Examples
197 --------
198 What is the monthly payment needed to pay off a $200,000 loan in 15
199 years at an annual interest rate of 7.5%?
200
201 >>> np.pmt(0.075/12, 12*15, 200000)
202 -1854.0247200054619
203
204 In order to pay-off (i.e., have a future-value of 0) the $200,000 obtained
205 today, a monthly payment of $1,854.02 would be required. Note that this
206 example illustrates usage of `fv` having a default value of 0.
207
208 """
209 when = _convert_when(when)
210 (rate, nper, pv, fv, when) = map(np.asarray, [rate, nper, pv, fv, when])
211 temp = (1+rate)**nper
212 miter = np.broadcast(rate, nper, pv, fv, when)
213 zer = np.zeros(miter.shape)
214 fact = np.where(rate == zer, nper + zer,
215 (1 + rate*when)*(temp - 1)/rate + zer)
216 return -(fv + pv*temp) / fact
217
218 def nper(rate, pmt, pv, fv=0, when='end'):
219 """
220 Compute the number of periodic payments.
221
222 Parameters
223 ----------
224 rate : array_like
225 Rate of interest (per period)
226 pmt : array_like
227 Payment
228 pv : array_like
229 Present value
230 fv : array_like, optional
231 Future value
232 when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
233 When payments are due ('begin' (1) or 'end' (0))
234
235 Notes
236 -----
237 The number of periods ``nper`` is computed by solving the equation::
238
239 fv + pv*(1+rate)**nper + pmt*(1+rate*when)/rate*((1+rate)**nper-1) = 0
240
241 but if ``rate = 0`` then::
242
243 fv + pv + pmt*nper = 0
244
245 Examples
246 --------
247 If you only had $150/month to pay towards the loan, how long would it take
248 to pay-off a loan of $8,000 at 7% annual interest?
249
250 >>> print round(np.nper(0.07/12, -150, 8000), 5)
251 64.07335
252
253 So, over 64 months would be required to pay off the loan.
254
255 The same analysis could be done with several different interest rates
256 and/or payments and/or total amounts to produce an entire table.
257
258 >>> np.nper(*(np.ogrid[0.07/12: 0.08/12: 0.01/12,
259 ... -150 : -99 : 50 ,
260 ... 8000 : 9001 : 1000]))
261 array([[[ 64.07334877, 74.06368256],
262 [ 108.07548412, 127.99022654]],
263 [[ 66.12443902, 76.87897353],
264 [ 114.70165583, 137.90124779]]])
265
266 """
267 when = _convert_when(when)
268 (rate, pmt, pv, fv, when) = map(np.asarray, [rate, pmt, pv, fv, when])
269
270 use_zero_rate = False
271 with np.errstate(divide="raise"):
272 try:
273 z = pmt*(1.0+rate*when)/rate
274 except FloatingPointError:
275 use_zero_rate = True
276
277 if use_zero_rate:
278 return (-fv + pv) / (pmt + 0.0)
279 else:
280 A = -(fv + pv)/(pmt+0.0)
281 B = np.log((-fv+z) / (pv+z))/np.log(1.0+rate)
282 miter = np.broadcast(rate, pmt, pv, fv, when)
283 zer = np.zeros(miter.shape)
284 return np.where(rate == zer, A + zer, B + zer) + 0.0
285
286 def ipmt(rate, per, nper, pv, fv=0.0, when='end'):
287 """
288 Compute the interest portion of a payment.
289
290 Parameters
291 ----------
292 rate : scalar or array_like of shape(M, )
293 Rate of interest as decimal (not per cent) per period
294 per : scalar or array_like of shape(M, )
295 Interest paid against the loan changes during the life or the loan.
296 The `per` is the payment period to calculate the interest amount.
297 nper : scalar or array_like of shape(M, )
298 Number of compounding periods
299 pv : scalar or array_like of shape(M, )
300 Present value
301 fv : scalar or array_like of shape(M, ), optional
302 Future value
303 when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
304 When payments are due ('begin' (1) or 'end' (0)).
305 Defaults to {'end', 0}.
306
307 Returns
308 -------
309 out : ndarray
310 Interest portion of payment. If all input is scalar, returns a scalar
311 float. If any input is array_like, returns interest payment for each
312 input element. If multiple inputs are array_like, they all must have
313 the same shape.
314
315 See Also
316 --------
317 ppmt, pmt, pv
318
319 Notes
320 -----
321 The total payment is made up of payment against principal plus interest.
322
323 ``pmt = ppmt + ipmt``
324
325 Examples
326 --------
327 What is the amortization schedule for a 1 year loan of $2500 at
328 8.24% interest per year compounded monthly?
329
330 >>> principal = 2500.00
331
332 The 'per' variable represents the periods of the loan. Remember that
333 financial equations start the period count at 1!
334
335 >>> per = np.arange(1*12) + 1
336 >>> ipmt = np.ipmt(0.0824/12, per, 1*12, principal)
337 >>> ppmt = np.ppmt(0.0824/12, per, 1*12, principal)
338
339 Each element of the sum of the 'ipmt' and 'ppmt' arrays should equal
340 'pmt'.
341
342 >>> pmt = np.pmt(0.0824/12, 1*12, principal)
343 >>> np.allclose(ipmt + ppmt, pmt)
344 True
345
346 >>> fmt = '{0:2d} {1:8.2f} {2:8.2f} {3:8.2f}'
347 >>> for payment in per:
348 ... index = payment - 1
349 ... principal = principal + ppmt[index]
350 ... print fmt.format(payment, ppmt[index], ipmt[index], principal)
351 1 -200.58 -17.17 2299.42
352 2 -201.96 -15.79 2097.46
353 3 -203.35 -14.40 1894.11
354 4 -204.74 -13.01 1689.37
355 5 -206.15 -11.60 1483.22
356 6 -207.56 -10.18 1275.66
357 7 -208.99 -8.76 1066.67
358 8 -210.42 -7.32 856.25
359 9 -211.87 -5.88 644.38
360 10 -213.32 -4.42 431.05
361 11 -214.79 -2.96 216.26
362 12 -216.26 -1.49 -0.00
363
364 >>> interestpd = np.sum(ipmt)
365 >>> np.round(interestpd, 2)
366 -112.98
367
368 """
369 when = _convert_when(when)
370 rate, per, nper, pv, fv, when = np.broadcast_arrays(rate, per, nper,
371 pv, fv, when)
372 total_pmt = pmt(rate, nper, pv, fv, when)
373 ipmt = _rbl(rate, per, total_pmt, pv, when)*rate
374 try:
375 ipmt = np.where(when == 1, ipmt/(1 + rate), ipmt)
376 ipmt = np.where(np.logical_and(when == 1, per == 1), 0.0, ipmt)
377 except IndexError:
378 pass
379 return ipmt
380
381 def _rbl(rate, per, pmt, pv, when):
382 """
383 This function is here to simply have a different name for the 'fv'
384 function to not interfere with the 'fv' keyword argument within the 'ipmt'
385 function. It is the 'remaining balance on loan' which might be useful as
386 it's own function, but is easily calculated with the 'fv' function.
387 """
388 return fv(rate, (per - 1), pmt, pv, when)
389
390 def ppmt(rate, per, nper, pv, fv=0.0, when='end'):
391 """
392 Compute the payment against loan principal.
393
394 Parameters
395 ----------
396 rate : array_like
397 Rate of interest (per period)
398 per : array_like, int
399 Amount paid against the loan changes. The `per` is the period of
400 interest.
401 nper : array_like
402 Number of compounding periods
403 pv : array_like
404 Present value
405 fv : array_like, optional
406 Future value
407 when : {{'begin', 1}, {'end', 0}}, {string, int}
408 When payments are due ('begin' (1) or 'end' (0))
409
410 See Also
411 --------
412 pmt, pv, ipmt
413
414 """
415 total = pmt(rate, nper, pv, fv, when)
416 return total - ipmt(rate, per, nper, pv, fv, when)
417
418 def pv(rate, nper, pmt, fv=0.0, when='end'):
419 """
420 Compute the present value.
421
422 Given:
423 * a future value, `fv`
424 * an interest `rate` compounded once per period, of which
425 there are
426 * `nper` total
427 * a (fixed) payment, `pmt`, paid either
428 * at the beginning (`when` = {'begin', 1}) or the end
429 (`when` = {'end', 0}) of each period
430
431 Return:
432 the value now
433
434 Parameters
435 ----------
436 rate : array_like
437 Rate of interest (per period)
438 nper : array_like
439 Number of compounding periods
440 pmt : array_like
441 Payment
442 fv : array_like, optional
443 Future value
444 when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
445 When payments are due ('begin' (1) or 'end' (0))
446
447 Returns
448 -------
449 out : ndarray, float
450 Present value of a series of payments or investments.
451
452 Notes
453 -----
454 The present value is computed by solving the equation::
455
456 fv +
457 pv*(1 + rate)**nper +
458 pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) = 0
459
460 or, when ``rate = 0``::
461
462 fv + pv + pmt * nper = 0
463
464 for `pv`, which is then returned.
465
466 References
467 ----------
468 .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
469 Open Document Format for Office Applications (OpenDocument)v1.2,
470 Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
471 Pre-Draft 12. Organization for the Advancement of Structured Information
472 Standards (OASIS). Billerica, MA, USA. [ODT Document].
473 Available:
474 http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
475 OpenDocument-formula-20090508.odt
476
477 Examples
478 --------
479 What is the present value (e.g., the initial investment)
480 of an investment that needs to total $15692.93
481 after 10 years of saving $100 every month? Assume the
482 interest rate is 5% (annually) compounded monthly.
483
484 >>> np.pv(0.05/12, 10*12, -100, 15692.93)
485 -100.00067131625819
486
487 By convention, the negative sign represents cash flow out
488 (i.e., money not available today). Thus, to end up with
489 $15,692.93 in 10 years saving $100 a month at 5% annual
490 interest, one's initial deposit should also be $100.
491
492 If any input is array_like, ``pv`` returns an array of equal shape.
493 Let's compare different interest rates in the example above:
494
495 >>> a = np.array((0.05, 0.04, 0.03))/12
496 >>> np.pv(a, 10*12, -100, 15692.93)
497 array([ -100.00067132, -649.26771385, -1273.78633713])
498
499 So, to end up with the same $15692.93 under the same $100 per month
500 "savings plan," for annual interest rates of 4% and 3%, one would
501 need initial investments of $649.27 and $1273.79, respectively.
502
503 """
504 when = _convert_when(when)
505 (rate, nper, pmt, fv, when) = map(np.asarray, [rate, nper, pmt, fv, when])
506 temp = (1+rate)**nper
507 miter = np.broadcast(rate, nper, pmt, fv, when)
508 zer = np.zeros(miter.shape)
509 fact = np.where(rate == zer, nper+zer, (1+rate*when)*(temp-1)/rate+zer)
510 return -(fv + pmt*fact)/temp
511
512 # Computed with Sage
513 # (y + (r + 1)^n*x + p*((r + 1)^n - 1)*(r*w + 1)/r)/(n*(r + 1)^(n - 1)*x -
514 # p*((r + 1)^n - 1)*(r*w + 1)/r^2 + n*p*(r + 1)^(n - 1)*(r*w + 1)/r +
515 # p*((r + 1)^n - 1)*w/r)
516
517 def _g_div_gp(r, n, p, x, y, w):
518 t1 = (r+1)**n
519 t2 = (r+1)**(n-1)
520 return ((y + t1*x + p*(t1 - 1)*(r*w + 1)/r) /
521 (n*t2*x - p*(t1 - 1)*(r*w + 1)/(r**2) + n*p*t2*(r*w + 1)/r +
522 p*(t1 - 1)*w/r))
523
524 # Use Newton's iteration until the change is less than 1e-6
525 # for all values or a maximum of 100 iterations is reached.
526 # Newton's rule is
527 # r_{n+1} = r_{n} - g(r_n)/g'(r_n)
528 # where
529 # g(r) is the formula
530 # g'(r) is the derivative with respect to r.
531 def rate(nper, pmt, pv, fv, when='end', guess=0.10, tol=1e-6, maxiter=100):
532 """
533 Compute the rate of interest per period.
534
535 Parameters
536 ----------
537 nper : array_like
538 Number of compounding periods
539 pmt : array_like
540 Payment
541 pv : array_like
542 Present value
543 fv : array_like
544 Future value
545 when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
546 When payments are due ('begin' (1) or 'end' (0))
547 guess : float, optional
548 Starting guess for solving the rate of interest
549 tol : float, optional
550 Required tolerance for the solution
551 maxiter : int, optional
552 Maximum iterations in finding the solution
553
554 Notes
555 -----
556 The rate of interest is computed by iteratively solving the
557 (non-linear) equation::
558
559 fv + pv*(1+rate)**nper + pmt*(1+rate*when)/rate * ((1+rate)**nper - 1) = 0
560
561 for ``rate``.
562
563 References
564 ----------
565 Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May). Open Document
566 Format for Office Applications (OpenDocument)v1.2, Part 2: Recalculated
567 Formula (OpenFormula) Format - Annotated Version, Pre-Draft 12.
568 Organization for the Advancement of Structured Information Standards
569 (OASIS). Billerica, MA, USA. [ODT Document]. Available:
570 http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
571 OpenDocument-formula-20090508.odt
572
573 """
574 when = _convert_when(when)
575 (nper, pmt, pv, fv, when) = map(np.asarray, [nper, pmt, pv, fv, when])
576 rn = guess
577 iter = 0
578 close = False
579 while (iter < maxiter) and not close:
580 rnp1 = rn - _g_div_gp(rn, nper, pmt, pv, fv, when)
581 diff = abs(rnp1-rn)
582 close = np.all(diff < tol)
583 iter += 1
584 rn = rnp1
585 if not close:
586 # Return nan's in array of the same shape as rn
587 return np.nan + rn
588 else:
589 return rn
590
591 def irr(values):
592 """
593 Return the Internal Rate of Return (IRR).
594
595 This is the "average" periodically compounded rate of return
596 that gives a net present value of 0.0; for a more complete explanation,
597 see Notes below.
598
599 Parameters
600 ----------
601 values : array_like, shape(N,)
602 Input cash flows per time period. By convention, net "deposits"
603 are negative and net "withdrawals" are positive. Thus, for
604 example, at least the first element of `values`, which represents
605 the initial investment, will typically be negative.
606
607 Returns
608 -------
609 out : float
610 Internal Rate of Return for periodic input values.
611
612 Notes
613 -----
614 The IRR is perhaps best understood through an example (illustrated
615 using np.irr in the Examples section below). Suppose one invests 100
616 units and then makes the following withdrawals at regular (fixed)
617 intervals: 39, 59, 55, 20. Assuming the ending value is 0, one's 100
618 unit investment yields 173 units; however, due to the combination of
619 compounding and the periodic withdrawals, the "average" rate of return
620 is neither simply 0.73/4 nor (1.73)^0.25-1. Rather, it is the solution
621 (for :math:`r`) of the equation:
622
623 .. math:: -100 + \\frac{39}{1+r} + \\frac{59}{(1+r)^2}
624 + \\frac{55}{(1+r)^3} + \\frac{20}{(1+r)^4} = 0
625
626 In general, for `values` :math:`= [v_0, v_1, ... v_M]`,
627 irr is the solution of the equation: [G]_
628
629 .. math:: \\sum_{t=0}^M{\\frac{v_t}{(1+irr)^{t}}} = 0
630
631 References
632 ----------
633 .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
634 Addison-Wesley, 2003, pg. 348.
635
636 Examples
637 --------
638 >>> round(irr([-100, 39, 59, 55, 20]), 5)
639 0.28095
640 >>> round(irr([-100, 0, 0, 74]), 5)
641 -0.0955
642 >>> round(irr([-100, 100, 0, -7]), 5)
643 -0.0833
644 >>> round(irr([-100, 100, 0, 7]), 5)
645 0.06206
646 >>> round(irr([-5, 10.5, 1, -8, 1]), 5)
647 0.0886
648
649 (Compare with the Example given for numpy.lib.financial.npv)
650
651 """
652 res = np.roots(values[::-1])
653 mask = (res.imag == 0) & (res.real > 0)
654 if res.size == 0:
655 return np.nan
656 res = res[mask].real
657 # NPV(rate) = 0 can have more than one solution so we return
658 # only the solution closest to zero.
659 rate = 1.0/res - 1
660 rate = rate.item(np.argmin(np.abs(rate)))
661 return rate
662
663 def npv(rate, values):
664 """
665 Returns the NPV (Net Present Value) of a cash flow series.
666
667 Parameters
668 ----------
669 rate : scalar
670 The discount rate.
671 values : array_like, shape(M, )
672 The values of the time series of cash flows. The (fixed) time
673 interval between cash flow "events" must be the same as that for
674 which `rate` is given (i.e., if `rate` is per year, then precisely
675 a year is understood to elapse between each cash flow event). By
676 convention, investments or "deposits" are negative, income or
677 "withdrawals" are positive; `values` must begin with the initial
678 investment, thus `values[0]` will typically be negative.
679
680 Returns
681 -------
682 out : float
683 The NPV of the input cash flow series `values` at the discount
684 `rate`.
685
686 Notes
687 -----
688 Returns the result of: [G]_
689
690 .. math :: \\sum_{t=0}^{M-1}{\\frac{values_t}{(1+rate)^{t}}}
691
692 References
693 ----------
694 .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
695 Addison-Wesley, 2003, pg. 346.
696
697 Examples
698 --------
699 >>> np.npv(0.281,[-100, 39, 59, 55, 20])
700 -0.0084785916384548798
701
702 (Compare with the Example given for numpy.lib.financial.irr)
703
704 """
705 values = np.asarray(values)
706 return (values / (1+rate)**np.arange(0, len(values))).sum(axis=0)
707
708 def mirr(values, finance_rate, reinvest_rate):
709 """
710 Modified internal rate of return.
711
712 Parameters
713 ----------
714 values : array_like
715 Cash flows (must contain at least one positive and one negative
716 value) or nan is returned. The first value is considered a sunk
717 cost at time zero.
718 finance_rate : scalar
719 Interest rate paid on the cash flows
720 reinvest_rate : scalar
721 Interest rate received on the cash flows upon reinvestment
722
723 Returns
724 -------
725 out : float
726 Modified internal rate of return
727
728 """
729 values = np.asarray(values, dtype=np.double)
730 n = values.size
731 pos = values > 0
732 neg = values < 0
733 if not (pos.any() and neg.any()):
734 return np.nan
735 numer = np.abs(npv(reinvest_rate, values*pos))
736 denom = np.abs(npv(finance_rate, values*neg))
737 return (numer/denom)**(1.0/(n - 1))*(1 + reinvest_rate) - 1