2

I am running into a roadblock and would appreciate some help on this.

Problem Statement:

I am trying to calculate XIRR for a cash flow over 30 years in Python.

What have I tried so far:

However, none of the established libraries(like numpy and pandas) seem to have support for this. After doing some research, I learned through this source (https://vindeep.com/Corporate/XIRRCalculation.aspx) that with some simple manipulation, XIRR can be calculated from IRR.

So, all I need is an IRR function that is implemented well. The functionality used to exist in numpy but has moved to this other package (https://github.com/numpy/numpy-financial). While, this package works, it is very very slow. Here is a small test:

import pandas as pd
import numpy as np
import numpy_financial as npf
from time import time


# Generate some example data
t = pd.date_range('2022-01-01', '2037-01-01', freq='D')

cash_flows = np.random.randint(10000, size=len(t)-1)
cash_flows = np.insert(cash_flows, 0, -10000)

# Calculate IRR
start_timer = time()
npf.irr(cash_flows, guess)
stop_timer = time()
print(f"""Time taken to calculate IRR over 30 years of daily data: {round((stop_timer-start_timer)/60, 2)}""")

One other alternative seems to be https://github.com/better/irr - however, this has an edge case bug that has not been addressed in over 4 years.

Can anyone kindly offer to a more stable implementation. It feels like such simple and very commonly used functionality and the lack of a good stable implementation surprises me. Can someone point to any good resources.

Thanks

Uday

UGuntupalli
  • 769
  • 1
  • 9
  • 22
  • If the irr is to be used by engineers are they going to use it to analyse real, non financial, projects? An irr across 10000 periods (30 years by day) involves solving a polynomial of order 10000. Does anybody really expect to know what day cash will be received / spent next year let alone in 2050? Explore, with the customer, working with quarterly/annual assumptions which will make the calculation much easier and still be more precise than the assumptions which drive it. Monthly assumptions ( 360 periods ) will probably be practical too. – Tls Chris Jun 18 '21 at 13:55
  • @TlsChris, Currently xirr functionality is not offered in any of the standard packages that I researched. If it is, then I would happily use it. The projects I am dealing with are real financial projects with long life times. The cash flows are on quarterly basis, but since Xirr function is not available I went through the reference provided in the original question to use IRR instead with irregular cash flows. – UGuntupalli Jun 20 '21 at 13:48
  • What is guess in npf.irr(cash_flows, guess)? npf.irr only accepts a single parameter according to this https://github.com/numpy/numpy-financial/blob/master/numpy_financial/_financial.py. Did you modify the original function? – VRComp Jun 20 '21 at 17:19

4 Answers4

7

pyxirr creator here. The library has been used in a financial project for over a year, but I only recently found the time to publish it. We had the task of quickly calculating XIRR for various portfolios and existing implementations quickly became a bottleneck. pyxirr also mimics some numpy-financial functions and works much faster.

The XIRR implementation in Excel is not always correct. In edge cases the algorithm does not converge and shows incorrect result instead of error or NA. The result can be checked with the xnpv function: xnpv(xirr_rate, dates, values) and should be close to zero. Similarly, you can check irr using the npv function: npv(irr_rate, values), but note the difference in npv calculation between Excel and numpy-financial.

Alexander Volkovsky
  • 2,588
  • 7
  • 13
6

Try using pyxirr package. Implemented in Rust, it is blazing fast. For 30 years time period it took about .001 sec.

igrinis
  • 12,398
  • 20
  • 45
0

Taking a look at the implementation on their GitHub, it is pretty evident to me that the npf.irr() function is implemented pretty well. Your alternative seems to be to implement the function yourself using NumPy operations but I am doubtful that a) that is easy to accomplish or b) possible to accomplish in pure Python.

NumPy Financial seems to be doing their implementation using eigenvalues which means they are performing complex mathematic operations. Perhaps, if you are not bounded to Python, consider Microsoft's C# implementation of IRR and see if that works faster. I suspect that they are using regression to calculate the IRR. Therefore, based on your guess, it may indeed be quicker than NumPy Financial.

Your final alternative is to continue with what you have at the moment and just run on a more powerful machine. On my machine, this operation took about 71 seconds and it is does not even have a GPU. I am sure more powerful computers, with parallelization, should be able to compute this much much faster than that.

Mahyar Mirrashed
  • 471
  • 1
  • 3
  • 14
  • Thank you for the suggestion Mahyar. I am unfortunately bound to Python. While I can personally get a more powerful machine, I am developing code for a team of engineers, so upgrading everyone's laptops may not be an option. – UGuntupalli Jun 18 '21 at 13:08
0

Look at the answer I provided here: https://stackoverflow.com/a/66069439/4045275.

I didn't benchmark it against pyxirr

Pythonista anonymous
  • 8,140
  • 20
  • 70
  • 112