mcpField
C
company-valuation

company-valuation

github.com/himself65数据与数据库3.5k3.3k 次安装3 天前更新
代码仓库

关于 company-valuation

company-valuation 是用于分析公司隐含股价的技能,通过 DCF、同业倍数及适用时的 SOTP 进行交叉估值,并提供敏感性和情景分析。

主要功能

  1. 01五年 FCFF 预测与 DCF
  2. 02同业倍数相对估值
  3. 03多业务分部公司的 SOTP
  4. 04WACC 与终值增长率敏感性分析
  5. 05看涨、基准与看跌情景

适用场景

  1. 01估算公司的隐含股价
  2. 02比较公司与同业的估值
  3. 03评估估值对假设变化的敏感度

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/himself65/finance-skills --skill company-valuation

安装后在 Claude Code 中输入/company-valuation确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
dcf.md
relative_valuation.md
sotp.md
wacc_erp_rates.md

详细介绍

公司估值

如果你的宿主环境尚未执行以下 shell 探测命令(例如在 Codex 中),请先使用其 shell 工具运行 ! 包裹的命令,再选择设置路径。请使用实际输出;如果无法访问 shell,请说明这一限制。

通过三种方法交叉验证内在价值,再将结果融合为隐含股价:

  1. DCF — 预测 5 年 FCFF,按 WACC 折现,并计算终值。
  2. 相对估值 — 应用同行公司的 P/E、EV/Revenue、EV/EBITDA 中位数。
  3. SOTP — 存在 2 个或更多独立报告分部时,按各分部的纯业务同行倍数估值。

务必提供 WACC × 终值增长率敏感性表,以及看涨/基准/看跌情景。

免责声明:仅用于研究和教育,不构成财务建议。


步骤 1:检测流程

检测数据源和运行时依赖项。该技能支持 2 种方法路径——选择可用的最完整路径。

环境状态:

!`python3 -c "exec('try:\n import yfinance, numpy, pandas\n print(\'YFIN_OK\')\nexcept Exception:\n print(\'YFIN_MISSING\')')"`
!`python3 -c "exec('try:\n import yfinance as yf\n t=yf.Ticker(\'^TNX\')\n p=t.fast_info.last_price\n print(f\'RF_10Y={p/100:.4f}\')\nexcept Exception:\n print(\'RF_FETCH_FAIL\')')"`

决策树:

条件方法路径
YFIN_OK路径 A(主要路径):使用 yfinance 获取财务数据和同行倍数
YFIN_MISSING路径 B:安装 yfinance,然后使用路径 A。python3 -m pip install -q yfinance numpy pandas
RF_FETCH_FAIL使用默认值 rf = 0.045,并在输出中注明无风险利率可能已过时

如果输出了 RF_10Y=,请在步骤 4d 中使用该值作为 rf,而不是硬编码的 4.5%。


步骤 2:选择方法并设置默认值

方法适用性
公司类型DCF相对估值SOTP备用方案
成熟型现金流业务(CPG、电信、公用事业)✅ 主要方法✅❌—
高增长 SaaS / 软件✅ 谨慎使用✅ 主要方法❌使用 EV/Revenue + Rule of 40
多分部企业集团✅✅✅ 主要方法参见 references/sotp.md
银行 / 保险❌✅(P/B、P/TBV)❌DDM 或超额收益法;在输出中注明
尚未产生收入❌仅 EV/Revenue❌标记为低置信度
REITs❌✅(P/FFO、P/AFFO)❌基于 NAV
周期性行业(能源、半导体、工业)✅ 基于中周期水平✅有时按完整周期进行标准化
默认值表

提取数据前,先确定每个参数——除非用户另有指定,否则使用以下默认值。

