关于 dcf-model
dcf-model 是用于在 Excel 中构建投行标准贴现现金流模型的技能,面向进行股票估值的分析人员,涵盖财务分析、情景预测、估值及公式驱动的敏感性分析。
主要功能
- 01历史财务分析
- 02熊市、基准与牛市场景区块
- 03收入与运营费用预测
- 04WACC 与终值计算
- 05股权估值桥接
- 06公式驱动的敏感性分析
适用场景
- 01预测公司自由现金流
- 02比较熊市、基准与牛市估值
- 03测试 WACC 与终值增长率假设
MCP 相关
该技能要求在构建 DCF 模型时,优先使用可用 MCP 服务获取结构化财务数据。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ w95/ awesome-claude-corporate-skills --skill dcf-model安装后在 Claude Code 中输入/dcf-model确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
requirements.txtTROUBLESHOOTING.mdscripts/validate_dcf.py详细介绍
DCF 模型构建器
概述
此技能按照投资银行标准创建机构级 DCF 模型,用于股权估值。每项分析都会生成详细的 Excel 模型(DCF 工作表底部包含敏感性分析)。
工具
- 默认使用用户提供的所有信息,以及可用于数据获取的 MCP 服务。
关键限制——请先阅读
在整个 DCF 模型构建过程中均须遵守以下限制。开始前请先查看:
敏感性分析表:
- 使用完整的 DCF 重新计算公式填写全部 75 个单元格(3 个表 × 25 个单元格)
- 使用 openpyxl 循环以编程方式写入公式
- 不得使用占位文本,不得进行线性近似,也不得要求手动操作
- 每个单元格都必须根据相应假设组合重新计算完整的 DCF
单元格批注:
- 每创建一个硬编码值,就立即添加单元格批注
- 格式:“来源:[系统/文档],[日期],[参考资料],[适用时填写 URL]”
- 转到下一部分前,必须为每个蓝色输入值添加批注
- 不得拖到最后处理,也不得写“TODO: 添加来源”
模型布局规划:
- 写入任何公式前,定义所有部分的行位置
- 先写入所有标题和标签
- 再写入所有部分分隔线和空行
- 然后使用已锁定的行位置写入公式
- 创建公式后立即测试
公式重新计算:
- 交付前运行
python recalc.py model.xlsx 30 - 修复所有错误,直至状态为“success”
- 公式错误必须为零(#REF!、#DIV/0!、#VALUE! 等)
情景区块:
- 为 Bear/Base/Bull 情景创建单独区块
- 在每个区块中,按横向排列的投影年份展示假设
- 使用 IF 公式:
=IF($B$6=1,[Bear cell],IF($B$6=2,[Base cell],[Bull cell])) - 验证公式引用了正确情景区块中的单元格
DCF 流程
第 1 步:数据获取与验证
从 MCP 服务、用户提供的数据和网络获取数据。
数据源优先级:
- MCP 服务(如已配置)——来自 Daloopa 等提供商的结构化财务数据
- 用户提供的数据——用户研究中的历史财务数据
- 网络搜索/获取——需要时获取当前股价、Beta、债务和现金数据
验证清单:
- 核实净债务与净现金(对估值至关重要)
- 确认稀释后流通股数(检查近期回购/增发情况)
- 验证历史利润率是否符合业务模式
- 将收入增长率与行业基准交叉核对
- 确认税率合理(通常为 21%–28%)
第 2 步:历史分析(3–5 年)
分析并记录:
- 收入增长趋势:计算 CAGR,找出驱动因素
- 利润率变化:跟踪毛利率、EBIT 利润率和 FCF 利润率
- 资本密集度:折旧摊销和资本支出占收入的比例
- 营运资本效率:NWC 变化占收入增长的比例
- 回报指标:ROIC、ROE 趋势
创建汇总表,展示:
Historical Metrics (LTM):
Revenue: $X million
Revenue growth: X% CAGR
Gross margin: X%
EBIT margin: X%
D&A % of revenue: X%
CapEx % of revenue: X%
FCF margin: X%
第 3 步:构建收入预测
方法:
- 从最近的实际收入开始(LTM 或最近一个财年)
- 应用各预测年度的增长率
- 同时展示金额和计算得出的增长率 %
增长率框架:
- 第 1–2 年:反映近期可见度较高的更快增长
- 第 3–4 年:逐步回落至行业平均水平
- 第 5 年及以后:接近终值增长率
公式结构:
- 收入(第 N 年)= 收入(第 N-1 年)×(1 + 增长率)
- 增长率 %(第 N 年)= 收入(第 N 年)/ 收入(第 N-1 年)- 1
三情景方法:
Bear Case: Conservative growth (e.g., 8-12%)
Base Case: Most likely scenario (e.g., 12-16%)
Bull Case: Optimistic growth (e.g., 16-20%)
步骤 4:运营费用建模
固定/变动成本分析:
运营费用应体现合理的经营杠杆:
- 销售与营销:通常占收入的 15-40%,具体取决于商业模式
- 研发:科技公司的比例通常为 10-30%
- 一般及行政费用:通常占收入的 8-15%,随着公司规模扩大,体现经营杠杆
关键原则:
- 所有百分比均基于收入,而非毛利
- 建模时应体现经营杠杆:随着收入增长,百分比应下降
- 为销售与营销、研发、一般及行政费用分别设置独立项目
- 计算 EBIT = 毛利 - 运营费用总额
利润率扩张框架:
Current State → Target State (Year 5)
Gross Margin: X% → Y% (justify based on scale, efficiency)
EBIT Margin: X% → Y% (result of revenue growth + opex leverage)
步骤 5:自由现金流计算
按正确顺序构建自由现金流:
EBIT
(-) Taxes (EBIT × Tax Rate)
= NOPAT (Net Operating Profit After Tax)
(+) D&A (non-cash expense, % of revenue)
(-) CapEx (% of revenue, typically 4-8%)
(-) Δ NWC (change in working capital)
= Unlevered Free Cash Flow
营运资金建模:
- 按收入变动(收入增量)的百分比计算
- 常见范围:收入变动的 -2% 至 +2%
- 负数 = 现金来源(释放营运资金)
- 正数 = 现金用途(增加营运资金)
维护性与增长性资本支出:
- 维护性资本支出:维持当前运营(约占收入的 2-3%)
- 增长性资本支出:支持业务扩张(额外占收入的 2-5%)
- 资本支出总额应与公司的增长战略一致
步骤 6:资本成本(WACC)研究
股权成本的 CAPM 方法:
Cost of Equity = Risk-Free Rate + Beta × Equity Risk Premium
Where:
- Risk-Free Rate = Current 10-Year Treasury Yield
- Beta = 5-year monthly stock beta vs market index
- Equity Risk Premium = 5.0-6.0% (market standard)
债务成本计算:
After-Tax Cost of Debt = Pre-Tax Cost of Debt × (1 - Tax Rate)
Determine Pre-Tax Cost of Debt from:
- Credit rating (if available)
- Current yield on company bonds
- Interest expense / Total Debt from financials
资本结构权重:
Market Value Equity = Current Stock Price × Shares Outstanding
Net Debt = Total Debt - Cash & Equivalents
Enterprise Value = Market Cap + Net Debt
Equity Weight = Market Cap / Enterprise Value
Debt Weight = Net Debt / Enterprise Value
WACC = (Cost of Equity × Equity Weight) + (After-Tax Cost of Debt × Debt Weight)
特殊情况:
- 净现金头寸:如果现金 > 债务,则净债务为负
- 债务权重可能为负
- WACC 计算会相应调整
- 无债务:WACC = 股权成本
WACC 常见范围:
- 大盘股、业务稳定:7-9%
- 成长型公司:9-12%
- 高增长/高风险:12-15%
步骤 7:应用折现率(5-10 年预测)
年中惯例:
- 假设现金流在年中发生
- 折现期:0.5、1.5、2.5、3.5、4.5 等
- 折现因子 = 1 / (1 + WACC)^折现期
现值计算:
For each projection year:
PV of FCF = Unlevered FCF × Discount Factor
Example (Year 1):
FCF = $1,000
WACC = 10%
Period = 0.5
Discount Factor = 1 / (1.10)^0.5 = 0.9535
PV = $1,000 × 0.9535 = $954
预测期选择:
- 5 年:大多数分析的标准期限
- 7-10 年:具有较长增长空间的高增长公司
- 3 年:成熟、稳定的企业
步骤 8:终值计算
永续增长法(首选):
Terminal FCF = Final Year FCF × (1 + Terminal Growth Rate)
Terminal Value = Terminal FCF / (WACC - Terminal Growth Rate)
Critical Constraint: Terminal Growth < WACC (otherwise infinite value)
终值增长率的选择:
- 保守:2.0-2.5%(GDP 增长率)
- 中性:2.5-3.5%
- 激进:3.5-5.0%(仅适用于市场领导者)
不得超过:无风险利率或长期 GDP 增长率
退出倍数法(替代方法):
Terminal Value = Final Year EBITDA × Exit Multiple
Where Exit Multiple comes from:
- Industry comparable trading multiples
- Precedent transaction multiples
- Typical range: 8-15x EBITDA
终值现值:
PV of Terminal Value = Terminal Value / (1 + WACC)^Final Period
Where Final Period accounts for timing:
5-year model with mid-year convention: Period = 4.5
终值合理性检查:
- 应占企业价值的 50-70%
- 如果 >75%,模型可能过度依赖终值假设
- 如果 <40%,检查终值假设是否过于保守
步骤 9:从企业价值到股权价值的桥接
估值摘要结构:
(+) Sum of PV of Projected FCFs = $X million
(+) PV of Terminal Value = $Y million
= Enterprise Value = $Z million
(-) Net Debt [or + Net Cash if negative] = $A million
= Equity Value = $B million
÷ Diluted Shares Outstanding = C million shares
= Implied Price per Share = $XX.XX
Current Stock Price = $YY.YY
Implied Return = (Implied Price / Current Price) - 1 = XX%
关键调整:
- 净债务 = 债务总额 - 现金及现金等价物
- 如果为正:从 EV 中扣除(降低股权价值)
- 如果为负(净现金):加至 EV(提高股权价值)
- 使用稀释后股数:包括期权、RSU、可转换证券
- 其他调整(如适用):
- 少数股权
- 养老金负债
- 经营租赁义务
估值输出格式:
Valuation Component,Amount ($M)
PV Explicit FCFs,X.X
PV Terminal Value,Y.Y
Enterprise Value,Z.Z
(-) Net Debt,A.A
Equity Value,B.B
,,
Shares Outstanding (M),C.C
Implied Price per Share,$XX.XX
Current Share Price,$YY.YY
Implied Upside/(Downside),+XX%
步骤 10:敏感性分析
在 DCF 工作表底部构建 三个敏感性分析表,展示估值如何随不同假设变化:
- WACC 与终值增长率 - 展示企业价值对折现率和永续增长率的敏感性
- 收入增长率与 EBIT 利润率 - 展示营收增长和经营杠杆的影响
- Beta 与无风险利率 - 展示股权资本成本各组成部分的敏感性
实现方式:这些是简单的二维网格(不是 Excel 的“数据表”功能),每个单元格中都包含公式。每个单元格都必须针对对应的假设组合重新计算完整 DCF。有关如何使用 openpyxl 以编程方式填充全部 75 个单元格的详细要求,请参阅“关键约束”部分。
<correct_patterns>
本节包含构建 DCF 模型时应遵循的所有正确模式。
情景区块选择模式 - 请遵循此方法
每种情景的假设都分别组织在独立区块中:
关键结构 - 每个分区标题占三行:
BEAR CASE ASSUMPTIONS (section header, merge cells across)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),12%,10%,9%,8%,7%
EBIT Margin (%),45%,44%,43%,42%,41%
BASE CASE ASSUMPTIONS (section header, merge cells across)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),16%,14%,12%,10%,9%
EBIT Margin (%),48%,49%,50%,51%,52%
BULL CASE ASSUMPTIONS (section header, merge cells across)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),20%,18%,15%,13%,11%
EBIT Margin (%),50%,51%,52%,53%,54%
每个情景区块都必须有一行列标题,显示预测年份(FY2025E、FY2026E 等),并紧接在分区标题下方。否则,用户无法判断每个假设值对应哪个年份。
如何引用假设 - 创建汇总列:
- 情景选择器单元格(例如 B6)包含 1=Bear、2=Base 或 3=Bull
- 使用 INDEX 或 OFFSET 公式创建汇总列,从正确的情景区块中提取数值
- 预测公式引用汇总列(单元格引用清晰)
- 每个情景区块都包含覆盖预测年份的完整 DCF 假设集
建议的汇总列模式(使用 INDEX):
=INDEX(B10:D10, 1, $B$6)
不要这样做 - 在各处使用零散的 IF 语句:
=IF($B$6=1,[Bear block cell],IF($B$6=2,[Base block cell],[Bull block cell]))
汇总列方法可集中处理逻辑,让模型更易于审计。
正确的收入预测模式
使用 INDEX 公式创建汇总列,然后在预测中引用该列:
步骤 1 - FY1 增长率的汇总列:
=INDEX([Bear FY1 growth]:[Bull FY1 growth], 1, $B$6)
步骤 2 - 收入预测引用汇总列:
Revenue Year 1: =D29*(1+$E$10)
其中:
- D29 = 上一年度收入
- $E$10 = FY1 增长率的汇总列单元格(包含 INDEX 公式)
- $B$6 = 情景选择器(1=Bear、2=Base、3=Bull)
与在每个预测公式中嵌入 IF 语句相比,这种方法更简洁,也更容易审计所使用的情景假设。
正确的 FCF 公式模式
使用带 INDEX 公式的汇总列,然后在 FCF 计算中引用这些列:
汇总列方法:
Item,Formula,Reference
D&A,=E29*$E$21,$E$21 = consolidation column for D&A %
CapEx,=E29*$E$22,$E$22 = consolidation column for CapEx %
Δ NWC,=(E29-D29)*$E$23,$E$23 = consolidation column for NWC %
Unlevered FCF,=E57+E58-E60-E62,E57=NOPAT E58=D&A E60=CapEx E62=Δ NWC
每个汇总列单元格都包含一个 INDEX 公式,根据情景选择器从对应的情景区块中提取数值。这样可以让预测公式保持清晰,便于审计。
编写公式前,请确认情景区块的行位置并设置汇总列。
正确的单元格批注格式
每个硬编码值都需要采用以下格式:
"Source: [System/Document], [Date], [Reference], [URL if applicable]"
示例:
Item,Source Comment
Stock price,Source: Market data script 2025-10-12 Close price
Shares outstanding,Source: 10-K FY2024 Page 45 Note 12
Historical revenue,Source: 10-K FY2024 Page 32 Consolidated Statements
Beta,Source: Market data script 2025-10-12 5-year monthly beta
Consensus estimates,Source: Management guidance Q3 2024 earnings call
正确的假设表结构
关键:每个情景区块都需要包含三个结构元素:
- 章节标题行(合并单元格):例如,“看跌情景假设”
- 显示年份的列标题行——必须包含,不可跳过
- 包含假设值的数据行
结构:
BEAR CASE ASSUMPTIONS (section header - merge across columns A:G)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),X%,X%,X%,X%,X%
EBIT Margin (%),X%,X%,X%,X%,X%
Terminal Growth,X%,,,,
WACC,X%,,,,
BASE CASE ASSUMPTIONS (section header - merge across columns A:G)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),X%,X%,X%,X%,X%
EBIT Margin (%),X%,X%,X%,X%,X%
Terminal Growth,X%,,,,
WACC,X%,,,,
BULL CASE ASSUMPTIONS (section header - merge across columns A:G)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),X%,X%,X%,X%,X%
EBIT Margin (%),X%,X%,X%,X%,X%
Terminal Growth,X%,,,,
WACC,X%,,,,
如果没有显示预测年份(FY2025E、FY2026E 等)的列标题行,用户就无法判断每个假设值对应哪一年。此行为必需项。
然后创建一个汇总列(通常是右侧相邻列),使用 INDEX 公式,根据情景选择器从选定的情景区块中提取数据。投影公式应引用此汇总列。
正确的行规划流程
1. 首先写入所有标题和标签:
Row,Content
1,[Company Name] DCF Model
2,Ticker | Date | Year End
4,Case Selector
7,KEY ASSUMPTIONS
26,Assumption headers
27-31,Growth assumptions
...,...
2. 写入所有章节分隔线和空行
3. 然后使用已确定的行位置编写公式
4. 创建公式后立即测试
将其想象成施工过程:
- 正确:浇筑地基,然后砌墙(结构稳定)
- 错误:先砌墙,再浇筑地基(墙会倒塌)
Excel 版本:
- 正确:添加标题,然后编写公式(公式稳定)
- 错误:先编写公式,再添加标题(公式会失效)
正确的敏感性分析表实现方式
重要:这不是 Excel 的“数据表”功能,而是使用 openpyxl 编写常规公式的简单网格。是的,这意味着总共约 75 个公式(3 个表 × 每个表 25 个单元格),但这很简单,也是必需的。
使用公式以编程方式填充:
每个敏感性分析表都必须使用公式完整填充,以便针对每种假设组合重新计算隐含股价。不要使用 Excel 的数据表功能(它需要手动操作,无法通过 openpyxl 自动化)。
实现方法——具体示例:
表格结构(5x5 网格):
WACC vs Terminal Growth,2.0%,2.5%,3.0%,3.5%,4.0%
8.0%,[B88 formula],[C88 formula],[D88 formula],[E88 formula],[F88 formula]
9.0%,[B89 formula],[C89 formula],[D89 formula],[E89 formula],[F89 formula]
...,...,...,...,...,...
公式模式——单元格 B88(WACC=8.0%,终值增长率=2.0%):
B88 中的公式应使用以下数值重新计算隐含股价:
- 行标题中的 WACC:
$A88(8.0%) - 列标题中的终值增长率:
B$87(2.0%)
**推荐方法:**引用主 DCF 计算,但替换这些数值。
公式结构示例:
=([使用 $A88 作为折现率计算的 FCF 现值之和] + [使用 B$87 作为增长率、$A88 作为 WACC 计算的终值] - [净债务]) / [股份数]
**关键——为 5x5 网格中的每个单元格都编写公式(每个表 25 个单元格,共 75 个)。**使用 openpyxl 在循环中以编程方式写入这些公式。不要跳过此步骤,也不要留下占位文本。
Python 实现模式:
# Pseudocode for populating sensitivity table
for row_idx, wacc_value in enumerate(wacc_range):
for col_idx, term_growth_value in enumerate(term_growth_range):
# Build formula that uses wacc_value and term_growth_value
formula = f"=<DCF recalc using {wacc_value} and {term_growth_value}>"
ws.cell(row=start_row+row_idx, column=start_col+col_idx).value = formula
打开模型后,敏感性分析表必须立即可用,无需用户执行任何手动操作。
</correct_patterns>
<common_mistakes>
本节列出了构建 DCF 模型时需要避免的所有错误做法。
错误:简化敏感性分析表近似值或占位文本
不要使用线性近似:
// WRONG - Linear approximation
B97: =B88*(1+(0.096-0.116)) // Assumes linear relationship
// WRONG - Division shortcut
B105: =B88/(1+(E48-0.07)) // Doesn't recalculate full DCF
不要留下占位文本:
// WRONG - Placeholder note
"Note: Use Excel Data Table feature (Data → What-If Analysis → Data Table) to populate sensitivity tables."
// WRONG - Empty cells
[leaving cells blank because "this is complex"]
不要混淆术语:
- ❌ “敏感性分析表需要使用 Excel 的 Data Table 功能”(不对——这是我们无法使用的 Excel 专用工具)
- ✅ “敏感性分析表是简单的网格,每个单元格中都有公式”(正确——这就是我们要构建的内容)
这些捷径为什么不对:
- 线性近似公式不会实际重新计算 DCF,只是进行简单的数学调整
- 变量之间的关系并非线性,因此结果会不准确
- 占位文本需要用户手动处理
- 交付时模型无法立即使用
- 不够专业,也无法直接交付给客户
- 空单元格 = 未完成的交付成果
应拒绝的常见借口: “写 75 个以上的公式感觉很复杂,所以我会留个说明,让用户手动完成。”
实际情况: 使用 Python 的 openpyxl 循环编写 75 个公式很简单。每个公式都遵循相同的模式——只需替换行列值。这是交付成果的必需部分。
正确做法: 为每个敏感性分析单元格填入公式,针对相应的假设组合重新计算完整的 DCF
错误:缺少单元格批注
不要这样做:
- 创建所有硬编码输入时都不添加批注
- 心想“我之后再添加”
- 写“TODO:添加来源”
- 留下没有文档说明的蓝色输入项
这样做为什么不对:
- 无法核实数据来源
- 不符合 xlsx 技能要求
- 不便于审计
- 之后再修复会浪费时间
正确做法: 创建每个硬编码值时,立即添加单元格批注
错误:公式行引用错误
症状:
FCF 部分引用了错误的假设行:
D&A: =E29*$E$34 // 应为 $E$21,但引用了错误的行
CapEx: =E29*$E$41 // 应为 $E$22,但行位置偏移了
出现这种情况的原因:
- 先编写公式
- 然后插入标题
- 所有行引用都发生偏移
- 公式现在指向错误的单元格 → 出现 #REF! 错误
正确做法: 先锁定行布局,再编写公式
错误:每个情景下的每项假设只占一行
不要这样安排假设:
Assumption,Bear,Base,Bull
Revenue Growth FY1,10%,13%,16%
Revenue Growth FY2,9%,12%,15%
这种纵向布局不便于查看每种情景下假设随年份变化的情况。
这样做为什么不对:
- 不便于查看每种情景下假设随年份的变化
- 更难比较整个预测期内不同情景的假设
- 审查情景逻辑时不够直观
正确做法:
- 为每种情景(Bear、Base、Bull)创建独立区块
- 在每个区块中,按横向排列显示各预测年份的假设
- 这样更便于将每种情景的假设作为一个整体进行审查
错误:没有边框
不要交付没有边框的模型:
- 没有区分各个部分
- 所有单元格混在一起
- 难以阅读,也不专业
这样做为什么不对:
- 无法直接交付给客户
- 难以浏览
- 显得不专业
正确做法: 为所有主要区块添加边框
错误:字体颜色不正确或没有区分字体颜色
不要这样做:
- 所有文本都是黑色
- 只使用填充颜色(不更改字体颜色)
- 混淆哪些单元格应为蓝色、哪些应为黑色
这样做为什么不对:
- 无法区分输入项和公式
- 无法进行审计
- 违反 xlsx 技能要求
正确做法: 所有硬编码输入项使用蓝色字体,所有公式使用黑色字体,工作表链接使用绿色字体
错误:按毛利润计算运营费用
不要这样做:
S&M: =E33*0.15 // E33 = 毛利润(错误)
这样做为什么不对:
- 运营费用随收入变化,而不是随毛利润变化
- 会导致不切实际的利润率变化
- 不符合企业的实际运营方式
正确做法:
S&M: =E29*0.15 // E29 = 收入(正确)
前 5 大错误总结
- 公式行引用错位 → 在编写公式之前先定义所有行位置
- 缺少单元格批注 → 在创建单元格时就添加批注,而不是最后才加
- 过度简化的敏感性表格 → 用完整的 DCF 重算公式填充所有单元格,而不是近似值
- 情景区块引用错误 → 确保 IF 公式从正确的 Bear/Base/Bull 区块取值
- 没有边框 → 添加专业的分节边框,以便呈现给客户
此外,还要注意以下错误:
WACC 计算错误
- 在资本结构中混用账面价值和市场价值
- 错误地使用股权 beta 而非资产/无杠杆 beta
- 对债务成本应用错误的税率
- 无风险利率不正确(必须使用当前 10Y 国债收益率)
- 未针对净债务与净现金头寸进行调整
增长假设缺陷
- 永续增长率 > WACC(会创造无限价值)
- 预测增长率与历史表现不一致
- 忽视行业增长约束
- 收入增长与单位经济模型不一致
- 没有运营依据的利润率扩张
终值错误
- 使用错误的增长方法(永续增长法与退出倍数法)
- 终值 > 企业价值的 80%(表明过度依赖终值)
- 终值利润率与稳态假设不一致
- 终值的折现期数错误
现金流预测错误
- 营业费用基于毛利润而非收入
- D&A/CapEx 百分比与商业模式不一致
- 营运资本变动未正确计算
- 各年度税率不一致
- NOPAT 计算错误
这些错误最为常见。在开始任何 DCF 建模之前,请重新阅读本节。
</common_mistakes>
Excel 文件创建
本技能在所有电子表格操作中使用 xlsx 技能。 xlsx 技能提供:
- 标准化的公式构建规则
- 数字格式约定
- 通过
recalc.py脚本自动重算公式 - 全面的错误检查与验证
本技能创建的所有 Excel 文件都必须遵循 xlsx 技能要求,包括零公式错误和正确重算。
质量评分标准
每个 DCF 模型都必须最大化以下方面:
- 基于历史表现的现实收入和利润率假设
- 采用正确 CAPM 方法的适当资本成本计算
- 展示估值区间的全面敏感性分析
- 带有支持性依据的清晰终值计算
- 支持情景分析的专业模型结构
- 对所有关键假设的透明文档记录
输入要求
最低必需输入
- 公司标识:股票代码或公司名称
- 增长假设:预测期的收入增长率(或“使用一致预期”)
- 可选参数:
- 预测期(默认:5 年)
- 情景案例(Bear/Base/Bull 增长和利润率假设)
- 终值增长率(默认:2.5-3.0%)
- 若不使用 CAPM,则指定具体的 WACC 输入
Excel 模型结构
工作表架构
创建两个工作表:
- DCF - 主估值模型,底部包含敏感性分析
- WACC - 资本成本计算
关键:敏感性表格放在 DCF 工作表的底部(而不是单独的工作表)。这样可以将所有估值输出保持在一起。
公式重算(强制要求)
创建或修改 Excel 模型后,必须使用 xlsx 技能中的 recalc.py 脚本重新计算所有公式:
python recalc.py [path_to_excel_file] [timeout_seconds]
示例:
python recalc.py AAPL_DCF_Model_2025-10-12.xlsx 30
该脚本将:
- 使用 LibreOffice 重新计算所有工作表中的所有公式
- 扫描所有单元格中的 Excel 错误(#REF!、#DIV/0!、#VALUE!、#NAME?、#NULL!、#NUM!、#N/A)
- 返回包含错误位置和数量的详细 JSON
预期输出格式:
{
"status": "success", // or "errors_found"
"total_errors": 0, // Total error count
"total_formulas": 42, // Number of formulas in file
"error_summary": {} // Only present if errors found
}
如果发现错误,输出将包含详细信息:
{
"status": "errors_found",
"total_errors": 2,
"total_formulas": 42,
"error_summary": {
"#REF!": {
"count": 2,
"locations": ["DCF!B25", "DCF!C25"]
}
}
}
修复所有错误,然后重新运行 recalc.py,直到状态为“success”后再交付模型。
格式标准
重要:遵循 xlsx 技能中的公式构建规则和数字格式惯例。DCF 技能还规定了具体的视觉呈现标准。
配色方案——两层设置:
第 1 层:字体颜色(xlsx 技能的强制要求)
- 蓝色文本(RGB:0,0,255):所有硬编码输入(股价、股数、历史数据、假设)
- 黑色文本(RGB:0,0,0):所有公式和计算结果
- 绿色文本(RGB:0,128,0):对其他工作表的引用(WACC 工作表引用)
第 2 层:填充颜色(可选,用于增强呈现效果)
- 填充颜色为可选项,仅应在用户要求或有助于增强呈现效果时使用
- 如果用户要求使用颜色或专业格式,请采用以下标准方案:
- 章节标题:深蓝色(RGB:68,114,196)背景,白色文本
- 子标题/列标题:浅蓝色(RGB:217,225,242)背景,黑色文本
- 输入单元格:浅绿色/奶油色(RGB:226,239,218)背景,蓝色文本
- 计算单元格:白色背景,黑色文本
- 如用户指定品牌颜色,可覆盖此方案
两层颜色如何搭配使用(如果使用填充颜色):
- 输入单元格:蓝色文本 + 浅绿色填充 =“硬编码输入”
- 公式单元格:黑色文本 + 白色背景 =“计算值”
- 工作表链接:绿色文本 + 白色背景 =“来自 WACC 工作表的引用”
字体颜色表示单元格的性质。填充颜色表示单元格的位置(如果使用)。
重要: xlsx 技能规定的字体颜色为强制要求。填充颜色为可选项——默认使用白色/无填充,除非用户要求增强格式或使用颜色。
边框标准(专业外观的必要要求)
粗边框(1.5pt)用于主要版块周围:
- KEY INPUTS 版块
- PROJECTION ASSUMPTIONS 版块
- 5-YEAR CASH FLOW PROJECTION 版块
- TERMINAL VALUE 版块
- VALUATION SUMMARY 版块
- 每个 SENSITIVITY ANALYSIS 表格
中等边框(1pt)用于子版块之间:
- 公司详情与历史表现之间
- 增长假设、EBIT 利润率与 FCF 参数之间
细边框(0.5pt)用于数据表格周围:
- 情景假设表(Bear | Base | Bull | Selected)
- 历史与预测财务数据矩阵
不加边框: 表格中的单个单元格(保持整洁、易于浏览)
边框为强制要求——没有专业边框的模型尚未达到可交付给客户的标准。
数字格式(遵循 xlsx 技能标准):
- 年份:设置为文本格式(例如,“2024”,而不是“2,024”)
- 百分比:
0.0%(保留一位小数) - 货币:百万级使用
$#,##0;每股金额使用$#,##0.00——标题中必须注明单位(“Revenue ($mm)”) - 零值:使用数字格式将所有零显示为“-”(例如,
$#,##0;($#,##0);-) - 大数:使用带千位分隔符的
#,##0 - 负数:用括号表示(
(#,##0)),不要使用减号
单元格批注(所有硬编码输入均必须添加):
根据 xlsx 技能的要求,所有硬编码值都必须添加单元格批注以记录来源。格式:“Source: [System/Document], [Date], [Reference], [URL if applicable]”
关键要求:创建单元格时立即添加批注。不要留到最后再处理。
DCF 工作表详细结构
第 1 部分:标题
Row,Content
1,[Company Name] DCF Model
2,Ticker: [XXX] | Date: [Date] | Year End: [FYE]
3,Blank
4,Case Selector Cell (1=Bear 2=Base 3=Bull)
5,Case Name Display (formula: =IF([Selector]=1"Bear"IF([Selector]=2"Base""Bull")))
第 2 部分:市场数据(不依赖情景)
Item,Value
Current Stock Price,$XX.XX
Shares Outstanding (M),XX.X
Market Cap ($M),[Formula]
Net Debt ($M),XXX [or Net Cash if negative]
第 3 部分:DCF 情景假设
为每种情景(Bear、Base、Bull)分别创建假设区块,包含 DCF 专属假设(Revenue Growth %、EBIT Margin %、Tax Rate %、D&A % of Revenue、CapEx % of Revenue、NWC Change % of ΔRev、Terminal Growth Rate、WACC),并沿预测年份横向排列。每个区块必须包含节标题、显示预测年份(FY1、FY2 等)的列标题行,以及数据行。确切布局请参见 <correct_patterns> 部分中的“正确的假设表结构”。
第 4 部分:历史与预测财务数据
引用一个汇总列(例如“Selected Case”),从情景区块中提取数据,而不是在每个预测行中分散使用 IF 公式。
Income Statement ($M),2020A,2021A,2022A,2023A,2024E,2025E,2026E
Revenue,XXX,XXX,XXX,XXX,[=E29*(1+$E$10)],[=F29*(1+$E$11)],[=G29*(1+$E$12)]
% growth,XX%,XX%,XX%,XX%,[=E29/D29-1],[=F29/E29-1],[=G29/F29-1]
,,,,,,
Gross Profit,XXX,XXX,XXX,XXX,[=E29*E33],[=F29*F33],[=G29*G33]
% margin,XX%,XX%,XX%,XX%,[=E33/E29],[=F33/F29],[=G33/G29]
,,,,,,
Operating Expenses:,,,,,,,
S&M,XXX,XXX,XXX,XXX,[=E29*0.15],[=F29*0.14],[=G29*0.13]
R&D,XXX,XXX,XXX,XXX,[=E29*0.12],[=F29*0.11],[=G29*0.10]
G&A,XXX,XXX,XXX,XXX,[=E29*0.08],[=F29*0.07],[=G29*0.07]
Total OpEx,XXX,XXX,XXX,XXX,[=E36+E37+E38],[=F36+F37+F38],[=G36+G37+G38]
,,,,,,
EBIT,XXX,XXX,XXX,XXX,[=E33-E39],[=F33-F39],[=G33-G39]
% margin,XX%,XX%,XX%,XX%,[=E41/E29],[=F41/F29],[=G41/G29]
,,,,,,
Taxes,(XX),(XX),(XX),(XX),[=E41*$E$24],[=F41*$E$24],[=G41*$E$24]
Tax rate,XX%,XX%,XX%,XX%,[=E43/E41],[=F43/F41],[=G43/G41]
,,,,,,
NOPAT,XXX,XXX,XXX,XXX,[=E41-E43],[=F41-F43],[=G41-G43]
关键公式模式:
- Revenue growth:
=E29*(1+$E$10),其中 $E$10 是 Year 1 growth 的汇总列 - 不要使用:
=E29*(1+IF($B$6=1,$B$10,IF($B$6=2,$C$10,$D$10)))
这种方法更简洁、更易审计,并通过集中管理情景逻辑来避免公式错误。
第 5 部分:自由现金流构建
重要:确认行引用指向正确的假设行。创建公式后立即测试。
Cash Flow ($M),2020A,2021A,2022A,2023A,2024E,2025E,2026E
NOPAT,XXX,XXX,XXX,XXX,[=E45],[=F45],[=G45]
(+) D&A,XXX,XXX,XXX,XXX,[=E29*$E$21],[=F29*$E$21],[=G29*$E$21]
% of Rev,XX%,XX%,XX%,XX%,[=E58/E29],[=F58/F29],[=G58/G29]
(-) CapEx,(XX),(XX),(XX),(XX),[=E29*$E$22],[=F29*$E$22],[=G29*$E$22]
% of Rev,XX%,XX%,XX%,XX%,[=E60/E29],[=F60/F29],[=G60/G29]
(-) Δ NWC,(XX),(XX),(XX),(XX),[=(E29-D29)*$E$23],[=(F29-E29)*$E$23],[=(G29-F29)*$E$23]
% of Δ Rev,XX%,XX%,XX%,XX%,[=E62/(E29-D29)],[=F62/(F29-E29)],[=G62/(G29-F29)]
,,,,,,
Unlevered FCF,XXX,XXX,XXX,XXX,[=E57+E58-E60-E62],[=F57+F58-F60-F62],[=G57+G58-G60-G62]
行引用示例(基于布局规划):
- $E$21 = D&A % 假设(汇总列,第 21 行)
- $E$22 = CapEx % 假设(汇总列,第 22 行)
- $E$23 = NWC % 假设(汇总列,第 23 行)
- E29 = 当年 Revenue(第 29 行)
- E45 = 当年 NOPAT(第 45 行)
编写公式前:确认这些行号与实际布局一致。先测试一列,再向右复制。
第 6 部分:折现与估值
DCF Valuation,2024E,2025E,2026E,2027E,2028E,Terminal
Unlevered FCF ($M),XXX,XXX,XXX,XXX,XXX,
Period,0.5,1.5,2.5,3.5,4.5,
Discount Factor,0.XX,0.XX,0.XX,0.XX,0.XX,
PV of FCF ($M),XXX,XXX,XXX,XXX,XXX,
,,,,,,
Terminal FCF ($M),,,,,,,XXX
Terminal Value ($M),,,,,,,XXX
PV Terminal Value ($M),,,,,,,XXX
,,,,,,
Valuation Summary ($M),,,,,,
Sum of PV FCFs,XXX,,,,,
PV Terminal Value,XXX,,,,,
Enterprise Value,XXX,,,,,
(-) Net Debt,(XX),,,,,
Equity Value,XXX,,,,,
,,,,,,
Shares Outstanding (M),XX.X,,,,,
IMPLIED PRICE PER SHARE,$XX.XX,,,,,
Current Stock Price,$XX.XX,,,,,
Implied Upside/(Downside),XX%,,,,,
WACC 工作表结构
COST OF EQUITY CALCULATION,,
Risk-Free Rate (10Y Treasury),X.XX%,[Yellow input]
Beta (5Y monthly),X.XX,[Yellow input]
Equity Risk Premium,X.XX%,[Yellow input]
Cost of Equity,X.XX%,[Calculated blue]
,,
COST OF DEBT CALCULATION,,
Credit Rating,AA-,[Yellow input]
Pre-Tax Cost of Debt,X.XX%,[Yellow input]
Tax Rate,XX.X%,[Link to DCF sheet]
After-Tax Cost of Debt,X.XX%,[Calculated blue]
,,
CAPITAL STRUCTURE,,
Current Stock Price,$XX.XX,[Link to DCF]
Shares Outstanding (M),XX.X,[Link to DCF]
Market Capitalization ($M),"X,XXX",[Calculated]
,,
Total Debt ($M),XXX,[Yellow input]
Cash & Equivalents ($M),XXX,[Yellow input]
Net Debt ($M),XXX,[Calculated]
,,
Enterprise Value ($M),"X,XXX",[Calculated]
,,
WACC CALCULATION,Weight,Cost,Contribution
Equity,XX.X%,X.X%,X.XX%
Debt,XX.X%,X.X%,X.XX%
,,
WEIGHTED AVERAGE COST OF CAPITAL,X.XX%,[Green output]
关键 WACC 公式:
Market Cap = Price × Shares
Net Debt = Total Debt - Cash
Enterprise Value = Market Cap + Net Debt
Equity Weight = Market Cap / EV
Debt Weight = Net Debt / EV
WACC = (Cost of Equity × Equity Weight) + (After-tax Cost of Debt × Debt Weight)
敏感性分析(DCF 工作表底部)
术语提醒:“敏感性表”是指带有行标题、列标题且每个数据单元格都包含公式的简单二维网格。不是 Excel 的“数据表”功能(数据 → 模拟分析 → 数据表)。你将使用 openpyxl 在每个单元格中写入常规 Excel 公式。
位置:DCF 工作表第 87 行及之后(不是单独的工作表)
三个纵向堆叠的敏感性表:
- WACC vs Terminal Growth(第 87-100 行)- 5x5 网格 = 25 个含公式的单元格
- Revenue Growth vs EBIT Margin(第 102-115 行)- 5x5 网格 = 25 个含公式的单元格
- Beta vs Risk-Free Rate(第 117-130 行)- 5x5 网格 = 25 个含公式的单元格
需要写入的公式总数:75(必须完成,不可选)
重要:必须使用 openpyxl 以编程方式为所有敏感性表单元格填入公式。不要使用线性近似捷径。不要留下占位文本或关于手动步骤的说明。不要以“太复杂”为由让单元格留空——使用 Python 循环生成公式。
表格设置:
- 创建包含行标题/列标题(待测试的假设值)的表格结构
- 为每个数据单元格填入公式,该公式:
- 使用行标题值(例如 WACC = 9.0%)
- 使用列标题值(例如 Terminal Growth = 3.0%)
- 使用这些特定假设重新计算完整 DCF
- 返回该情景下的隐含股价
- 交付时,所有单元格都必须包含可运行的公式
- 使用条件格式设置单元格:较高值使用绿色渐变,较低值使用红色渐变
- 将基准情景单元格设为粗体
- 表格之间留出 1-2 行空白
无需手动干预——用户打开文件时,敏感性表必须完全可用。
情景选择器实现
三情景框架:
Bear 情景
- 保守的 Revenue growth(处于历史区间低端)
- 利润率收缩或不扩张
- 更高的 WACC(风险溢价上升)
- 更低的终值增长率
- 更高的 CapEx 假设
基础情景
- 共识预测或管理层指引中的收入增长率
- 基于经营杠杆的适度利润率扩张
- 当前市场隐含的 WACC
- 与 GDP 持平的终值增长率(2.5-3.0%)
- 标准 CapEx 假设
乐观情景
- 乐观的收入增长率(预测区间上限)
- 显著的利润率扩张
- 较低的 WACC(风险溢价降低)
- 较高的终值增长率(3.5-5.0%)
- 较低的 CapEx 强度
公式实现:
不要在各处散布嵌套 IF 公式。 而应创建一个汇总列,使用 INDEX 或 OFFSET 公式从相应的情景区域提取数值。
推荐模式(使用 INDEX):
=INDEX(B10:D10, 1, $B$6),其中 B10:D10 = Bear/Base/Bull 数值,1 = 行偏移量,$B$6 = 情景选择器单元格(1、2 或 3)
然后在所有预测中引用汇总列:
Revenue Year 1: =D29*(1+$E$10),其中 $E$10 是第 1 年增长率的汇总列数值。
这种方法将情景逻辑集中管理,使模型更易于审计和维护。
交付内容结构
文件命名:[Ticker]_DCF_Model_[Date].xlsx
两个工作表:
- DCF - 完整模型,包含 Bear/Base/Bull 情景,以及底部的三个敏感性分析表(WACC 与终值增长率、收入增长率与 EBIT 利润率、Beta 与无风险利率)
- WACC - 资本成本计算
主要特性:情景选择器(1/2/3)、使用 INDEX/OFFSET 公式的汇总列、颜色编码的单元格、所有输入项均添加单元格批注、专业边框
最佳实践
模型构建
- 循序渐进地构建:完成每个部分后再继续下一部分
- 边构建边测试:输入示例数字以验证公式
- 采用一致的结构:相似的计算遵循相似的模式
- 为复杂公式添加批注:为特殊计算添加说明
- 加入检查项:在适用时添加求和检查和余额检查
文档编写
- 记录所有假设:说明关键输入项的依据
- 注明数据来源:记录每个数据点的来源
- 解释方法:描述任何非标准方法
- 标记不确定性:突出显示可见性有限的部分
质量控制
- 交叉核对计算:通过多种方式验证计算结果
- 对假设进行压力测试:运行敏感性分析,确保模型稳健
- 同行评审:请其他人检查公式
- 版本控制:随着工作推进保存不同版本
常见变体
高增长科技公司
- 延长预测期(7-10 年)
- 较高的初始增长率(20-30%)
- 利润率随时间显著扩张
- 较高的 WACC(12-15%)
- 对单位经济效益建模(用户数、ARPU 等)
成熟/稳定公司
- 缩短预测期(3-5 年)
- 温和的增长率(GDP +1-3%)
- 利润率稳定
- 较低的 WACC(7-9%)
- 重点关注现金创造和资本配置
周期性公司
- 按经济周期进行建模
- 将利润率标准化至周期中值
- 考虑低谷和峰值情景
- 根据周期性调整 Beta
多业务板块公司
- 为每个业务部门单独建立 DCF
- 根据业务板块采用不同的增长率和利润率
- 采用分部加总估值法
- 考虑协同效应
故障排查
如果遇到错误或不合理的结果,请阅读 TROUBLESHOOTING.md 获取详细的调试指南。
工作流集成
开始构建 DCF 时
-
收集市场数据:
- 查看是否有可用的 MCP 服务提供当前市场数据
- 使用网络搜索/获取工具查询股价、Beta 和其他市场指标
- 如果需要特定数据,请向用户索取
-
收集历史财务数据:
- 查看是否有可用的 MCP 服务(Daloopa 等)
- 如果无法通过 MCP 获取,请向用户索取
- 如有必要,手动从 10-K 文件中提取
-
使用本技能中详细说明的 DCF 方法开始构建模型
构建模型期间
- 使用 openpyxl 构建 Excel 模型,并使用公式(而非硬编码值)
- 遵循 xlsx 技能规范来编写公式和设置格式
- 仅在用户要求或提供了具体品牌指南时应用填充颜色
交付模型前(必须)
-
验证结构:
- Bear/Base/Bull 情景区块包含覆盖各预测年度的假设
- 情景选择器可正常使用,公式引用正确的情景区块
- 敏感性分析表位于 DCF 工作表底部(而非单独的工作表)
- 字体颜色:蓝色表示输入值,黑色表示公式,绿色表示工作表链接
- 所有硬编码输入值的单元格均添加批注
- 主要区块使用专业边框
-
重新计算公式:运行
python recalc.py model.xlsx 30 -
检查输出:
- 如果
status为"success"→ 继续执行第 4 步 - 如果
status为"errors_found"→ 检查error_summary,并阅读 TROUBLESHOOTING.md 获取调试指南
- 如果
-
修复错误并重新运行 recalc.py,直到状态为 "success"
-
抽查公式:
- 测试一个 FCF 公式——它是否引用了正确的假设行?
- 更改情景选择器——合并列是否正确更新?
- 确认收入公式引用的是合并列(而非嵌套 IF 公式)
-
交付模型
可用数据源
- MCP 服务:如果已配置(Daloopa 用于历史财务数据)
- 网页搜索/抓取:获取当前股价、Beta 和市场数据
- 用户提供的数据:历史财务数据、市场一致预期
- 手动提取:SEC EDGAR 文件(备用方案)
最终输出检查清单
交付 DCF 模型前:
必需项:
- 运行
python recalc.py model.xlsx 30,直到状态为 "success"(公式错误数为零) - 两个工作表:DCF(底部包含敏感性分析)、WACC
- 字体颜色:蓝色 = 输入值,黑色 = 公式,绿色 = 工作表链接
- 所有硬编码输入值的单元格均添加批注
- 敏感性分析表中的公式均已填充
- 主要区块使用专业边框
验证:
- OpEx 基于收入计算(而非毛利润)
- 终值占 EV 的 50-70%
- 终值增长率 < WACC
- 税率为 21-28%
- 文件命名:
[Ticker]_DCF_Model_[Date].xlsx