6

ActiveState 食谱网站有一个用 Python实现内部收益率的函数:

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 的几个示例),但我想知道为什么

  • 它似乎不是牛顿法(无导数)或正割法(仅跟踪一次迭代)的实现。
  • 特别是,将投资变量定义为第一个现金流量元素(以及它的后续使用)让我感到困惑。

有任何想法吗?

4

3 回答 3

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.

于 2011-08-01T08:01:48.980 回答
3

这对我来说似乎是假的。收敛速度太慢,不适合实际使用。

>>> irr([-100, 100]) # expecting answer 0
0.00990099009900991
于 2011-08-01T00:09:29.153 回答
2

我也觉得是假的。

>>> irr([-100,50],100000)  # expecting answer -0.5
0.0
于 2011-08-01T00:32:31.933 回答