Skip to content

Commit

Permalink
Merge pull request #11 from tarioch/bugfix/flip_case
Browse files Browse the repository at this point in the history
correct left border for brentq algorithm needs to be less than -1, fi…
  • Loading branch information
tarioch authored Jul 29, 2020
2 parents b3d9294 + 217ff4a commit 32f9ef6
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 5 deletions.
9 changes: 5 additions & 4 deletions src/xirr/math.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import scipy.optimize


DAYS_PER_YEAR = 365.0

#
Expand Down Expand Up @@ -35,21 +36,21 @@ def xirr(valuesPerDate):
>>> from datetime import date
>>> valuesPerDate = {date(2019, 12, 31): -80005.8, date(2020, 3, 12): 65209.6}
>>> xirr(valuesPerDate)
-0.6453638827247169
-0.645363882724717
'''
if not valuesPerDate or len(valuesPerDate) < 2:
return None

if(all(v >= 0 for v in valuesPerDate.values())):
if all(v >= 0 for v in valuesPerDate.values()):
return -float("inf")
if(all(v <= 0 for v in valuesPerDate.values())):
if all(v <= 0 for v in valuesPerDate.values()):
return float("inf")

result = None
try:
result = scipy.optimize.newton(lambda r: xnpv(valuesPerDate, r), 0)
except (RuntimeError, OverflowError): # Failed to converge?
result = scipy.optimize.brentq(lambda r: xnpv(valuesPerDate, r), -1.0, 1e20)
result = scipy.optimize.brentq(lambda r: xnpv(valuesPerDate, r), -0.999999999999999, 1e20)

if not isinstance(result, complex):
return result
Expand Down
5 changes: 4 additions & 1 deletion tests/test_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
({'2017-12-16': -2236.3994659663, '2017-12-26': -47.3417585212, '2017-12-29': -46.52619316339632, '2017-12-31': 10424.74612565936, '2017-12-20': -13.077972551952}, 1.2238535289956518e+16),
({'2018-05-09': -200, '2018-06-09': 30, '2018-11-09': 50, '2018-12-09': 20}, -0.8037),
({'2011-01-01': -1, '2011-01-02': 0, '2012-01-01': -1}, float("inf")),
({'2011-01-01': 1, '2011-01-02': 0, '2012-01-01': 1}, -float("inf"))
({'2011-01-01': 1, '2011-01-02': 0, '2012-01-01': 1}, -float("inf")),
({'2011-07-01': -10000, '2014-07-01': 1}, -0.9535),
({'2011-07-01': 10000, '2014-07-01': -1}, -0.9535),
])
def test_xirr(valuesPerDateString, expected):
valuesPerDate = {datetime.fromisoformat(k).date(): v for k, v in valuesPerDateString.items()}
Expand All @@ -37,6 +39,7 @@ def test_xirr(valuesPerDateString, expected):
({'2019-12-31': -100, '2020-03-05': 100}, None),
({'2019-12-31': -100, '2020-03-05': 1000}, None),
({'2018-05-09': -200, '2018-06-09': 30, '2018-11-09': 50, '2018-12-09': 20}, -0.8037),
({'2011-01-01': 1, '2011-01-02': 0, '2012-01-01': 1}, None),
])
def test_cleanXirr(valuesPerDateString, expected):
valuesPerDate = {datetime.fromisoformat(k).date(): v for k, v in valuesPerDateString.items()}
Expand Down

0 comments on commit 32f9ef6

Please sign in to comment.