参数默认值理由
预测期限5 年标准的明确预测期
终值增长率 g2.5%约等于美国长期 GDP 增速
无风险利率 rf步骤 1 中的实时 10Y UST,否则为 4.5%当前资本成本基准
股权风险溢价 erp5.5%Damodaran 中间区间
Beta来自 yfinance 的 info['beta']市场观察到的杠杆 Beta
债务成本 kdinterest_expense / total_debt,否则为 5.5%实际利率;备用值基于投资级债券利差
税率过去 3 年实际税率的中位数,下限 15%,上限 30%剔除一次性因素的影响
利润率假设各项比率过去 3 年的中位数平滑周期性波动
SBC 处理方式软件/SaaS 视为现金成本;工业/CPG 视为非现金成本行业惯例
同行数量4-6 家平衡信号与噪声
同行倍数中位数(而非均值)降低异常值的影响
方法权重(不含 SOTP)DCF 50% / 相对估值 50%等权交叉验证
方法权重(含 SOTP)DCF 40% / 相对估值 30% / SOTP 30%适用时为 SOTP 分配权重
敏感性网格WACC ±1%,步长 0.5% × g 从 1.5-3.5%,步长 0.5%5×5 矩阵

当前无风险利率、ERP 表格和各行业 WACC 基准请参见 references/wacc_erp_rates.md。


步骤 3:获取数据

import yfinance as yf
import numpy as np
import pandas as pd

TICKER = "AAPL"  # replace
t = yf.Ticker(TICKER)

info       = t.info
income_a   = t.income_stmt
cashflow_a = t.cashflow
balance_a  = t.balance_sheet
income_q   = t.quarterly_income_stmt
cashflow_q = t.quarterly_cashflow

earnings_est = t.earnings_estimate
revenue_est  = t.revenue_estimate

price       = info.get("currentPrice") or info.get("regularMarketPrice")
market_cap  = info.get("marketCap")
shares_out  = info.get("sharesOutstanding")
total_debt  = info.get("totalDebt") or 0
cash        = info.get("totalCash") or 0
beta        = info.get("beta") or 1.0
sector      = info.get("sector")
industry    = info.get("industry")

关键财务报表项目(yfinance 标签):

需求项目
营收Total Revenue
EBITOperating Income
净利润Net Income
D&ADepreciation And Amortization(在现金流量表中)
资本支出Capital Expenditure(负值)
ΔNWCChange In Working Capital(现金流量表)
SBCStock Based Compensation(现金流量表)

第 4 步:构建 DCF

完整方法论和行业特定调整见 references/dcf.md。快速框架:

# 4a. Revenue growth path — fade from Y1 (consensus or hist CAGR) to terminal g
rev = income_a.loc["Total Revenue"].dropna().iloc[::-1].values  # yfinance columns are newest-first; reverse to oldest -> newest
hist_cagr = (rev[-1] / rev[0]) ** (1 / (len(rev)-1)) - 1
y1 = float(revenue_est.loc["+1y", "growth"]) if "+1y" in revenue_est.index else hist_cagr
g_terminal = 0.025
growth_path = np.linspace(y1, g_terminal + 0.01, 5)

# 4b. Margins — 3y median
ebit_margin = float((income_a.loc["Operating Income"] / income_a.loc["Total Revenue"]).iloc[:3].median())
da_pct      = float((cashflow_a.loc["Depreciation And Amortization"] / income_a.loc["Total Revenue"]).iloc[:3].median())
capex_pct   = float((cashflow_a.loc["Capital Expenditure"].abs() / income_a.loc["Total Revenue"]).iloc[:3].median())
nwc_pct     = float((cashflow_a.loc["Change In Working Capital"].abs() / income_a.loc["Total Revenue"]).iloc[:3].median())
eff_tax     = (income_a.loc["Tax Provision"] / income_a.loc["Pretax Income"]).iloc[:3].median()
tax_rate    = float(min(0.30, max(0.15, eff_tax))) if pd.notna(eff_tax) else 0.21  # 3y median effective, floored 15%, capped 30%

# 4c. FCFF per year
rev_t = [float(income_a.loc["Total Revenue"].iloc[0])]
fcff  = []
for g in growth_path:
    rev_t.append(rev_t[-1] * (1 + g))
    ebit = rev_t[-1] * ebit_margin
    nopat = ebit * (1 - tax_rate)
    fcff.append(nopat + rev_t[-1]*da_pct - rev_t[-1]*capex_pct - rev_t[-1]*nwc_pct)

