diff --git a/numpy_financial/_financial.py b/numpy_financial/_financial.py index 1adbbea..6ae42cd 100644 --- a/numpy_financial/_financial.py +++ b/numpy_financial/_financial.py @@ -1153,8 +1153,8 @@ def irr(values, *, raise_exceptions=False, selection_logic=_irr_default_selectio g = np.roots(row) eirr = np.real(g[np.isreal(g)]) - 1 - # Realistic IRR - eirr = eirr[eirr >= -1] + # The discount factor must be nonzero in the NPV equation. + eirr = eirr[eirr > -1] # If no real solution if len(eirr) == 0: diff --git a/numpy_financial/tests/test_financial.py b/numpy_financial/tests/test_financial.py index 765e1b2..9a2a0a0 100644 --- a/numpy_financial/tests/test_financial.py +++ b/numpy_financial/tests/test_financial.py @@ -796,6 +796,18 @@ def test_numpy_gh_6744(self, v): # Test that if there is no solution then npf.irr returns nan. assert numpy.isnan(npf.irr(v)) + @pytest.mark.parametrize("cashflows", [ + [100, 50, 0], [-100, -50, 0], [0, 100, 0], [0, -100, 0], + ]) + def test_zero_polynomial_root_is_not_an_irr(self, cashflows): + assert numpy.isnan(npf.irr(cashflows)) + with pytest.raises(npf.NoRealSolutionError): + npf.irr(cashflows, raise_exceptions=True) + + def test_trailing_zeros_preserve_negative_irr(self): + assert_allclose(npf.irr([-100, 50, 0, 0]), -0.5) + assert_allclose(npf.irr([[-100, 50, 0], [-100, 150, 0]]), [-0.5, 0.5]) + def test_gh_15(self): v = [ -3000.0,