python-3.xpandasdataframeirr

How to calculate IRR for each investment in a dataframe?


If I've created a scrubbed Pandas dataframe containing investments, dates and cash flows, anyone have tips for calculating the IRR for each investment according to the cash flows in the dataframe? I've been trying PYXIRR, however this isn't a requirement if anyone has any better ideas.

EX:

Investments Date Cash Flow
Investment A 1/1/2000 -100
Investment A 12/31/2020 +100
Investment A 12/31/2021 +100
Investment B 5/31/2005 -500
Investment B 12/31/2021 +600
Investment C 3/6/2010 -100
Investment C 12/31/2011 -100
Investment C 12/31/2012 -50
Investment C 12/31/2021 +300

to output of:

Investments IRR
Investment A 50%
Investment B 6%
Investment C 10%

I was able to calculate the IRR for all the cash flows as a singular return stream, but not with the grouped buckets. Trying to use groupby gives me an unhashable dataframe error message.

Many thanks in advance


Solution

  • pyxirr is a quite nice package to achieve this.

    You can use df.groupby.apply() to calculate the xirr per grouped investment.

    df = pd.DataFrame(dict(investment=['A', 'B', 'A', 'B', 'A'],
                           dates=pd.to_datetime(['2022-10-31', '2023-01-31',
                                                 '2023-03-31', '2023-05-31',
                                                 '2023-08-31']),
                           amount=[-100, -1000, 80, 1200, 30]
                           )
                      )
    
      investment      dates  amount
    0          A 2022-10-31    -100
    1          B 2023-01-31   -1000
    2          A 2023-03-31      80
    3          B 2023-05-31    1200
    4          A 2023-08-31      30
    
    

    You first group by investments, and then calculate the xirr per grouped DataFrame, e.g. using a lambda function:

    xirr = df.groupby('investment').apply(lambda x: pyxirr.xirr(x['dates'],
                                                                x['amount'])
                                         )
    investment
    A    0.199111
    B    0.741177
    

    Note that this calculates the xirr, which takes date of the cashflow into account. If you want the normal IRR, use the same approach but pyxirr.irr(x['amount'])