Python IRR 函数给出的结果不同于 Excel XIRR
Python IRR Function giving different result than Excel XIRR
我正在使用以下函数通过 Python 执行 IRR 计算:
from scipy.optimize import newton
def xnpv(rate, values, dates):
if rate <= -1.0:
return float('inf')
min_date = min(dates)
return sum([
value / (1 + rate)**((date - min_date).days / 365)
for value, date
in zip(values, dates)
])
def xirr(values, dates):
return newton(lambda r: xnpv(r, values, dates), 0)
函数来源:https://2018.pycon.co/talks/personal-pynance/personal-pynance.pdf
几个月来,此函数与各种不同的现金流量和日期完美配合,我得到了与 Excel 的 XIRR 函数相同的结果。但是,突然使用下面的现金流量和日期列表它停止工作,我得到的结果与 Excel 的 IRR 公式(这是正确的和预期的)不同:
import pandas as pd
import datetime
import numpy as np
from decimal import *
# Input Data
dates = [datetime.date(2020, 8, 31), datetime.date(2020, 5, 5), datetime.date(2020, 2, 28), datetime.date(2020, 8, 31),datetime.date(2018, 6, 30)]
values = [50289.0, -75000.0, 0.0, 0.0, 0.0]
# Create Dataframe from Input Data
test = pd.DataFrame({"dates" : dates, "values" : values})
# Filter all rows with 0 cashflows
test = test[test['values'] != 0]
# Sort dataframe by date
test = test.sort_values('dates', ascending=True)
test['values'] = test['values'].astype('float')
# Create separate lists for values and dates
test_values = list(test['values'])
test_dates = list(test['dates'])
# Calculate IRR
xirr(test_values, test_dates)
我在 Python 中得到的结果是 0.0001 而在 Excel 中我得到 -0.71 并且我不知道我在这里缺少什么。也许有人有想法?!??!
Scipy 优化函数容易陷入局部极小值。将优化方法更改为不同的方法,例如anderson
,得到你想要的。
证明
from scipy.optimize import anderson
def xnpv(rate, values, dates):
if rate <= -1.0:
return float('inf')
min_date = min(dates)
return sum([
value / (1 + rate)**((date - min_date).days / 365)
for value, date
in zip(values, dates)
])
def xirr(values, dates):
return anderson(lambda r: xnpv(r, values, dates), 0)
import datetime
from decimal import *
# Input Data
dates = [datetime.date(2020, 8, 31), datetime.date(2020, 5, 5), datetime.date(2020, 2, 28), datetime.date(2020, 8, 31),datetime.date(2018, 6, 30)]
values = [50289.0, -75000.0, 0.0, 0.0, 0.0]
# Create Dataframe from Input Data
test = pd.DataFrame({"dates" : dates, "values" : values})
# Filter all rows with 0 cashflows
test = test[test['values'] != 0]
# Sort dataframe by date
test = test.sort_values('dates', ascending=True)
test['values'] = test['values'].astype('float')
# Create separate lists for values and dates
test_values = list(test['values'])
test_dates = list(test['dates'])
# Calculate IRR
xirr(test_values, test_dates)
array(-0.70956212)
我正在使用以下函数通过 Python 执行 IRR 计算:
from scipy.optimize import newton
def xnpv(rate, values, dates):
if rate <= -1.0:
return float('inf')
min_date = min(dates)
return sum([
value / (1 + rate)**((date - min_date).days / 365)
for value, date
in zip(values, dates)
])
def xirr(values, dates):
return newton(lambda r: xnpv(r, values, dates), 0)
函数来源:https://2018.pycon.co/talks/personal-pynance/personal-pynance.pdf
几个月来,此函数与各种不同的现金流量和日期完美配合,我得到了与 Excel 的 XIRR 函数相同的结果。但是,突然使用下面的现金流量和日期列表它停止工作,我得到的结果与 Excel 的 IRR 公式(这是正确的和预期的)不同:
import pandas as pd
import datetime
import numpy as np
from decimal import *
# Input Data
dates = [datetime.date(2020, 8, 31), datetime.date(2020, 5, 5), datetime.date(2020, 2, 28), datetime.date(2020, 8, 31),datetime.date(2018, 6, 30)]
values = [50289.0, -75000.0, 0.0, 0.0, 0.0]
# Create Dataframe from Input Data
test = pd.DataFrame({"dates" : dates, "values" : values})
# Filter all rows with 0 cashflows
test = test[test['values'] != 0]
# Sort dataframe by date
test = test.sort_values('dates', ascending=True)
test['values'] = test['values'].astype('float')
# Create separate lists for values and dates
test_values = list(test['values'])
test_dates = list(test['dates'])
# Calculate IRR
xirr(test_values, test_dates)
我在 Python 中得到的结果是 0.0001 而在 Excel 中我得到 -0.71 并且我不知道我在这里缺少什么。也许有人有想法?!??!
Scipy 优化函数容易陷入局部极小值。将优化方法更改为不同的方法,例如anderson
,得到你想要的。
证明
from scipy.optimize import anderson
def xnpv(rate, values, dates):
if rate <= -1.0:
return float('inf')
min_date = min(dates)
return sum([
value / (1 + rate)**((date - min_date).days / 365)
for value, date
in zip(values, dates)
])
def xirr(values, dates):
return anderson(lambda r: xnpv(r, values, dates), 0)
import datetime
from decimal import *
# Input Data
dates = [datetime.date(2020, 8, 31), datetime.date(2020, 5, 5), datetime.date(2020, 2, 28), datetime.date(2020, 8, 31),datetime.date(2018, 6, 30)]
values = [50289.0, -75000.0, 0.0, 0.0, 0.0]
# Create Dataframe from Input Data
test = pd.DataFrame({"dates" : dates, "values" : values})
# Filter all rows with 0 cashflows
test = test[test['values'] != 0]
# Sort dataframe by date
test = test.sort_values('dates', ascending=True)
test['values'] = test['values'].astype('float')
# Create separate lists for values and dates
test_values = list(test['values'])
test_dates = list(test['dates'])
# Calculate IRR
xirr(test_values, test_dates)
array(-0.70956212)