dcf-model by anthropics/financial-services-plugins
npx skills add https://github.com/anthropics/financial-services-plugins --skill dcf-model此技能遵循投行标准,为股权估值创建机构级的 DCF 模型。每次分析都会生成一个详细的 Excel 模型(DCF 工作表底部包含敏感性分析)。
这些约束适用于所有 DCF 模型构建过程。开始前请仔细阅读:
敏感性表格:
单元格批注:
模型布局规划:
公式重算:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
python recalc.py model.xlsx 30情景区块:
=IF($B$6=1,[熊市单元格],IF($B$6=2,[基准单元格],[牛市单元格]))从 MCP 服务器、用户提供的数据和网络获取数据。
数据源优先级:
验证清单:
分析并记录:
创建汇总表显示:
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%
方法论:
增长率框架:
公式结构:
三情景方法:
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%)
固定/可变成本分析:
运营费用应模拟现实的运营杠杆:
关键原则:
利润率扩张框架:
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)
按正确顺序构建自由现金流:
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
营运资本建模:
维持性资本支出与增长性资本支出:
股权成本的资本资产定价模型方法:
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)
特殊情况:
典型的加权平均资本成本范围:
年中惯例:
现值计算:
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
预测期选择:
永续增长法(首选):
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)
终值增长率选择:
不得超过:无风险利率或长期 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
终值合理性检查:
估值摘要结构:
(+) 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%
关键调整:
估值输出格式:
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%
在 DCF 工作表底部构建三个敏感性表格,显示估值如何随不同假设变化:
实现:这些是简单的二维网格(不是 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 等)。没有这个,用户无法分辨哪个假设值对应哪个年份。
如何引用假设 - 创建一个汇总列:
推荐的汇总列模式(使用 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 - 第 1 年增长率的汇总列: =INDEX([Bear FY1 growth]:[Bull FY1 growth], 1, $B$6)
步骤 2 - 收入预测引用汇总列: Revenue Year 1: =D29*(1+$E$10)
其中:
这种方法比在每个预测公式中嵌入 IF 语句更清晰,并且使审计正在使用哪个情景假设变得容易得多。
使用带有 INDEX 公式的汇总列,然后在自由现金流计算中引用它们:
汇总列方法:
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 公式,该公式根据情景选择器从适当的情景区块中提取。这使预测公式保持清晰且易于审计。
在编写公式之前,确认情景区块的行位置并设置汇总列。
每个硬编码值都需要此格式:
"来源:[系统/文档],[日期],[参考],[URL(如适用)]"
示例:
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(加权平均资本成本=8.0%,终值增长率=2.0%):
B88 中的公式应使用以下内容重新计算隐含价格:
$A88 (8.0%)B$87 (2.0%)推荐方法: 引用主要的 DCF 计算,但替换这些值。
示例公式结构: =([使用 $A88 作为折现率的 PV FCFs 之和] + [使用 B$87 作为增长率和 $A88 作为加权平均资本成本的终值] - [净债务]) / [股数]
关键 - 为 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"]
不要混淆术语:
为什么这些捷径是错误的:
需要拒绝的常见合理化理由: "编写 75 多个公式感觉很复杂,所以我会给用户留个便条让他们手动完成。"
现实情况: 当您在 Python 中使用 openpyxl 循环时,编写 75 个公式很简单。每个公式都遵循相同的模式 - 只需替换行/列值。这是交付物的必需部分。
正确做法: 用公式填充每个敏感性单元格,这些公式针对该特定假设组合重新计算完整的 DCF
不要这样做:
为什么这是错误的:
正确做法: 在创建每个硬编码值时添加单元格批注
症状: 自由现金流部分引用了错误的假设行:D&A: =E29*$E$34 // 应该是 $E$21,但引用了错误的行 CapEx: =E29*$E$41 // 应该是 $E$22,但行偏移了
为什么会发生这种情况:
正确做法: 首先锁定行布局,然后写入公式
不要像这样构建假设:
Assumption,Bear,Base,Bull
Revenue Growth FY1,10%,13%,16%
Revenue Growth FY2,9%,12%,15%
这种垂直布局使得很难看到每个情景内跨年份的进展。
为什么这是错误的:
正确做法:
不要交付没有边框的模型:
为什么这是错误的:
正确做法: 在所有主要部分周围添加边框
不要这样做:
为什么这是错误的:
正确做法: 所有硬编码输入用蓝色文本,所有公式用黑色文本,工作表链接用绿色
不要这样做: S&M: =E33*0.15 // E33 = 毛利润(错误)
为什么这是错误的:
正确做法: S&M: =E29*0.15 // E29 = 收入(正确)
此外,请注意这些错误:
这些是最常见的错误。在开始任何 DCF 构建之前,请重新阅读本节。
</common_mistakes>
此技能使用 xlsx 技能进行所有电子表格操作。 xlsx 技能提供:
recalc.py 脚本自动公式重算此技能创建的所有 Excel 文件必须遵循 xlsx 技能要求,包括零公式错误和正确的重算。
每个 DCF 模型必须最大化以下方面:
创建两个工作表:
关键:敏感性表格放在 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
该脚本将:
预期输出格式:
{
"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 技能的强制要求)
第 2 层:填充颜色(用于增强呈现的可选项)
两层如何协同工作(如果使用填充颜色):
字体颜色告诉您它是什么。填充颜色告诉您它在哪里(如果使用)。
重要提示: 来自 xlsx 技能的字体颜色是强制性的。填充颜色是可选的 - 除非用户请求增强格式或颜色,否则默认为白色/无填充。
粗边框(1.5pt)围绕主要部分:
中等边框(1pt)在子部分之间:
细边框(0.5pt)围绕数据表:
无边框: 表格内的单个单元格(保持清晰、可扫描)
边框是强制性的 - 没有专业边框的模型不符合客户就绪标准。
数字格式(遵循 xlsx 技能标准):
0.0%(一位小数)$#,##0 表示百万;$#,##0.00 表示每股 - 始终在标题中指定单位("收入(百万美元)")$#,##0;($#,##0);-)#,##0 带千位分隔符(#,##0) 在括号内(不是减号)单元格批注(所有硬编码输入的强制要求):
根据 xlsx 技能,所有硬编码值必须有单元格
This skill creates institutional-quality DCF models for equity valuation following investment banking standards. Each analysis produces a detailed Excel model (with sensitivity analysis included at the bottom of the DCF sheet).
These constraints apply throughout all DCF model building. Review before starting:
Sensitivity Tables:
Cell Comments:
Model Layout Planning:
Formula Recalculation:
python recalc.py model.xlsx 30 before deliveryScenario Blocks:
=IF($B$6=1,[Bear cell],IF($B$6=2,[Base cell],[Bull cell]))Fetch data from MCP servers, user provided data, and the web.
Data Sources Priority:
Validation Checklist:
Analyze and document:
Create summary tables showing:
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%
Methodology:
Growth Rate Framework:
Formula structure:
Three-scenario approach:
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%)
Fixed/Variable Cost Analysis:
Operating expenses should model realistic operating leverage:
Key principles:
Margin expansion framework:
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)
Build FCF in proper sequence:
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
Working Capital Modeling:
Maintenance vs Growth CapEx:
CAPM Methodology for Cost of Equity:
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)
Cost of Debt Calculation:
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
Capital Structure Weights:
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)
Special Cases:
Typical WACC Ranges:
Mid-Year Convention:
Present Value Calculation:
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
Projection Period Selection:
Perpetuity Growth Method (Preferred):
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)
Terminal Growth Rate Selection:
Do not exceed : Risk-free rate or long-term GDP growth
Exit Multiple Method (Alternative):
Terminal Value = Final Year EBITDA × Exit Multiple
Where Exit Multiple comes from:
- Industry comparable trading multiples
- Precedent transaction multiples
- Typical range: 8-15x EBITDA
Present Value of Terminal Value:
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
Terminal Value Sanity Check:
Valuation Summary Structure:
(+) 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%
Critical Adjustments:
Valuation Output Format:
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%
Build three sensitivity tables at the bottom of the DCF sheet showing how valuation changes with different assumptions:
Implementation : These are simple 2D grids (NOT Excel's "Data Table" feature) with formulas in each cell. Each cell must contain a full DCF recalculation for that specific assumption combination. See Critical Constraints section for detailed requirements on populating all 75 cells programmatically using openpyxl.
<correct_patterns>
This section contains all the CORRECT patterns to follow when building DCF models.
Assumptions are organized in separate blocks for each scenario:
CRITICAL STRUCTURE - Three rows per section header:
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%
Each scenario block MUST have a column header row showing the projection years (FY2025E, FY2026E, etc.) immediately below the section title. Without this, users cannot tell which assumption value corresponds to which year.
How to reference assumptions - Create a consolidation column:
Recommended consolidation column pattern (using INDEX): =INDEX(B10:D10, 1, $B$6)
NOT this - scattered IF statements throughout: =IF($B$6=1,[Bear block cell],IF($B$6=2,[Base block cell],[Bull block cell]))
The consolidation column approach centralizes logic and makes the model easier to audit.
Create a consolidation column with INDEX formulas, then reference it in projections:
Step 1 - Consolidation column for FY1 growth: =INDEX([Bear FY1 growth]:[Bull FY1 growth], 1, $B$6)
Step 2 - Revenue projection references the consolidation column: Revenue Year 1: =D29*(1+$E$10)
Where:
This approach is cleaner than embedding IF statements in every projection formula and makes it much easier to audit which scenario assumptions are being used.
Use consolidation columns with INDEX formulas, then reference them in FCF calculations:
Consolidation column approach:
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
Each consolidation column cell contains an INDEX formula that pulls from the appropriate scenario block based on case selector. This keeps projection formulas clean and auditable.
Before writing formulas, confirm scenario block row locations and set up consolidation columns.
Every hardcoded value needs this format:
"Source: [System/Document], [Date], [Reference], [URL if applicable]"
Examples:
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
CRITICAL: Each scenario block requires THREE structural elements:
Structure:
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%,,,,
WITHOUT the column header row showing projection years (FY2025E, FY2026E, etc.), users cannot tell which assumption value corresponds to which year. This row is MANDATORY.
Then create a consolidation column (typically the next column to the right) that uses INDEX formulas to pull from the selected scenario block based on the case selector. This consolidation column is what your projection formulas reference.
1. Write ALL headers and labels FIRST:
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. Write ALL section dividers and blank rows
3. THEN write formulas using the locked row positions
4. Test formulas immediately after creation
Think of it like construction:
Excel version:
IMPORTANT : These are NOT Excel's "Data Table" feature. These are simple grids where you write regular formulas using openpyxl. Yes, this means ~75 formulas total (3 tables × 25 cells each), but this is straightforward and required.
Programmatic Population with Formulas:
Each sensitivity table must be fully populated with formulas that recalculate the implied share price for each combination of assumptions. Do not use Excel's Data Table feature (it requires manual intervention and cannot be automated via openpyxl).
Implementation approach - CONCRETE EXAMPLE:
Table Structure (5x5 grid):
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]
...,...,...,...,...,...
Formula Pattern - Cell B88 (WACC=8.0%, Terminal Growth=2.0%):
The formula in B88 should recalculate the implied price using:
$A88 (8.0%)B$87 (2.0%)Recommended approach: Reference the main DCF calculation but substitute these values.
Example formula structure: =([SUM of PV FCFs using $A88 as discount rate] + [Terminal Value using B$87 as growth rate and $A88 as WACC] - [Net Debt]) / [Shares]
CRITICAL - Write a formula for EVERY cell in the 5x5 grid (25 cells per table, 75 cells total). Use openpyxl to write these formulas programmatically in a loop. Do NOT skip this step or leave placeholder text.
Python implementation pattern:
# 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
The sensitivity tables must work immediately when the model is opened, with no manual steps required from the user.
</correct_patterns>
<common_mistakes>
This section contains all the WRONG patterns to avoid when building DCF models.
Don't use linear approximations:
// 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
Don't leave placeholder text:
// 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"]
Don't confuse terminology:
Why these shortcuts are wrong:
Common rationalization to REJECT: "Writing 75+ formulas feels complex, so I'll leave a note for the user to complete it manually."
Reality: Writing 75 formulas is straightforward when you use a loop in Python with openpyxl. Each formula follows the same pattern - just substitute the row/column values. This is a required part of the deliverable.
Instead: Populate every sensitivity cell with formulas that recalculate the full DCF for that specific combination of assumptions
Don't do this:
Why it's wrong:
Instead: Add cell comment AS EACH hardcoded value is created
Symptom: The FCF section references wrong assumption rows: D&A: =E29*$E$34 // Should be $E$21, but referencing wrong row CapEx: =E29*$E$41 // Should be $E$22, but row shifted
Why this happens:
Instead: Lock row layout FIRST, then write formulas
Don't structure assumptions like this:
Assumption,Bear,Base,Bull
Revenue Growth FY1,10%,13%,16%
Revenue Growth FY2,9%,12%,15%
This vertical layout makes it hard to see the progression across years within each scenario.
Why it's wrong:
Instead:
Don't deliver a model without borders:
Why it's wrong:
Instead: Add borders around all major sections
Don't do this:
Why it's wrong:
Instead: Blue text for ALL hardcoded inputs, black text for ALL formulas, green for sheet links
Don't do this: S&M: =E33*0.15 // E33 = Gross Profit (WRONG)
Why it's wrong:
Instead: S&M: =E29*0.15 // E29 = Revenue (CORRECT)
In addition, be aware of these errors:
These errors are the most common. Re-read this section before starting any DCF build.
</common_mistakes>
This skill uses thexlsx skill for all spreadsheet operations. The xlsx skill provides:
recalc.py scriptAll Excel files created by this skill must follow xlsx skill requirements, including zero formula errors and proper recalculation.
Every DCF model must maximize for:
Create two sheets :
CRITICAL : Sensitivity tables go at the BOTTOM of the DCF sheet (not on a separate sheet). This keeps all valuation outputs together.
After creating or modifying the Excel model, recalculate all formulas using the recalc.py script from the xlsx skill:
python recalc.py [path_to_excel_file] [timeout_seconds]
Example:
python recalc.py AAPL_DCF_Model_2025-10-12.xlsx 30
The script will:
Expected output format:
{
"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
}
If errors are found , the output will include details:
{
"status": "errors_found",
"total_errors": 2,
"total_formulas": 42,
"error_summary": {
"#REF!": {
"count": 2,
"locations": ["DCF!B25", "DCF!C25"]
}
}
}
Fix all errors and re-run recalc.py until status is "success" before delivering the model.
IMPORTANT : Follow the xlsx skill for formula construction rules and number formatting conventions. The DCF skill adds specific visual presentation standards.
Color Scheme - Two Layers :
Layer 1: Font Colors (MANDATORY from xlsx skill)
Layer 2: Fill Colors (Optional for enhanced presentation)
How the layers work together (if fill colors are used):
Font color tells you WHAT it is. Fill color tells you WHERE it is (if used).
IMPORTANT: Font colors from xlsx skill are mandatory. Fill colors are optional - default is white/no fill unless the user requests enhanced formatting or colors.
Thick borders (1.5pt) around major sections:
Medium borders (1pt) between sub-sections:
Thin borders (0.5pt) around data tables:
No borders: Individual cells within tables (keep clean, scannable)
Borders are mandatory - models without professional borders are not client-ready.
Number Formats (follows xlsx skill standards):
0.0% (one decimal place)$#,##0 for millions; $#,##0.00 for per-share - ALWAYS specify units in headers ("Revenue ($mm)")$#,##0;($#,##0);-)#,##0 with thousands separator(#,##0) in parentheses (NOT minus sign)Cell Comments (MANDATORY for all hardcoded inputs) :
Per the xlsx skill, ALL hardcoded values must have cell comments documenting the source. Format: "Source: [System/Document], [Date], [Reference], [URL if applicable]"
CRITICAL : Add comments AS CELLS ARE CREATED. Do not defer to the end.
Section 1: Header
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")))
Section 2: Market Data (NOT case dependent)
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]
Section 3: DCF Scenario Assumptions
Create separate assumption blocks for each scenario (Bear, Base, Bull) with DCF-specific assumptions (Revenue Growth %, EBIT Margin %, Tax Rate %, D&A % of Revenue, CapEx % of Revenue, NWC Change % of ΔRev, Terminal Growth Rate, WACC) laid out horizontally across projection years. Each block must include section header, column header row showing the projection years (FY1, FY2, etc.), and data rows. See <correct_patterns> section "Correct Assumption Table Structure" for the exact layout.
Section 4: Historical & Projected Financials
Reference a consolidation column (e.g., "Selected Case") that pulls from scenario blocks , not scattered IF formulas in every projection row.
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]
Key Formula Pattern :
=E29*(1+$E$10) where $E$10 is consolidation column for Year 1 growth=E29*(1+IF($B$6=1,$B$10,IF($B$6=2,$C$10,$D$10)))This approach is cleaner, easier to audit, and prevents formula errors by centralizing the scenario logic.
Section 5: Free Cash Flow Build
CRITICAL : Verify row references point to the CORRECT assumption rows. Test formulas immediately after creation.
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]
Row reference examples (based on layout planning):
Before writing formulas : Confirm these row numbers match the actual layout. Test one column, then copy across.
Section 6: Discounting & Valuation
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%,,,,,
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]
Key WACC Formulas:
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)
TERMINOLOGY REMINDER : "Sensitivity tables" = simple 2D grids with row headers, column headers, and formulas in each data cell. NOT Excel's "Data Table" feature (Data → What-If Analysis → Data Table). You will use openpyxl to write regular Excel formulas into each cell.
Location : Rows 87+ on DCF sheet (NOT a separate sheet)
Three sensitivity tables, vertically stacked:
Total formulas to write: 75 (this is required, not optional)
CRITICAL : All sensitivity table cells must be populated programmatically with formulas using openpyxl. DO NOT use linear approximation shortcuts. DO NOT leave placeholder text or notes about manual steps. DO NOT rationalize leaving cells empty because "it's complex" - use a Python loop to generate the formulas.
Table Setup:
No manual intervention required - the sensitivity tables must be fully functional when the user opens the file.
Three-Case Framework:
Formula Implementation:
DO NOT use nested IF formulas scattered throughout. Instead, create a consolidation column that uses INDEX or OFFSET formulas to pull from the appropriate scenario block.
Recommended pattern (using INDEX): =INDEX(B10:D10, 1, $B$6) where B10:D10 = Bear/Base/Bull values, 1 = row offset, $B$6 = case selector cell (1, 2, or 3)
Then reference the consolidation column in all projections: Revenue Year 1: =D29*(1+$E$10) where $E$10 is the consolidation column value for Year 1 growth.
This approach centralizes scenario logic, making the model easier to audit and maintain.
File naming : [Ticker]_DCF_Model_[Date].xlsx
Two sheets :
Key features : Case selector (1/2/3), consolidation column with INDEX/OFFSET formulas, color-coded cells, cell comments on all inputs, professional borders
If you encounter errors or unreasonable results, readTROUBLESHOOTING.md for detailed debugging guidance.
Gather market data :
Gather historical financials :
Begin model construction using the DCF methodology detailed in this skill
Verify structure :
Recalculate formulas : Run python recalc.py model.xlsx 30
Check output :
status is "success" → Continue to step 4status is "errors_found" → Check error_summary and read TROUBLESHOOTING.md for debugging guidanceBefore delivering DCF model:
Required:
python recalc.py model.xlsx 30 until status is "success" (zero formula errors)Validation:
[Ticker]_DCF_Model_[Date].xlsxWeekly Installs
72
Repository
GitHub Stars
5.6K
First Seen
13 days ago
Security Audits
Gen Agent Trust HubPassSocketWarnSnykWarn
Installed on
gemini-cli71
amp71
github-copilot71
codex71
kimi-cli71
opencode71
Python PDF处理教程:合并拆分、提取文本表格、创建PDF文件
58,600 周安装
OpenAI API 完整文档技能 - 官方文档集成与智能问答助手
1 周安装
Next.js 官方文档中文指南 - 从入门到精通,掌握App Router、数据获取与性能优化
1 周安装
Hono 框架中文文档 | 轻量级 Web 框架,支持 Bun、Deno、Cloudflare Workers
1 周安装
Express.js 全面中文文档与 API 参考 | 涵盖安全漏洞、性能优化与迁移指南
1 周安装
Drizzle ORM 完整文档 | 无头 ORM 与类 SQL 查询指南
1 周安装
Cortex 文档大全 | 集成指南与 API 参考 | 涵盖 FireHydrant、ServiceNow、Datadog 等
1 周安装
Fix errors and re-run recalc.py until status is "success"
Spot-check formulas :
Deliver model