首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中计算XIRR

在Python中计算XIRR
EN

Stack Overflow用户
提问于 2017-10-10 21:35:11
回答 3查看 9.9K关注 0票数 5

我需要计算一段时间内的金融投资的XIRR。在numpy、pandas或普通的python中有什么函数可以做到这一点吗?

Reference: What is XIRR?

原问题中被接受的答案不正确,可以改进。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-10 21:46:00

下面是取自here的一个实现。

代码语言:javascript
运行
复制
import datetime
from scipy import optimize

def xnpv(rate,cashflows):
    chron_order = sorted(cashflows, key = lambda x: x[0])
    t0 = chron_order[0][0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in chron_order])

def xirr(cashflows,guess=0.1):
    return optimize.newton(lambda r: xnpv(r,cashflows),guess)
票数 3
EN

Stack Overflow用户

发布于 2021-05-18 17:37:30

创建了一个用于快速计算XIRR的软件包PyXIRR

它没有外部依赖,工作速度比任何现有实现都要快。

代码语言:javascript
运行
复制
from datetime import date
from pyxirr import xirr

dates = [date(2020, 1, 1), date(2021, 1, 1), date(2022, 1, 1)]
amounts = [-1000, 1000, 1000]

# feed columnar data
xirr(dates, amounts)

# feed tuples
xirr(zip(dates, amounts))

# feed DataFrame
import pandas as pd
xirr(pd.DataFrame({"dates": dates, "amounts": amounts}))
票数 3
EN

Stack Overflow用户

发布于 2021-02-11 04:27:18

此实现计算一次时间增量,然后向量化NPV计算。对于更大的数据集,它的运行速度应该比@pyCthon的解决方案快得多。输入是一系列包含指数日期的pandas现金流。

代码

代码语言:javascript
运行
复制
import pandas as pd
import numpy as np
from scipy import optimize

def xirr2(valuesPerDate):
  """  Calculate the irregular rate of return.
  valuesPerDate is a pandas series of cashflows with index of dates.
  """

  # Clean values
  valuesPerDateCleaned = valuesPerDate[valuesPerDate != 0]

  # Check for sign change
  if valuesPerDateCleaned.min() * valuesPerDateCleaned.max() >= 0:
    return np.nan

  # Set index to time delta in years
  valuesPerDateCleaned.index = (valuesPerDateCleaned.index - valuesPerDateCleaned.index.min()).days / 365.0

  result = np.nan
  try:
    result = optimize.newton(lambda r: (valuesPerDateCleaned / ((1 + r) ** valuesPerDateCleaned.index)).sum(), x0=0, rtol=1e-4)
  except (RuntimeError, OverflowError): 
    result = optimize.brentq(lambda r: (valuesPerDateCleaned / ((1 + r) ** valuesPerDateCleaned.index)).sum(), a=-0.999999999999999, b=100, maxiter=10**4)

  if not isinstance(result, complex):
    return result
  else:
    return np.nan

测试

代码语言:javascript
运行
复制
valuesPerDate = pd.Series()
for d in pd.date_range(start='1990-01-01', end='2019-12-31', freq='M'):
  valuesPerDate[d] = 10*np.random.uniform(-0.5,1)
valuesPerDate[0] = -100

print(xirr2(valuesPerDate))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46668172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档