Функция IRR Python, дающая результат, отличный от Excel XIRR

#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 /…