#python #pandas #finance #irr #xirr
#python #pandas #финансы #irr #xirr
Вопрос:
Я использую следующие функции для выполнения IRR-вычислений с помощью Python:
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
В течение нескольких месяцев эти функции отлично работали со всеми видами различных денежных потоков и дат, и я получил тот же результат, что и с функцией XIRR в Excel. Однако, внезапно, с приведенным ниже списком денежных потоков и дат, он перестал работать, и я получаю результат, отличный от формулы IRR Excel (которая является правильной и ожидаемой):
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, и я понятия не имею, чего мне здесь не хватает. Может быть, у кого-то есть идея?!??!
Ответ №1:
Функции оптимизации 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)
Комментарии:
1. Да, большое спасибо, вы спасли мой день!! Я изменил функцию на anderson и получил ожидаемый результат. Однако теперь некоторые другие денежные потоки рассчитываются некорректно, что до сих пор нормально работало с методом Ньютона. Тем не менее, благодаря вам теперь я знаю основную причину этой проблемы и попытаюсь найти решение самостоятельно…
2. Попробуйте представить свое приблизительное предположение о том, каким должно быть значение. Я думаю, что это должно работать в большинстве ситуаций.
3. Я пишу библиотеку, которая переводит формулы Excel на Python, и я только что написал поддержку для XIRR, используя код Сергея Бушманова. Библиотека [xlcalculator][1], а код для XIRR можно найти в определениях финансовых функций. [Справка Microsoft][2] утверждает, что они используют оптимизацию Ньютона при вычислении XIRR. Я поддерживаю предложение о предоставлении предположения. [1]: github.com/bradbase/xlcalculator [2]: learn.microsoft.com/en-us/office/troubleshoot/excel /…
4. @bradbase Очень хорошая попытка! При переводе формул Excel может быть особенно полезно, если к csv могут быть применены такие операторы, как LOOKUP, которые не имеют точных аналогов в Python (с возможным указанием диапазона)
5. Приветствия. Я горжусь этим. Библиотека xlcalculator может быть запущена из словаря (ссылка ниже). Я думаю, что это единственная в своем роде библиотека, которая может принимать dict. Мне ( / проекту) еще предстоит реализовать поиск, но он есть на карточках. конкурирующие библиотеки (pycel, formulas и koala) реализовали поиск, поэтому нам нужно будет его поддерживать. В настоящее время никто не поднял вопрос о поддержке поиска, и никто не предложил PR ; D . github.com/bradbase/xlcalculator/blob/master/tests /…