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