@@ -948,12 +948,12 @@ def mirr(values, finance_rate, reinvest_rate, *, raise_exceptions=False):
948
948
949
949
Parameters
950
950
----------
951
- values : array_like
951
+ values : array_like, 1D or 2D
952
952
Cash flows, where the first value is considered a sunk cost at time zero.
953
953
It must contain at least one positive and one negative value.
954
- finance_rate : scalar
954
+ finance_rate : scalar or 1D array
955
955
Interest rate paid on the cash flows.
956
- reinvest_rate : scalar
956
+ reinvest_rate : scalar or D array
957
957
Interest rate received on the cash flows upon reinvestment.
958
958
raise_exceptions: bool, optional
959
959
Flag to raise an exception when the MIRR cannot be computed due to
@@ -962,7 +962,7 @@ def mirr(values, finance_rate, reinvest_rate, *, raise_exceptions=False):
962
962
963
963
Returns
964
964
-------
965
- out : float
965
+ out : float or 2D array
966
966
Modified internal rate of return
967
967
968
968
Notes
@@ -992,6 +992,22 @@ def mirr(values, finance_rate, reinvest_rate, *, raise_exceptions=False):
992
992
>>> npf.mirr([-100, 50, -60, 70], 0.10, 0.12)
993
993
-0.03909366594356467
994
994
995
+ It is also possible to supply multiple cashflows or pairs of
996
+ finance and reinvstment rates, note that in this case the number of elements
997
+ in each of the rates arrays must match.
998
+
999
+ >>> values = [
1000
+ ... [-4500, -800, 800, 800, 600],
1001
+ ... [-120000, 39000, 30000, 21000, 37000],
1002
+ ... [100, 200, -50, 300, -200],
1003
+ ... ]
1004
+ >>> finance_rate = [0.05, 0.08, 0.10]
1005
+ >>> reinvestment_rate = [0.08, 0.10, 0.12]
1006
+ >>> npf.mirr(values, finance_rate, reinvestment_rate)
1007
+ array([[-0.1784449 , -0.17328716, -0.1684366 ],
1008
+ [ 0.04627293, 0.05437856, 0.06252201],
1009
+ [ 0.35712458, 0.40628857, 0.44435295]])
1010
+
995
1011
Now, let's consider the scenario where all cash flows are negative.
996
1012
997
1013
>>> npf.mirr([-100, -50, -60, -70], 0.10, 0.12)
@@ -1010,22 +1026,31 @@ def mirr(values, finance_rate, reinvest_rate, *, raise_exceptions=False):
1010
1026
numpy_financial._financial.NoRealSolutionError:
1011
1027
No real solution exists for MIRR since all cashflows are of the same sign.
1012
1028
"""
1013
- values = np .asarray (values )
1014
- n = values .size
1015
-
1016
- # Without this explicit cast the 1/(n - 1) computation below
1017
- # becomes a float, which causes TypeError when using Decimal
1018
- # values.
1019
- if isinstance (finance_rate , Decimal ):
1020
- n = Decimal (n )
1021
-
1022
- pos = values > 0
1023
- neg = values < 0
1024
- if not (pos .any () and neg .any ()):
1029
+ values_inner = np .atleast_2d (values ).astype (np .float64 )
1030
+ finance_rate_inner = np .atleast_1d (finance_rate ).astype (np .float64 )
1031
+ reinvest_rate_inner = np .atleast_1d (reinvest_rate ).astype (np .float64 )
1032
+ n = values_inner .shape [1 ]
1033
+
1034
+ if finance_rate_inner .size != reinvest_rate_inner .size :
1025
1035
if raise_exceptions :
1026
- raise NoRealSolutionError ('No real solution exists for MIRR since'
1027
- ' all cashflows are of the same sign.' )
1036
+ raise ValueError ("finance_rate and reinvest_rate must have the same size" )
1028
1037
return np .nan
1029
- numer = np .abs (npv (reinvest_rate , values * pos ))
1030
- denom = np .abs (npv (finance_rate , values * neg ))
1031
- return (numer / denom ) ** (1 / (n - 1 )) * (1 + reinvest_rate ) - 1
1038
+
1039
+ out_shape = _get_output_array_shape (values_inner , finance_rate_inner )
1040
+ out = np .empty (out_shape )
1041
+
1042
+ for i , v in enumerate (values_inner ):
1043
+ for j , (rr , fr ) in enumerate (zip (reinvest_rate_inner , finance_rate_inner )):
1044
+ pos = v > 0
1045
+ neg = v < 0
1046
+
1047
+ if not (pos .any () and neg .any ()):
1048
+ if raise_exceptions :
1049
+ raise NoRealSolutionError ("No real solution exists for MIRR since"
1050
+ " all cashflows are of the same sign." )
1051
+ out [i , j ] = np .nan
1052
+ else :
1053
+ numer = np .abs (npv (rr , v * pos ))
1054
+ denom = np .abs (npv (fr , v * neg ))
1055
+ out [i , j ] = (numer / denom ) ** (1 / (n - 1 )) * (1 + rr ) - 1
1056
+ return _ufunc_like (out )
0 commit comments