这个IRR实现中使用了什么数值方法?
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
的那个方法则不满足。