关于 time-value-of-money
time-value-of-money 是供金融学习者和从业者计算现金流时间价值的技能,涵盖复利、年金、NPV、IRR 和贷款摊还,并提供 Python 实现及示例校验。
主要功能
- 01现值与终值计算
- 02离散与连续复利
- 03年金与永续年金估值
- 04现金流 NPV 与 IRR
- 05贷款摊还计划
- 06Python 演示与验证
适用场景
- 01比较不同日期的现金流
- 02使用 NPV 或 IRR 评估项目
- 03计算贷款还款额与余额
- 04通过示例校验金融公式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ joellewis/ finance_skills --skill time-value-of-money安装后在 Claude Code 中输入/time-value-of-money确认已加载。
附带文件scripts/time_value_of_money.py
详细介绍
货币的时间价值
核心概念
未来价值(FV)
当前金额按每期利率 r 计息 n 期后的价值。
$$FV = PV \times (1 + r)^n$$
未来价值会随时间呈指数增长,这是复利的数学基础。
现值(PV)
未来金额按利率 r 折现 n 期后的当前价值。这是未来价值的逆运算。
$$PV = \frac{FV}{(1 + r)^n}$$
现值是所有估值的基石:今天的 1 美元比明天的 1 美元更值钱,因为资本存在机会成本。
复利计算惯例
利息可以按不同频率复利计算。名义年利率 r_nom 每年复利 m 次时,会产生不同的有效收益率。
离散复利(每年复利 m 次):
$$FV = PV \times \left(1 + \frac{r_{nom}}{m}\right)^{m \times t}$$
连续复利:
$$FV = PV \times e^{r \times t}$$
有效年利率(EAR):
$$EAR = \left(1 + \frac{r_{nom}}{m}\right)^m - 1$$
连续复利时:EAR = e^(r_nom) - 1
常见频率:
| 频率 | m |
|---|---|
| 每年 | 1 |
| 每半年 | 2 |
| 每季度 | 4 |
| 每月 | 12 |
| 每日 | 365 |
| 连续 | infinity |
普通年金
在 n 期内,每期期末支付金额相等的一系列款项。
现值:
$$PV = PMT \times \frac{1 - (1 + r)^{-n}}{r}$$
未来价值:
$$FV = PMT \times \frac{(1 + r)^n - 1}{r}$$
先付年金
在每期期初支付金额相等的一系列款项。与普通年金相比,每笔现金流都提前一期,因此其价值需乘以 (1 + r)。
现值:
$$PV = PMT \times \frac{1 - (1 + r)^{-n}}{r} \times (1 + r)$$
未来价值:
$$FV = PMT \times \frac{(1 + r)^n - 1}{r} \times (1 + r)$$
增长年金
一系列有限期付款,每期按固定比率 g 增长,且 g != r。
现值:
$$PV = \frac{PMT}{r - g} \times \left[1 - \left(\frac{1 + g}{1 + r}\right)^n\right]$$
这广泛用于股权估值(例如,多阶段股息贴现模型)以及薪资和养老金预测。
永续年金
无限期支付金额相等的一系列款项。
$$PV = \frac{PMT}{r}$$
增长永续年金
付款额以固定比率 g 无限期增长;要使级数收敛,必须满足 g < r。
$$PV = \frac{PMT}{r - g}$$
将其应用于股息时,这就是戈登增长模型。
净现值(NPV)
所有折现现金流(包括初始投资)的总和。NPV 为正表示创造了价值。
$$NPV = \sum_{t=0}^{T} \frac{CF_t}{(1 + r)^t}$$
通常,CF_0 是负的现金流出(初始投资),后续的 CF_t 则为现金流入。
内部收益率(IRR)
使所有现金流的 NPV 恰好为零的折现率 r。
$$0 = \sum_{t=0}^{T} \frac{CF_t}{(1 + r)^t}$$
由于一般现金流序列没有闭式解,IRR 需通过数值方法(牛顿-拉夫森法或二分法)求解。对于常规现金流(符号只变一次),IRR 唯一。
摊销
摊销贷款的每笔还款都分为利息部分和本金部分:
- 利息部分:
Interest_t = Balance_{t-1} * r - 本金部分:
Principal_t = PMT - Interest_t - 剩余余额:
Balance_t = Balance_{t-1} - Principal_t
随着时间推移,利息部分逐渐减少,本金部分逐渐增加。
关键公式
| 公式 | 表达式 | 用例 |
|---|---|---|
| 终值 | FV = PV * (1 + r)^n | 将一笔总额复利到未来 |
| 现值 | PV = FV / (1 + r)^n | 对未来的一笔总额进行贴现 |
| EAR | (1 + r_nom/m)^m - 1 | 比较不同复利频率下的利率 |
| 连续复利终值 | FV = PV * e^(r*t) | 连续复利 |
| 普通年金现值 | PMT * [1 - (1+r)^(-n)] / r | 贷款还款、租赁估值 |
| 先付年金现值 | PMT * [1 - (1+r)^(-n)] / r * (1+r) | 租金、保险费(预先支付) |
| 增长年金现值 | PMT/(r-g) * [1 - ((1+g)/(1+r))^n] | 薪资流、增长型股息 |
| 永续年金现值 | PMT / r | 优先股、统一公债 |
| 增长型永续年金现值 | PMT / (r - g) | Gordon 增长模型 |
| NPV | sum(CF_t / (1+r)^t) | 项目/投资评估 |
| IRR | solve: sum(CF_t / (1+r)^t) = 0 | 不规则现金流的收益率指标 |
示例演算
示例 1:月供房贷
已知: 一笔金额为 $300,000 的房贷,年利率为 6.5%,固定期限为 30 年,按月还款(普通年金)。
计算: 每月还款金额。
解答:
首先,将年利率换算为月利率,并将年数换算为月数:
r_monthly = 0.065 / 12 = 0.00541667
n = 30 * 12 = 360 months
使用普通年金现值公式,求解 PMT:
PV = PMT * [1 - (1 + r)^(-n)] / r
300,000 = PMT * [1 - (1.00541667)^(-360)] / 0.00541667
计算年金因子:
(1.00541667)^360 = 6.99179
(1.00541667)^(-360) = 0.143010
1 - 0.143010 = 0.856990
0.856990 / 0.00541667 = 158.2108
求解 PMT:
PMT = 300,000 / 158.2108 = $1,896.20
每月房贷还款额为 $1,896.20。
30 年内的还款总额 = 360 * $1,896.20 = $682,632,这意味着支付的总利息为 $682,632 - $300,000 = $382,632。
示例 2:现金流不规则项目的 NPV
已知: 某项目需要 $50,000 的初始投资,并产生以下现金流:
- 第 1 年:$12,000
- 第 2 年:$15,000
- 第 3 年:$18,000
- 第 4 年:$22,000
- 第 5 年:$25,000
要求收益率(贴现率)为 10%。
计算: NPV,以及是否应接受该项目。
解答:
将每笔现金流贴现为现值:
PV(CF_0) = -50,000 / (1.10)^0 = -50,000.00
PV(CF_1) = 12,000 / (1.10)^1 = 10,909.09
PV(CF_2) = 15,000 / (1.10)^2 = 12,396.69
PV(CF_3) = 18,000 / (1.10)^3 = 13,523.67
PV(CF_4) = 22,000 / (1.10)^4 = 15,026.30
PV(CF_5) = 25,000 / (1.10)^5 = 15,523.03
汇总所有现值:
NPV = -50,000.00 + 10,909.09 + 12,396.69 + 13,523.67 + 15,026.30 + 15,523.03
NPV = +$17,378.78
由于 NPV 为正值($17,378.78),该项目能够创造价值,应予以接受。其收益高于 10% 的要求收益率。
若要计算 IRR,需要求解使 NPV = 0 的利率。通过数值计算,该现金流的 IRR 约为 21.2%(21.18%),远高于 10% 的门槛利率。
常见误区
- 利率与周期频率不匹配:如果按月付款,贴现率必须是月利率。将年名义利率除以 12;除非是从 EAR 换算,否则不要对
(1 + annual rate)开 12 次方根。 - 忘记 IRR 的现金流符号约定:流出(投资)必须为负,流入(回报)必须为正,反之亦可,但必须始终使用一致的约定。符号错误会导致 IRR 结果毫无意义。
- 混淆名义利率与有效利率:按月复利的 12% 名义利率对应的 EAR 为 12.68%,而非 12%。务必明确复利计算依据。
- 先付年金与普通年金之间出现差一错误:先付年金将所有付款提前一期。若忘记乘以
(1 + r)调整因子,就会低估先付年金现金流的价值。 - 非常规现金流存在多个 IRR 解:当现金流多次改变符号时(例如先有初始流出,随后有流入,最后又有大额终期流出),笛卡尔符号法则允许正实数 IRR 解的数量最多与符号变化次数相同。在这种情况下,应使用 NPV 分析或修正 IRR(MIRR)。
运行脚本
scripts/time_value_of_money.py 将上述每个公式实现为 TimeValueOfMoney 类的静态方法(present_value、future_value、npv、irr、annuity_pv、annuity_fv、growing_annuity_pv、perpetuity_pv、fisher_rate、continuous_compounding),并包含一个 AmortizationSchedule 类。
- 运行:
uv run scripts/time_value_of_money.py(PEP 723 内联元数据;仅使用标准库,无第三方依赖),或直接运行python3 scripts/time_value_of_money.py。 - 直接运行(或使用
--verify)会演示所有方法,并且断言上面的示例计算值(示例 1:抵押贷款月供 = $1,896.20;示例 2:NPV = $17,378.78,IRR = 21.18%);任何不匹配都会以非零状态码退出。 --help会列出可用方法和导入用法。- 如需以编程方式使用,请导入而非运行:
from time_value_of_money import TimeValueOfMoney, AmortizationSchedule,然后调用例如TimeValueOfMoney.npv(...)。
交叉引用
- return-calculations(核心插件):CAGR 是复合增长的特例;投资组合 MWR 使用相同的 NPV=0 框架,并在该插件中实现
- statistics-fundamentals(核心插件):贴现率估算通常依赖回归(CAPM beta)和分布假设