# 4d. WACC
rf, erp, kd = 0.045, 0.055, 0.055  # override rf with live value from Step 1
ke = rf + beta * erp
e_v = market_cap / (market_cap + total_debt)
d_v = 1 - e_v
wacc = e_v*ke + d_v*kd*(1 - tax_rate)

# 4e. Terminal value — compute both, use midpoint
tv_gordon = fcff[-1] * (1 + g_terminal) / (wacc - g_terminal)
tv_exit   = (rev_t[-1] * ebit_margin + rev_t[-1] * da_pct) * 15  # peer median EV/EBITDA
tv_base   = 0.5 * (tv_gordon + tv_exit)

# 4f. Bridge to equity
pv_fcff = sum(f / (1+wacc)**(i+1) for i, f in enumerate(fcff))
pv_tv   = tv_base / (1+wacc)**5
ev      = pv_fcff + pv_tv
equity  = ev + cash - total_debt
implied_price_dcf = equity / shares_out

检查项:(a)如果 wacc <= g_terminal → 停止,终值增长率过于激进;(b)如果 pv_tv / ev > 0.85 或 < 0.45 → 标记并展示两种终值计算方法;(c)如果 wacc 超出 references/wacc_erp_rates.md 中的行业合理区间 → 说明。


第 5 步:相对估值

选择 4-6 家可比公司。可比公司映射和调整规则见 references/relative_valuation.md。

PEERS = ["MSFT", "ORCL", "CRM", "NOW", "SAP", "WDAY"]  # pick by industry
multiples = {}
for p in PEERS:
    pi = yf.Ticker(p).info
    multiples[p] = {
        "pe_fwd": pi.get("forwardPE"),
        "ev_rev": pi.get("enterpriseToRevenue"),
        "ev_ebitda": pi.get("enterpriseToEbitda"),
        "ps": pi.get("priceToSalesTrailing12Months"),
    }
med_pe     = np.nanmedian([v["pe_fwd"] for v in multiples.values()])
med_ev_rev = np.nanmedian([v["ev_rev"] for v in multiples.values()])
med_ev_eb  = np.nanmedian([v["ev_ebitda"] for v in multiples.values()])

eps_ttm    = float(income_q.loc["Diluted EPS"].iloc[:4].sum())
rev_ttm    = float(income_q.loc["Total Revenue"].iloc[:4].sum())
ebitda_ttm = float(income_q.loc["EBIT"].iloc[:4].sum()) + float(cashflow_q.loc["Depreciation And Amortization"].iloc[:4].sum())
net_debt   = total_debt - cash

implied_pe       = med_pe * eps_ttm
implied_ev_rev   = (med_ev_rev * rev_ttm - net_debt) / shares_out
implied_ev_ebit  = (med_ev_eb  * ebitda_ttm - net_debt) / shares_out
implied_price_rel = np.nanmedian([implied_pe, implied_ev_rev, implied_ev_ebit])

如果目标公司的增长或利润率特征存在重大差异,可比公司中位数上调或下调 10-30%。务必说明调整幅度及理由。SaaS 的 Rule of 40 基准见 references/relative_valuation.md。


第 6 步:分部加总估值(SOTP,仅适用于多分部公司)

除非 10-K 报告中列出 2 个或更多经济特征不同的经营分部,否则跳过。yfinance 不会提供分部数据,用户必须自行提供或从申报文件中解析。完整方法论见 references/sotp.md:

  • 确定各分部及其对应的纯业务可比公司
  • 应用可比公司 EV/EBITDA 中位数(增长型分部使用 EV/Rev)
  • 扣除未分摊的公司成本(未知时按收入的 2-5% 计,上限为 5%)
  • 扣除净债务和少数股东权益;再除以股份数

