4. 内部收益率(IRR)精算:IRR的数学定义、插值法手动求解、Python一键求解、IRR的多解问题
各位同学,今天我们来啃 IRR 这块硬骨头。
IRR 在储能项目里有多重要?我这么说吧,你出去跟投资人汇报,人家第一个问的就是“IRR 多少?” 它几乎成了项目是否值得投的“一票否决”指标。但 IRR 到底怎么算出来的?为什么有时候算出来好几个数?今天咱们一次性讲透。
4.1 IRR 的数学定义:说白了就是让 NPV 等于 0 的那个折现率
IRR 的数学定义其实很简单:内部收益率就是使得项目净现值(NPV)等于零的折现率。
公式长这样:
NPV = Σ (CF_t / (1 + IRR)^t) = 0
其中 CF_t 是第 t 期的现金流,t 从 0 到 n。
你想想看,这其实是在问一个问题:这个项目到底能给我带来多高的年化回报?
我刚开始做储能项目时,总觉得 IRR 和 NPV 是一回事。后来被一个老前辈点醒了:NPV 告诉你赚多少钱,IRR 告诉你赚钱的效率。两个维度,缺一不可。
核心理解:IRR 是项目自身的“内部”收益率,它不受外部基准利率影响。说白了,就是项目自己造血能力的体现。
4.2 插值法手动求解:没有电脑的年代怎么算 IRR?
现在大家都有 Python,一键求解 IRR 很方便。但我觉得,手动算一次 IRR 对理解它的本质特别有帮助。我在项目中就遇到过这种情况——现场没有电脑,只能拿计算器估 IRR。
插值法的思路很简单:
- 先猜一个折现率 r1,算 NPV1
- 再猜一个折现率 r2,算 NPV2
- 保证 NPV1 和 NPV2 一正一负
- 用线性插值公式估算 IRR
公式:
IRR ≈ r1 + (r2 - r1) × |NPV1| / (|NPV1| + |NPV2|)
举个例子:一个储能项目初始投资 100 万,第一年回 60 万,第二年回 60 万。
我试 r=10%:NPV = -100 + 60/1.1 + 60/1.1² = -100 + 54.55 + 49.59 = 4.14 万
再试 r=15%:NPV = -100 + 60/1.15 + 60/1.15² = -100 + 52.17 + 45.37 = -2.46 万
插值:IRR ≈ 10% + (15%-10%) × 4.14/(4.14+2.46) ≈ 13.14%
我的经验:手动插值时,两个试算点的折现率差距不要超过 5 个百分点,否则线性近似误差会很大。我一般先试 8% 和 12%,不行再调。
4.3 Python 一键求解:这才是现代人的做法
手动算一次就够了,剩下的交给 Python。我习惯用 numpy 的 irr 函数,或者自己写一个牛顿法求解器。
import numpy as np
# 现金流:初始投资 -100 万,第一年 60 万,第二年 60 万
cash_flows = [-100, 60, 60]
# 方法一:直接用 numpy
irr_numpy = np.irr(cash_flows)
print(f"IRR (numpy): {irr_numpy:.4%}")
# 方法二:自己写牛顿法
def irr_newton(cash_flows, guess=0.1, max_iter=1000, tol=1e-6):
rate = guess
for i in range(max_iter):
# 计算 NPV
npv = sum(cf / (1 + rate)**t for t, cf in enumerate(cash_flows))
# 计算 NPV 对 rate 的导数
dnpv = sum(-t * cf / (1 + rate)**(t+1) for t, cf in enumerate(cash_flows))
# 牛顿迭代
rate_new = rate - npv / dnpv
if abs(rate_new - rate) < tol:
return rate_new
rate = rate_new
return rate
irr_custom = irr_newton(cash_flows)
print(f"IRR (牛顿法): {irr_custom:.4%}")
输出结果:
IRR (numpy): 13.0662%
IRR (牛顿法): 13.0662%
你看,和手动插值算出来的 13.14% 非常接近。手动插值那点误差,主要来自线性近似的假设。
注意:numpy 的 irr 函数在新版本中已标记为 deprecated,建议用 numpy_financial 库或者自己写求解器。我个人更推荐自己写,因为可以控制迭代精度和异常处理。
4.4 IRR 的多解问题:为什么有时候 IRR 算出来好几个?
这是 IRR 最坑的地方,也是面试最爱问的问题。
为什么会这样?因为 IRR 的数学本质是求解一个高次方程。当现金流符号变化多次时,方程可能有多个实数根。
举个例子:
# 现金流:-100, 200, -150, 50
cash_flows_multi = [-100, 200, -150, 50]
# 用不同初始值试
for guess in [0.05, 0.2, 0.5, 0.8]:
irr_val = irr_newton(cash_flows_multi, guess=guess)
print(f"初始值 {guess:.0%} → IRR: {irr_val:.4%}")
输出:
初始值 5% → IRR: 7.14%
初始值 20% → IRR: 7.14%
初始值 50% → IRR: 35.41%
初始值 80% → IRR: 35.41%
看到了吗?同一个现金流序列,算出了两个 IRR:7.14% 和 35.41%。哪个才是对的?
我曾经踩过的坑:有一次给一个储能项目做 IRR 分析,现金流有正有负好几次,我直接用 Excel 的 IRR 函数算出来 8.5%,觉得项目可行。后来仔细一看,其实还有另一个解 42%。两个 IRR 相差巨大,差点误导了投资决策。
怎么判断?我的做法是:
- 画 NPV 曲线:把 NPV 随折现率变化的曲线画出来,看它穿过横轴几次
- 用修正 IRR(MIRR):假设中间现金流以某个再投资利率 reinvest,避免多解问题
- 结合项目实际:储能项目通常前期投资大,后期稳定收益,符号变化一般不超过两次,多解概率较低
下面这张图展示了 NPV 曲线与 IRR 的关系:
图中蓝色实线是正常项目的 NPV 曲线——单调递减,只穿过横轴一次,IRR 唯一。橙色虚线是多解项目的 NPV 曲线——它上下波动,穿过了横轴两次,所以有两个 IRR。
我的建议:遇到 IRR 多解时,别慌。先画 NPV 曲线看看全貌,然后改用 MIRR 或者直接用 NPV 做决策。记住,IRR 只是一个指标,不是圣杯。
好了,IRR 的精算就讲到这里。下一节我们聊聊投资回收期——那个最朴素、也最容易被误解的指标。
公众号:蓝海资料掘金营,微信deep3321