这个IRR实现中使用了什么数值方法?

6 投票
3 回答
2028 浏览
提问于 2025-04-16 22:37

ActiveState Recipes网站上有一个用Python实现的内部收益率(Internal Rate of Return)函数:

def irr(cashflows, iterations=100):
    """The IRR or Internal Rate of Return is the annualized effective 
       compounded return rate which can be earned on the invested 
       capital, i.e., the yield on the investment.

       >>> irr([-100.0, 60.0, 60.0, 60.0])
       0.36309653947517645
    """
    rate = 1.0
    investment = cashflows[0]
    for i in range(1, iterations+1):
        rate *= (1 - npv(rate, cashflows) / investment)
    return rate

这段代码返回的值是正确的(至少在我用Excel检查的几个例子中是这样),但我想知道为什么

  • 这看起来并不是牛顿法的实现(没有导数),也不是割线法(只记录了一次迭代)。
  • 特别是,投资变量被定义为第一个现金流元素(以及后续的使用)让我感到困惑。

有什么想法吗?

3 个回答

2

我也觉得这看起来不太靠谱。

>>> irr([-100,50],100000)  # expecting answer -0.5
0.0
3

我觉得这听起来不太靠谱。它的收敛速度太慢,实际使用起来不太方便。

>>> irr([-100, 100]) # expecting answer 0
0.00990099009900991
4

这个方法叫做“固定点迭代”,你可以在维基百科上找到相关的介绍,链接是http://en.wikipedia.org/wiki/Fixed_point_iteration

简单来说,如果rate这个值是正确的(也就是内部收益率IRR),那么净现值NPV就会等于零。因此,下面这条语句

rate *= (1 - npv(rate, cashflows) / investment)

就不会改变rate的值。所以,一旦你找到了IRR,这个迭代过程就不会再改变它。固定点迭代有时候能找到正确的值,有时候则不能。@Gareth和@unutbu的例子就表明,这里并不总是能收敛到正确的结果。

判断是否收敛的标准是这样的:在循环中把更新语句写成

rate = rate * (1 - npv(rate, cashflows) / investment)

现在,如果右边的导数(也就是变化率)相对于rate的值在1和-1之间,那么这个方法就会收敛。我现在还不太清楚在什么情况下会满足这个条件。

你可能会好奇,为什么迭代过程中不使用

rate *= (1 - npv(rate, cashflows))

而是用一个奇怪的investment变量。其实我也有同样的疑问;如果满足导数条件,这样做也会是一个收敛到IRR的固定点方法。我的猜测是,给出的这个方法在某些情况下满足导数条件,而没有investment的那个方法则不满足。

撰写回答