SOTP 折价 =(SOTP 价格 − 市场价格)/ SOTP 价格。如果 >20%,则标记为企业集团折价。


第 7 步:交叉验证、敏感性分析和情景分析

# Blended implied price
if sotp_price is None:
    blended = 0.5*implied_price_dcf + 0.5*implied_price_rel
else:
    blended = 0.4*implied_price_dcf + 0.3*implied_price_rel + 0.3*sotp_price

# 5x5 sensitivity grid
wacc_grid = [wacc + dx for dx in (-0.01, -0.005, 0, 0.005, 0.01)]
g_grid    = [0.015, 0.020, 0.025, 0.030, 0.035]
sens = {}
for w in wacc_grid:
    for g in g_grid:
        tv = fcff[-1]*(1+g)/(w-g)
        pv = sum(f/(1+w)**(i+1) for i,f in enumerate(fcff)) + tv/(1+w)**5
        sens[(w,g)] = (pv + cash - total_debt) / shares_out

此外,还要给出 Bull / Base / Bear 情景:收入增长率调整 ±300 个基点,EBIT 利润率调整 ±200 个基点,WACC 调整 ∓100 个基点,终值增长率分别设为 3.0% / 2.5% / 1.5%。


第 8 步:回复用户

按以下顺序呈现估值结果:

  1. 核心结论 — 用一句话说明加权公允价值、当前价格、上涨或下跌百分比,以及最看多或最看空的方法。
  2. 概览 — 行业板块、行业、总市值、当前价格、3 个月 / 12 个月价格变动、LTM 收入增长率。
  3. 三种方法汇总 — 3 列表格:方法 | 隐含价格 | 权重 | 简要理由。
  4. DCF 构建 — 假设表(增长路径、利润率、WACC 组成、终值方法)+ 5 年 FCFF 预测表 + EV 到股权价值的桥接表。
  5. 可比公司对照 — 可比公司表格,包含预期 P/E、EV/Rev、EV/EBITDA、毛利率、收入增长率;最后一行为中位数;标记目标公司的溢价 / 折价。
  6. SOTP(如适用)— 分部表格 + 调整项 + 股权价值。
  7. 敏感性矩阵 — WACC × g 网格(5×5),突出显示基准情景。
  8. 情景分析 — Bull / Base / Bear 情景表,列出关键变量和隐含价格。
  9. 主要风险 — 说明哪些假设对估值影响最大,以及哪些因素可能推翻投资逻辑。
错误处理
缺失情况 / 边界情况处理方式
yfinance 返回 None 作为 beta使用 references/wacc_erp_rates.md 中的行业默认 beta
LTM EBITDA 为负跳过 EV/EBITDA 倍数;采用 EV/Revenue + DCF
LTM EPS 为负跳过 P/E 倍数;如果预期 P/E 为正则使用,否则跳过
Gordon 模型中的增长率 > WACC将 g = wacc − 0.5% 设为上限并标记
历史数据不足 3 年使用现有数据;将数据置信度标记为“低”
获取可比公司数据失败从中位数计算中剔除该公司;在输出中说明
SOTP 没有分部数据跳过第 6 节;仅采用 DCF + 相对估值
需包含的注意事项
  • TTM 数据存在滞后;可比公司倍数反映市场情绪(可能过度波动)
  • DCF 结果取决于输入数据的质量;敏感性分析比单点估值更重要
  • yfinance 数据未经官方认证;做出任何决策前都应与一手申报文件交叉核对
  • 这不是财务建议

参考文件

  • references/dcf.md — DCF 方法论和行业特定指引(软件、零售、金融、医疗保健、能源、制造业、CPG、电信、REIT、流媒体)
  • references/relative_valuation.md — 可比公司筛选、倍数调整规则、Rule of 40、按主题划分的可比公司组
  • references/sotp.md — 分部加总估值方法论、企业集团折价识别、催化因素
  • references/wacc_erp_rates.md — 无风险利率、股权风险溢价、行业 WACC 基准、行业默认 beta

评论

支持 Markdown