Anexen / pyxirr

Rust-powered collection of financial functions.
https://anexen.github.io/pyxirr/
The Unlicense
167 stars 14 forks source link

Control Xirr accuracy #57

Open rogerleung opened 1 month ago

rogerleung commented 1 month ago

Hi Sir,

Is there a way i can set a parameter on how many trials i wanna run? I run some cashflows and cross check with excel numbers and there are some ~<1% differences which i believe it's owing to number of trials. / tolerence

Best, Roger

Anexen commented 4 weeks ago

Hello, @rogerleung

This is not possible at the moment because PyXIRR uses several optimization algorithms to find a solution and each algorithm requires its own configuration.

In general, PyXIRR has stricter accuracy requirements than Excel. You can compare XIRR using XNPV function and check which one is closer to zero: XNPV(XIRR(cf), cf) = 0

rogerleung commented 3 weeks ago

Hi Anexen.

Here is one example I would like to give. As you can see the excel is correctly giving a -59% IRR (by starting with initial guess of -.1) however, if i run it on the package it gives me 230.80406113058913%

image

image

[RandomCashflow.xlsx](https://github.com/user-attachments/files/16685276/RandomCashflow.xlsx)

I am not sure if that's possible to allow user to make an initial guess. For example for projects with overall cashflow that's negative. It's more likely the IRR being negative

Happy to provide more context and thanks for the great work again.

Best, Roger

Anexen commented 3 weeks ago

Thank you for providing the data.

This is a complicated case. Just checked GoogleSheets and LibreOffice, they are both return 230.80406 (or 23080%).

I agree that -59% seems to be a more accurate rate. I also agree that the rate is more likely to be negative when the overall cashflow is negative. However, the difficult question is "by how much"? In this case, the initial guess of -0.1 isn't sufficient. LibreOffice/GoogleSheets/PyXIRR return -59% when initial guess is approximately -0.4.

pyxirr.xirr(cashflow["Date"], cashflow["Cashflow"], guess=-0.4)

You may also find the Multiple IRR Problem section in the README useful.

rogerleung commented 3 weeks ago

Hello -

I have designed a way to guess the better IRR to use (especially for the negative ones) Wanna run you through and see what do you think. It works quite well on my side (on 800+ real Private Equity Deals).


import pyxirr
import pandas as pd
def xirr_optimised(cf_date, amounts):
    loop = [-.1,-.2,-.3,-.4,-.5,-.6,-.7,-.8,-.9]
    res = set()
    result = {}

    try:
      if sum(amounts) > 0:
        return pyxirr.xirr(cf_date, amounts, guess = .1)

      for i in loop:
        temp = pyxirr.xirr(cf_date, amounts, guess = i)
        if temp < 0:
            res.add(temp)

      for i in res:
        result[i] = abs(amounts[0] + pyxirr.xnpv(i, pd.DataFrame({"cf_date": cf_date[1:], "amounts": amounts[1:]})))

      return min(result, key = result.get)
    except:
      return 'NaN'