价值投资工具
特色条目  构建基本面分析MCP工具包\ 使用MCP工具构建可重复、可审计的财务工作流程的从业者演练。 价值投资工具VIT是一个Python库和STDIO MCP服务器,支持基于价值投资原则的基本股权分析:获取和汇总财务数据,与同行进行基准比较,使用场景运行DCF估值,估算企业价值和股权价值,并保存图表/CSV以用于可重复的工作流程。
重要披露-此代码是在ChatGPT-5和Claude Sonnet-4的审查和重构支持下共同开发的
目录
- MCP服务器(STDIO)快速入门 - 最低可行跑步时间(5分钟)
- 数据惯例和假设
- 公司内在绩效因素
- 多公司比较基础
- 对等多重比较
- [历史业绩的隐含价值(电动汽车和股票)]()
- [基于情景的内在价值(DCF与终端增长)]()
- 数据健康报告
- 功能概述
- 自动估值编排器
- 注释、路线图、贡献
- 许可证
1.为什么存在这种情况
ValueInvestingTools(VIT)是一个用于基本面股权分析的Python库,支持估值场景、观察与隐含EV、同行基准测试和可导出的可视化/数据等工作流程。
VIT获取报表,构建干净的数据集,运行DCF和对等多个估值,并准备绘制输出。
此存储库还附带了一个MCP服务器,因此支持STDIO的LLM客户端可以调用VIT函数作为工具来执行计算、生成图表和工件,并保存可复制工作流的输出(请注意,此存储库中有一个单独的MCP服务器自述文件。请参阅 MCP服务器设置指南 -> VIT-MCP_服务器_SetUp_README.md
大多数免费数据源(如雅虎财经)都提供快速快照,但它们:
- 不一致地混合TTM和时间点值。
- 忽略关键比率(净资产收益率、再投资率、多年复合年增长率)。
- 隐藏计算方法,使再现性变得困难。
ValueInvestingTools通过以下方式解决这些差距:
- 直接从报表(收入、资产负债表、现金流)计算指标。
- 为了程序一致性,将所有内容都以小数形式返回(0.15=15%)。
- 提供Pandas DataFrames(默认)或JSON可序列化字典(用于LLM/代理)的输出。
- 添加健康/状态注释,以便用户看到值何时丢失、近似或基于短覆盖率。
2.如何使用这个图书馆
该工具包遵循逐步的工作流程,反映了分析师通常对公司的看法:
- 公司快照->查看TTM与历史平均值。
- 同行组比较->用户选择可比较的同行,将目标公司的数字放在上下文中。
- 基本面评分(0-5)->使盈利能力、增长、再投资和风险标准化,以便进行跨公司比较。
- 可视化->使用聚类条形图、箱线图和时间序列图探索结果。
- 估值三角法->超越原始基本面:
- 5.1与同行相比的基准估值倍数(市盈率、市盈率、EV/EBITDA)。 - 5.2使用永久增长方法运行DCF情景(低/中/高)。 - 5.3根据历史增长+FCF估算隐含企业价值。 - 5.4翻译企业价值->股权->每股价值,看看市场看起来是富有还是便宜。 - 5.5使用WACC x终端生长敏感性网格对关键假设进行压力测试。
- 综合定性来源(公司报告、分析师报告、新闻),并考虑VIT健康记录中缺失的数据或脆弱的假设。
上述流程反映了图书馆的组织方式:从内在因素开始,添加比较背景,然后使用估值模型将基本面与价格联系起来。
2.1数据提供者和可扩展性
当前的默认数据源是雅虎财经 yfinance提供程序抽象存在于 providers/ 以支持未来的后端(例如财务建模准备),同时保持分析层的稳定。
- 默认提供商:雅虎财经(
providers/yahoo.py). - 提供程序适配器在单个进程中缓存自动收报机对象和通用数据集,以减少重复的网络调用。
- 未来的提供商:可以通过以下方式连接其他API
providers/base.py而不改变公共功能签名。 - 路线图:见
docs/Roadmap.md供应商扩张计划和FMP勘探说明。
2.2 MCP使用(STDIO)
MCP服务器通过STDIO公开相同的库函数,因此兼容的客户端可以编排工作流。
- 快速启动:
python server.py - 详细设置:
VIT-MCP_Server_SetUp_README.md
MCP客户端兼容性
任何支持STDIO的MCP客户端都可以使用此服务器。设置指南包括不同客户端的配置示例和注意事项。有关特定于客户端的MCP配置详细信息,请参阅您正在使用的客户端的官方OpenAI或Anthropic文档。
3.安装和快速启动
# Python 3.10+ recommended
python -m venv .venv
source .venv/bin/activate # macOS/Linux
.\.venv\Scripts\activate # Windows
pip install -r requirements.txtimport ValueInvestingTools as vit
# 1) Single-company snapshot: TTM vs historical averages
summary = vit.fundamentals_ttm_vs_average("MSFT")
print(summary)
# 2) Multi-company fundamentals (absolute values)
tickers = ["MSFT", "AAPL", "GOOG"]
actuals = vit.compute_fundamentals_actuals(tickers, basis="annual")
# 3) Scored fundamentals (0-5 per metric, with factor rollups and total)
scores = vit.compute_fundamentals_scores(actuals, basis="annual")
# 4) Visualize: clustered scores across tickers
vit.plot_scores_clustered(scores, basis="annual", include_total=True)
# 5) Drill into a single metric over time for one company
vit.plot_single_metric_ts("MSFT", "ROE", family="Profitability", basis="annual")3.1 MCP服务器(STDIO)快速启动
MCP服务器公开了与STDIO上的工具调用相同的库函数,因此兼容的客户端可以编排工作流。有关设置说明,请参阅 VIT-MCP_Server_SetUp_README.md.
3.2最低可行运行时间(5分钟)
使用此快速路径验证环境和完整的数据往返。
# 1) create + activate venv (Windows)
python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt
# 2) confirm import + version
python -c "import vit; print('vit OK:', vit.__version__)"
# 3) run a single-company snapshot
python -c "import ValueInvestingTools as vit; print(vit.fundamentals_ttm_vs_average('MSFT').head())"如果打印的是非空表,则数据层、计算流和导入工作正常。
4.数据惯例和假设
惯例
- 单位比率、利润率和增长率均为小数(0.18=18%)。格式化为%仅用于显示。
- 基础切换和后缀:
- basis="annual" ->多年平均值,公共标签以 -Ave. - basis="ttm" ->在过去的12个月里,标签以 -TTM.
- 特殊情况:
- CAGR(收入、收益)总是按年计算的,因为多年增长不能以TTM为基础来定义。 - PEG和Beta始终是快照(TTM),而不管基差标志如何。
- 评分:0-5,其中5=有利/强/更安全。
- 输出:默认为DataFrames;使用
as_df=False对于JSON友好的字典。 - CSV持久性:选择加入
save_csv=True(默认为无文件)。
假设和数据来源
- 源:雅虎财经(通过yfinance Python库)。
- 范围:最近3-5个财政年度,以及相关的TTM。
- 声明:损益表、资产负债表、现金流量表。
- 估计:PEG比率使用路孚特(通过雅虎)的预期每股收益增长。
- 对等规范化:不适用于评分-所有截止值都是绝对的,而不是相对的。
- 增长率方法 假设FCF优先法,在计算终端价值时,增长假设优先考虑自由现金流复合年增长率而非收入复合年增长期,以反映股东价值来自现金生成,而不是收入扩张。需要资本支出或营运资金按比例增加的收入增长比有效的现金转换提供的价值低。(更多信息见第9节)
解释注意事项
这些工具不能替代深入的定性分析或尽职调查。他们:
- 强调长期基本面,而不是短期催化剂或情绪。
- 不要考虑管理质量、监管或竞争动态等定性驱动因素。
- 将平均历史FCF和增长视为永久性假设的代理,这可能不成立。
- 可能低估了无形重行业(如SaaS、制药)的再投资。
产出应被视为一致的分析基线,而不是投资建议。
5.公司内在绩效因素
实施范围说明(2026-02-22):当前发布的模型是由compute_fundamentals_actuals和compute_fundamentals_scores. 4x4基础重新设计(Altman/Beneish集成和独立Piotroski模块)计划在ADR和路线图中进行,但尚未在API现场评分中进行。
理论
无论短期市场噪音如何,每家公司都有一套内在驱动因素来塑造其长期价值。
虽然还有其他预测评分系统,如F-Score或Z-Score,但VIT提供了一个启发式/诊断框架,有助于根据四个具有透明阈值的关键驱动因素来构建公司财务业绩之间的比较。
这些驱动因素分为四大类:
- 盈利能力 -产生资本回报和利润的效率。
- 成长 -随着时间的推移,扩大收入和收益的能力。
- 再投资 -将收益再投资为复合价值的纪律和能力。
- 风险 -资产负债表强度和波动性敞口。
通过在不同公司和时间对这些因素进行一致的评分,这创造了一个可以在不同行业和周期之间进行比较的确定性财务质量基线。
与相对排名(z-scores)不同,该框架使用绝对阈值,以便:
- 从实际财务角度来看,5分总是意味着“优秀”,而不仅仅是“比同行好”
- 随着时间的推移,分数是稳定的,如果行业同行变得更弱或更强,分数也不会漂移。
- 一家公司可以单独评分,而不需要同行组。
要素组成和权重
| 因素 | 子指标 | 加权 |
|---|---|---|
| 盈利能力 | ROE(30%)、净利润率(25%)、营业利润率(25%)、ROA(20%) | 100% |
| 增长 | 收入复合年增长率(40%)、收益复合年增长(40%)和PEG比率(20%) | 100% |
| 再投资 | 再投资率(60%),资本支出/收入比率(40%) | 100% |
| 风险 | 债务/股权(40%)、贝塔系数(40%)和流动比率(20%) | 100% |
重量原理
- 净资产收益率(30%):有效利用股东资本;经验上与长期回报挂钩。
- 净利润率和营业利润率(各25%):获取效率和定价权;尤其是在低利润率行业。
- ROA(20%):广泛衡量资产利用率;对资产密集型产业至关重要。
- 收入和收益复合年增长率(各40%):与股东价值创造密切相关;信号可扩展性和纪律性。
- 聚乙二醇(20%)通过将估值与增长联系起来,提供现实检验;前瞻性但嘈杂。
- 再投资率(60%):复合潜力的直接衡量标准(留存收益用于增长)。
- 资本支出比率(40%):捕捉资本密集度;高值可能表明投资增长或效率低下。
- 债务/股权(40%):核心偿付能力比率;高杠杆降低了灵活性。
- 贝塔系数(40%):系统性风险代理;广泛应用于股权成本(CAPM)。
- 流动比率(20%):流动性测试;由于行业差异,权重较低。
评分阈值和力学
| 度量 | 方向 | t1 | t2 | t3 | t4 |
|---|---|---|---|---|---|
| 净资产收益率 | 上升 | 0.05 | 0.10 | 0.15 | 0.20 |
| 净利润率 | 上升 | 0.05 | 0.10 | 0.15 | 0.20 |
| 营业利润率 | 上升 | 0.05 | 0.10 | 0.15 | 0.20 |
| ROA | 上升 | 0.03 | 0.06 | 0.10 | 0.15 |
| 收入复合年增长率 | 上升 | 0.00 | 0.05 | 0.10 | 0.15 |
| 收益复合年增长率 | 上升 | 0.00 | 0.05 | 0.10 | 0.15 |
| PEG比率 | 下降 | 3.00 | 2.00 | 1.50 | 1.00 |
| 再投资率 | 上升 | 0.10 | 0.25 | 0.50 | 0.75 |
| 资本支出比率 | 下降 | 0.10 | 0.05 | 0.02 | 0.00 |
| 债务/股本 | 下降 | 2.00 | 1.50 | 1.00 | 0.50 |
| 贝塔 | 下跌 | 2.00 | 1.50 | 1.20 | 0.80 |
| 流动比率 | 上升 | 0.80 | 1.00 | 1.50 | 2.00 |
诠释
- 跨过阈值会使分数增加1。
- 示例(越高越好):净资产收益率为12%->得分为3。
- 示例(越低越好):贝塔系数1.3->得分3。
推荐逻辑
总分和因子分解可以映射到诊断类别中:
- 优秀表演者(>=18,所有因素得分>=4) -在盈利能力、增长、再投资和风险方面具有广泛的实力。
- 弹性芯(14-16.9) -基本面强劲,但存在轻微弱点。
- 不均匀的基本面(11-13.9) -表现参差不齐;一些优势被关键的弱点所抵消。
- **基础薄弱(\标记为关键弱点。
- 无论总分如何,风险评分\都会被标记。
- 再投资得分\标记为不可持续。
- 因素之间过度不平衡(高度分散)->已标记。
- 标记数据完整性\。
选项和默认值
函数: compute_fundamentals_actuals(tickers, basis="annual", save_csv=False, as_df=True)
基础:
"annual"多年平均值(默认值)。"ttm"过去12个月(时间点)。
重要注意事项:
- CAGR(收入、收益)仅按年计算。
- PEG和Beta始终是快照/TTM度量,而不管基差标志如何。
save_csv:默认为False;如果为True,则按股票代码保存原始语句。as_df:True返回一个DataFrame;False返回JSON可序列化的字典。
计算
import ValueInvestingTools as vit
# Annual averages for one company
df = vit.compute_fundamentals_actuals(["MSFT"], basis="annual")
print(df.T)
# Scores (0-5) and factor rollups
scores = vit.compute_fundamentals_scores(df, basis="annual", merge_with_actuals=False)
print(scores.filter(regex="^score_|_score$").T)
# Average vs TTM comparison table
summary = vit.fundamentals_ttm_vs_average("MSFT")
print(summary)可视化
# Profitability time series
vit.plot_single_metric_ts("MSFT", "ROE", family="Profitability", basis="annual")
# Family of metrics (e.g., Reinvestment) across tickers
vit.plot_multi_tickers_multi_metrics_ts(
["MSFT","AAPL","GOOG"],
family="Reinvestment-basic",
metrics=["ReinvestmentRate","CapexRatio"],
basis="annual"
)
# Clustered scores (factor rollups across companies)
scores = vit.compute_fundamentals_scores(["MSFT","AAPL","GOOG"], basis="annual")
vit.plot_scores_clustered(
scores,
metrics=["profitability_score","growth_score","reinvestment_score","risk_score"],
include_total=True, sort_by="avg"
)口译指南
输出是评分表和视觉效果。以下是如何阅读它们:
度量级别分数(0-5):
- 示例:净资产收益率=12%->得分=3(扎实但不是精英)。
- 示例:贝塔=1.3->得分=3(中等波动性)。
因素汇总:
- 盈利能力得分=ROE、利润率、ROA的平均值。
- 增长得分=收入复合年增长率、收益复合年增长速度、PEG的平均值。
- 再投资得分=再投资率+资本支出比率。
- 风险评分=债务/权益、贝塔系数、流动比率。
总分(满分20分):
- MSFT:盈利能力4.0+增长3.0+再投资3.5+风险4.0=14.5->“弹性核心”
视觉效果:
- 集群条形图:突出一家公司内各因素的相对优势。
- 时间序列:显示基本面是改善还是恶化。
关键点:高分是积极的,但解释取决于背景。
- 一家公司可能在增长方面得分较高,但在风险方面得分较低->波动较大。
- 另一种可能在盈利能力方面得分很高,但在再投资方面得分较低->成熟,未来复合收益较低。
虽然这个例子使用了一家公司(MSFT),但同样的框架可以无缝地扩展到同行群体比较,从而很容易发现一家公司的优势和劣势是否在竞争对手中脱颖而出。
6.多公司比较基础
理论
孤立地看待一家公司可以洞察其内在业绩,但估值和投资决策本质上是相对的。同一行业、地理位置或市值范围内的竞争对手面临着类似的宏观条件,因此同行比较突显了公司的基本面是强劲、一般还是滞后。
关键原则:
- 保持同行组中所有公司的基准一致(年度与TTM)。
- 慎重选择同行:行业、规模、产品组合和地区都很重要。
- 关注方向性差距(一家公司在利润率、杠杆率、增长方面是否一直更强?)。
- 分数和汇总使跨维度比较变得更加容易,但原始指标对于细微差别同样重要。
选项和默认值
- 函数:
compute_fundamentals_actuals(tickers, basis="annual", save_csv=False, as_df=True) - 心脏:股票代码列表(建议至少2个)。
- 基础:
"annual"(多年平均值)或"ttm"(时间点)。 - save.csv:如果为True,则保存每条股票代码语句。
- as_df:True返回DataFrame;False返回JSON可序列化的字典。
计算
import ValueInvestingTools as vit
tickers = ["MSFT", "AAPL", "GOOG"]
# Absolute fundamentals across companies
actuals = vit.compute_fundamentals_actuals(tickers, basis="annual")
# Score fundamentals for the peer set
scores = vit.compute_fundamentals_scores(actuals, basis="annual")
print(actuals.head())
print(scores.filter(regex="score").head())可视化
# Compare reinvestment metrics across companies
vit.plot_multi_tickers_multi_metrics_ts(
["MSFT","AAPL","GOOG"],
family="Reinvestment-basic",
metrics=["ReinvestmentRate","CapexRatio"],
basis="annual"
)
# Compare score rollups across companies
vit.plot_scores_clustered(
scores,
metrics=["profitability_score","growth_score","reinvestment_score","risk_score"],
include_total=True, sort_by="avg"
)口译指南
在比较多家公司时:
- 绝对指标 (例如,净资产收益率、利润率、债务比率)揭示了谁在原始条件下表现最佳。
- 评分指标 将值标准化为0-5的范围,使异常值一目了然。
- 汇总 允许快速进行高层评估(例如,A公司盈利能力更强,B公司风险较弱)。
- 可视化:
- 多股票折线图显示了随时间变化的趋势差异。 - 聚类条形图显示了各因素的相对位置。
备注:评分是绝对的,不是相对的——一家公司的高分不会降低另一家公司。这确保了随着时间的推移的稳定性,但这意味着如果行业总体上很强(或很弱),同行可能都会得分很高(或很低)。
7.同行倍数比较
7.1对等体倍数计算
理论
通过倍数进行相对估值是股权分析中使用最广泛的工具之一。倍数不是预测现金流或建立详细的预测,而是提供一个基于市场的基准:类似公司如何相对于其收益、销售额或经营现金流进行交易?
这个库总结了同行估值区间(第25、50和75百分位数),这样你就可以根据保守、中值和看涨的背景来锚定公司的估值。默认情况下,市盈率、市盈率和EV/EBITDA的来源是TTM比率(最近过去十二个月),而不是多年平均值(与之前的基本因素分析函数不同)。如果你想要一个前瞻性信号,你可以将PE切换为转发PE multiple_basis="forward_pe" 同时保持PS和EV/EBITDA落后。
但这种方法只与所选的同龄人一样好。
选择正确的同行集对于获得有意义的基准至关重要。选择不当的同行可能会扭曲分析并导致误导性的结论。
在选择同行时,请考虑:
- 行业和商业模式-公司应在相同或密切相关的行业运营。
- 公司规模和市场份额——大盘股与小盘股公司的交易倍数通常不同。
- 地理风险——本地与全球足迹会改变增长、利润和风险状况。
- 财务指标——资本密集度、利润结构、再投资需求。
- 客户群和产品组合——所服务市场的重叠程度。
- 竞争定位——拥有耐用护城河的公司与拥有商品化产品的公司。
虽然同行选择不在这个库的范围内,但分析师必须做出判断,以确保苹果对苹果的比较。
选项和默认值
函数: peer_multiples(tickers: list[str], *, target_ticker: str, include_target: bool = False, multiple_basis: str = "ttm", as_df: bool = True) -> dict[str, Any]
- target_ticker:正在进行基准测试的公司的股票代码。
- 心脏:同行股票代码列表。
- 多重基线:
"ttm"(默认)或"forward_pe"(使用雅虎forwardPE当PE可用时;PS和EV/EBITDA仍然落后,输出在元数据中反映了这一点)。 - 同行质量诊断:
True添加了覆盖率和分散度诊断,这样您就可以在信任估值区间之前查看对等集是否可靠。
您可以选择加入 include_target=True 如果你想让目标被计入同行统计数据中(通常不建议用于估值可比性)。
输出
- 对等_详细信息:传入的所有股票的每个股票快照(包括target_ticker(如果存在))。包含原始比率,如pe_ratio、ps_ratio和ev_to_ebitda,以及您构建的任何每股估值字段。
- peer_multiple_bands_wide:行=PE/PS/EV_EBITDA,列=最小值/P25/中位数/P75/最大值/平均值。仅当include_target=False时从对等方计算;如果include_target=True,则包含目标。
- 对等通信频带:每股估值区间较长(例如,PE_Min、PE_P25等),仅在include_target=False时从同行计算。
- 同行质量诊断:可比性检查(规模/增长/利润率/杠杆率/风险代理的覆盖范围+分散警告),以帮助在信任估值区间之前评估同行集是否存在异质性。
计算
import ValueInvestingTools as vit
tickers = ["AAPL","GOOGL","AMZN","MSFT"]
# Target required; default behavior excludes target from stats
res = vit.peer_multiples(tickers, target_ticker="MSFT", include_target=False)可视化
# Access detail (all tickers) and peer-only bands
detail = res["peer_comp_detail"] # includes MSFT row
bands = res["peer_multiple_bands_wide"] # quartiles over peers (MSFT excluded)
# Boxplot with overlay of target, using detail + bands
fig, ax = vit.plot_peer_metric_boxplot(
peer_comp_detail=detail,
peer_multiple_bands_wide=bands,
metric="EV_EBITDA",
target_ticker="MSFT",
include_target_in_stats=False, # match the call above
)备注
- 默认情况下,将目标从对等统计中排除是一种可防御的比较方法(防止主体偏离其基准)。
- 通过设置include_target=True,您可以将目标包含在演示文稿或小型对等集的对等统计中。
- plot_peer_metricboxplot已经更新,即使目标被排除在统计数据之外,也会将目标值与对等分布叠加在一起。
口译指南
低/中/高波段:
- P25(Lo)->保守基准。
- P50(Med)->中等/中等估计值。
- P75(嗨)->乐观基准。
相对定位:
- 如果目标始终低于P25,则可能被低估或从根本上弱于同行。
- 如果持续高于P75,它可能会被高估或合理溢价(由于护城河、增长、利润率)。
背景很重要:
- 高增长公司可能会要求更高的倍数。
- 尽管基本面稳健,但成熟公司可能会以折扣价交易。
关键点:多重诊断是诊断性的,而不是确定性的。它们在以下方面表现最佳:
- 对DCF结果进行健全性检查。
- 一种判断市场对一家公司的评价是否与同行一致的方法。
- 一个快速屏幕,用于识别需要更深入分析的异常值。
7.2提取价格快照和平均值
许多工作流程需要过去1/30/90/180天的简单平均价格锚。
函数
historical_average_share_prices(tickers, *, analysis_report_date=None, save_csv=False, as_df=True)
它做什么
返回一个或多个股票代码在1d、30d、90d、180d窗口(截至今天)内的平均价格。在内部,它利用了库的价格快照助手,因此在使用快照的任何地方都可以获得一致的行为。列:报价单、平均价格_1d、平均价格_30d、平均价格_90d、平均定价_180d、价格_asof、备注
import ValueInvestingTools as vit
vit.historical_average_share_prices(["MSFT","AAPL"])请注意,CSV导出是通过以下方式选择加入的 save_csv=True;文件保存在 ./output.
7.3将同行倍数转换为每股价格
现在,您可以将同行多个波段直接转换为目标的隐含每股价格。
函数
price_from_peer_multiples(peer_multiples_output, *, ticker=None, analysis_report_date=None, save_csv=False, as_df=True)
它做什么
- 获取以下输出
peer_multiples(...)PE、PS和EV/EBITDA的每股价格区间返回P25/P50/P75。它在可能的情况下推断目标股票代码(或者您可以显式传递ticker=) - 对于EV/EBITDA,企业价值使用同行快照中携带的最新股份、净债务、现金和等价物以及少数股权转换为每股股权价值,然后映射到P25/中位数/P75。所使用的输入在inputs_used for audibility中回显
import ValueInvestingTools as vit
peers = vit.peer_multiples(["AAPL","GOOGL","MSFT","AMZN"], target_ticker="NVDA")
vit.price_from_peer_multiples(peers)如果您的peer_multiples结果将目标从对等体统计中排除(推荐),则只有在需要时覆盖目标时,才能从对等体正确计算频带。
8.历史业绩的隐含价值(EV和股权)
理论
基于情景的DCF(第9节)在明确假设的情况下向前预测,而隐含EV模块则向后看:它使用自由现金流和增长的历史平均值,就像它们是永久增长模型的稳态输入一样。
因此,值得注意的是,此功能 不引入单独的终端增长输入相反,它使用平均FCF基数和历史复合年增长率(带护栏)以及WACC的折扣。
它回答的问题是:“如果我们假设公司的平均历史自由现金流和增长无限期持续下去,这意味着什么企业价值(EV),以及它与今天的市场EV相比如何。”
计算基于永续增长法:
$$EV\_{\\text{隐含}=\\frac{FCF\_{\\text{avg}\\cdot(1+g)}{WACC-g}$$
哪里:
- $FCF\_{\\text{avg}}$=平均历史自由现金流(过去3-5年)
- $g$=平均历史增长率
- $WACC=R_f+\\beta\\cdot ERP$(使用融资beta,否则需要出错)
- $g$的上限为$WACC-0.5%$,以避免不切实际的永久性假设
向后看的局限性:这种方法假设历史FCF和增长模式代表可持续的稳态条件。这一假设在以下情况下尤其成问题:
- 周期性业务(捕捉任意周期位置)
- 正在经历战略转型的公司
- 面临中断或监管变化的行业
- 历史FCF中有重大一次性项目的公司
选项和默认值
平衡(默认) -保守倾向,历史锚定:
- 无风险利率: 4.18%
- 股权风险溢价: 4.23%
- FCF增长回落: 2.0%,带护栏 **g\隐含电动汽车,市场将定价为更高的增长/更低的风险。
- 如果观察到的电动汽车\股权->每股)
一旦计算出隐含的EV,就可以使用标准调整将其与股权价值进行对账:
$$\\text{股权}=EV-\\text{净债务}-\\text{少数派权益}$$
当无法直接获得净债务时的替代形式:
$$\\text{股权}=EV-\\text{总债务}+\\text{现金和等价物}-\\text{少数派权益}$$
然后:
$$\\text{每股隐含股份}=\\frac{\\text{股权}{\\text{Shares Outstanding}}$$
备注:如果雅虎财经有部分数据,该功能将回退到 sharesOutstanding * currentPrice 当 marketCap 缺失;否则离开现场 None 并在中记录上下文 Notes.
通过实施 compare_to_market_cap
compare_to_market_cap(ticker_or_evdf, *, years=None, risk_free_rate=0.0418, equity_risk_premium=0.0423, growth=None, target_cagr_fallback=0.02, use_average_fcf_years=None, volatility_threshold=0.5, as_df=True, analysis_report_date=None)
目的:将隐含股权价值(源自隐含EV)与雅虎财经的观察市值进行比较。
输入:
- 通过a 股票代码串 (镜子
compare_to_market_ev选项), 或 这 单行数据帧 返回由compare_to_market_ev. - 可选旋钮与您的EV比较工作流程相匹配(WACC、增长、平均窗口等)。
输出:单行 pd.DataFrame 上面列出的列。
计算
df_cap = compare_to_market_cap("AAPL", years=5, use_average_fcf_years=5)
print(df_cap[["Ticker","Observed_MarketCap","Equity_Implied","Premium_%"]])
# Example B - from an existing EV comparison:
df_ev = compare_to_market_ev("AAPL", years=5)
df_cap2 = compare_to_market_cap(df_ev)
# Visualize
fig, ax = plot_market_cap_observed_vs_implied_equity_val(df_cap, save_path="aapl_equity_vs_mktcap.png")口译指南
主要用例:最好用作 完整性检查 除了前瞻性DCF和同行倍数外,它不是一种独立的估值方法。
市场比较背景:
- 溢价>20%:市场预计比历史模式有更高的增长/更低的风险
- 溢价5-20%:与历史表现相比,市场适度乐观
- 溢价-5%至+5%:市场定价与历史模式大致一致
- 折扣-20%至-5%:市场与历史表现相比略显悲观
- 折扣\0.5:波动性高(建议缩短窗口)
当结果最可靠时:
- 成熟、稳定的业务,现金流可预测
- 具有一致资本配置模式的公司
- 具有稳定竞争动态的行业
何时使用替代方法:
- 高增长公司(历史增长不具有代表性)
- 周期性业务(周期的时间对结果有重大影响)
- 近期发生重大战略变化的公司
9.基于情景的内在价值(DCF与终端增长)
理论
贴现现金流(DCF)通过对有限的现金流加上最终价值进行贴现来估算企业价值:
终值(永续增长法) $TV=\\frac{FCF\_{N}\\cdot(1+g)}{WACC-g}$
DCF隐含EV $EV\_{\\text{intended}=\\sum\_{t=1}^{N}\\frac{FCF_t}{(1+WACC)^t};+;\\frac{TV}{(1+WACC)^N}$
该库使用三种场景方法(低/中/高)来括住不确定性,而不会产生假精度。
关键方法
这运行 DCF情景(低/中/高) 与明确 顶端生长 模型。与早期版本相比,默认值略有收紧:
- 股权风险溢价 4.23%
- FCF增长回落 2.0%
- FCF窗口 默认3年。
- 终端生长护栏 `g 低WACC(低风险)
- 中等增长->中等WACC
- 高增长->高WACC(高风险)
FCF基线:使用归一化的历史FCF,去除异常值和最近一段加权,而不是简单的平均值。
增长约束:为了保持稳定,增长率上限为加权平均资本成本-0.5%,下限为-5%。
返回包含以下列的DataFrame:场景、Growth_Used、WACC_Used、Per_Share_Value,适用于3个场景
对结果的影响:加权平均资本成本修正通常会降低杠杆公司的折现率,导致企业价值高于之前的仅股权成本方法。高杠杆公司将看到最显著的估值变化。
与使用收入复合年增长率的标准方法相比,方法论优势
FCF增长优先级:与大多数默认为收入复合年增长率的估值库不同,该库在终端增长假设中优先考虑FCF复合年增长。这种区别至关重要,因为:
收入与自由现金流增长差异:
- 收入增长并不能保证股东价值的创造
- 公司可以通过利润压缩、过高的资本要求或糟糕的营运资金管理来增加收入,同时破坏价值
- FCF增长直接反映了股东在满足所有运营需求和再投资后的可用现金
现实世界影响示例:
- 资本密集型企业:需要按比例增加资本支出的收入增长显示FCF增长较低,导致更保守(现实)的估值
- 成熟的优化器:提高营运资金效率的公司可能会显示FCF增长超过收入增长
- 高增长转型:尽管收入增长,但FCF为负的早期公司会受到适当的估值限制
验证框架:FCF复合年增长率是有限的(-30%至+30%),因为由于资本支出不稳定和周期性模式,它可能会高度波动。当FCF增长极端或不可靠时,该模型会通过保守的0.8倍调整回落到收入复合年增长率,然后回落到指定的回落率。
竞争差异化:大多数图书馆使用收入复合年增长率,因为它更稳定、更可预测。该库接受基于FCF的增长的复杂性,以产生更符合长期股东价值创造的估值。
当这件事最重要的时候:
- 制造业、公用事业和其他资本密集型行业
- 正在经历商业模式转型的公司
- 具有不断变化的再投资需求的成熟公司
- 任何收入增长不能转化为利润现金生成的情况
选项和默认值(快速参考)
years=5地平线(第5年结束)。risk_free_rate=0.0418, equity_risk_premium=0.0423.target_cagr_fallback=0.02如果对等/目标增长不可用。peer_tickers=[...]可选地,种子从同级FCF CAGR(P25/P50/P75)生长。- 增长始终限制在加权平均资本成本-0.5%。
- 需要测试版;缺少beta->错误。
- 共享估值违约通过以下方式暴露
valuation_defaults(...)为了可审计性。 assumptions_as_of可以传递给估值函数,在输出中标记假设日期。Assumptions_Used有效载荷现在包括assumptions_schema_version和assumptions_snapshot_id用于可重复的运行间比较。
转型公司的高级控制
fcf_window_years=3->默认情况下使用最近3年的FCF。集None使用所有可用的FCF历史记录,或设置1-3以强调最近的时期。manual_baseline_fcf=None->根据历史数据计算(默认)。为快速增长的公司覆盖当前的运行率FCF。manual_growth_rates=None->使用对等/目标增长逻辑(默认)。覆盖人工智能/生物技术/其他高增长行业的\[低、中、高\]定制增长率。
计算
import ValueInvestingTools as vit
df = vit.dcf_three_scenarios(
ticker="META",
peer_tickers=["AAPL","GOOG","MSFT"], # optional but recommended for better growth seeding
years=5,
risk_free_rate=0.0418,
equity_risk_premium=0.0423,
target_cagr_fallback=0.02
)
print(df)
# Advanced controls for transformational companies (e.g., NVDA, high-growth AI)
df_advanced = vit.dcf_three_scenarios(
ticker="NVDA",
fcf_window_years=2, # Use only recent 2 years
manual_baseline_fcf=72_000_000_000, # Use current $72B run-rate
manual_growth_rates=[0.20, 0.30, 0.40], # AI-appropriate growth rates
risk_free_rate=0.04, # Current lower rates
equity_risk_premium=0.0423
)
print(df_advanced)灵敏度网格(加权平均资本成本x终端增长)
使用 dcf_sensitivity_grid 看看每股价值在合理的加权平均资本成本和终端增长范围内是如何变化的。
grid = vit.dcf_sensitivity_grid(
ticker="META",
years=5,
wacc_values=[0.06, 0.08, 0.10],
growth_values=[0.01, 0.02, 0.03],
)
print(grid["grid_wide"])口译指南
WACC灵敏度:DCF值对加权平均资本成本假设高度敏感。加权平均资本成本每变化1%,企业价值就会改变15-25%。债务成本估算使用的近似值可能无法反映真实的借贷成本。
FCF质量问题:
- 具有波动性或周期性FCF模式的公司收到波动性警告
- 如果业务组合发生变化,历史FCF可能无法代表可持续的运行率
- 历史FCF中的一次性项目可能会扭曲基线假设
增长率限制:
- 由于利润率变化和资本密集度,FCF增长可能与收入增长存在显著差异
- 历史增长可能无法预测未来的表现,特别是对于成熟或中断的行业
- 基于同行的增长种子假设类似的商业模式和竞争地位
情景解读:
- 情景之间的巨大差异表明假设敏感性很高
- 每股负值表明数据质量问题或基本业务挑战
- 价值明显高于/低于市场价格,需要对潜在假设进行调查
何时应谨慎行事:
- EV/FCF倍数>50倍或\50倍或\
"Historical FCF highly volatile (CoV > threshold)".
这些字段附在 行级别 (因此,多个自动收报机的输出每个自动收报器都有不同的注释)。
编排器整合
这 orchestrator_function 自动从所有子功能中收集健康记录,并将其标准化为 块列表每个区块都有:
{
"source": "compute_fundamentals_actuals",
"ticker": "MSFT",
"data_incomplete": true,
"notes": [
"Revenue series too short (正常化为熊猫。带列的DataFrame:源| Ticker |数据不完整|注释
- `health_to_markdown(health_report)` ->呈现与Markdown表相同。
- `save_health_report_excel(health_report, path="...")` ->将规范化表和原始JSON保存到Excel。
这些助手接受以下两种情况:
- 新模式(每个函数/每个股票代码的块列表),以及
- 遗留模式(带notesfor_lm、method_status等的dict)用于向后兼容性。
## 备注-如何访问
注释通常以列的形式返回(例如,在dcf_three_scenario中),或者作为dict与主DataFrame一起返回。您可能会看到的示例:
- “过去4个季度建造的TTM”
- “增长上限为加权平均资本成本-0.5%”
- “仅基于3个年度积分的收入复合年增长率”
- “缺少Beta->无法计算WACC”
- “净债务缺失->根据最新资产负债表估算”
这些使分析变得可以解释——你不仅可以看到数字,还可以看到幕后应用的假设和捷径。
## 使用示例
out = orchestrator_function( target_ticker="NVDA", peer_tickers=["NVDA","MSFT","META","GOOGL"], )
View structured health notes
print(health_to_markdown(out["data_health_report"]))
Save to Excel
save_health_report_excel(out["data_health_report"], path="output/NVDA_health.xlsx")
## 口译指南
- High missing_pct(>20%)->指标可能不可靠。
- 低n_unique(例如,1)->值可能已过时或不完整(例如,未报告beta)。
- 短的复合年增长率窗口->在注释中标记,这意味着增长分数可能很嘈杂。
- 零/NaN分数->不是错误,而是数据不可用或标记为警告的信号。
**最佳实践**:在得出结论之前,始终查看健康记录和指标。“看起来完美”的分数可能会掩盖薄弱的潜在覆盖率。
# 11.功能概述
本节提供了图书馆公共职能的快速参考。按工作流程阶段排序(从单个股票基本面->同行比较->估值->可视化->健康状况)。每一行都显示了任务、功能、简单的语言目的、关键选项,以及关于您可能遇到的健康/注释标志的简要说明。有意排除内部助手(例如_fetch_timeseries_for_plot)。
|任务|功能|目的|关键选项|注释/数据运行状况|
|------|-------------|---------|-------------|---------------------|
|单一公司快照| `fundamentals_ttm_vs_average` |比较一个股票的TTM与多年平均值| `basis="annual"` 或 `"ttm"` |关于丢失物品、简短历史的说明|
|多公司基本面| `compute_fundamentals_actuals` |计算原始指标(盈利能力、增长、再投资、风险)| `basis`, `save_csv`, `as_df` |标记缺失值;复合年增长率需要3年|
|价格快照| `historical_average_share_prices` |返回1d/30d/90d/180d窗口的平均价格| `save_csv`, `as_df` |返回Ticker、平均价格_1d/30d/90d/180d、价格_asof、备注|
|基本评分| `compute_fundamentals_scores` |应用0-5评分,汇总因子和总分| `basis`, `merge_with_actuals` |当merge_with_actuals=True时,包括注释/data_incomplete|
|对等倍数| `peer_multiples` |每股估值区间为P25/P50/P75倍| `multiple_basis="ttm"`,同行列表|同行选择至关重要;如果比率缺失,则标记NaN|
|同行倍数->价格| `price_from_peer_multiples` |将对等多波段(PE/PS/EV-EBITDA)转换为隐含每股价值| `ticker` (可选), `save_csv`, `as_df` |使用最新股票、债务、现金、MI进行EV->Equity桥接;echos输入_用于可审计性|
|增长指标| `historical_growth_metrics` |计算具有明确起始/结束年份的收入、收益和FCF复合年增长率| `min_years`, `save_csv`, `as_df` |FCF复合年增长率需要3个年度积分和正终点;注释字段解释了差距|
|隐含EV| `dcf_implied_enterprise_value` |通过增强验证,从归一化的历史FCF和增长计算EV| `window_years`, `risk_free_rate`, `equity_risk_premium`, `growth`, `volatility_threshold` |优先考虑FCF复合年增长率而非收入复合年增长期;归一化FCF基线;波动性警告;EV/FCF倍数的合理性检查;发出机器可读的信号 `Valuation_Confidence` |
|比较电动汽车| `compare_to_market_ev` |通过增强的市场数据验证比较隐含与观察到的电动汽车| `ticker`, `years`, `growth`, `volatility_threshold` |增强保费解释(5%、20%阈值);从市值+债务-现金中回退EV估计;携带/丰富 `Valuation_Confidence` |
|股权桥| `implied_equity_value_from_ev` |通过稳健的资产负债表处理,转换EV->股权->每股| `ticker`, `implied_ev`, `notes_from_ev` |有多个债务/现金数据的后备来源;增加每股计算;针对负资产和高杠杆的强化验证警告|
|DCF(基于场景)| `dcf_three_scenarios` |使用适当的加权平均资本成本计算每股低/中/高DCF值,并为转型公司提供高级控制| `years`, `peer_tickers`, `risk_free_rate`, `equity_risk_premium`, `target_cagr_fallback`, `fcf_window_years`, `manual_baseline_fcf`, `manual_growth_rates` |适当的加权平均资本成本,包括债务成本;优先考虑FCF复合年增长率;修正风险增长关系;增强FCF归一化;为高增长/转型公司提供新的高级控制;EV/FCF多重警告|
|DCF灵敏度网格| `dcf_sensitivity_grid` |构建WACC x终端增长敏感性表(宽矩阵+长行)| `ticker`, `years`, `growth`, `wacc_values`, `growth_values` |重复使用DCF基线输入和护栏;回报 `inputs_used` +笔记;上限增长 `WACC - gap` 每个细胞|
|可视化基本原理| `plot_single_metric_ts`, `plot_multi_tickers_multi_metrics_ts` |时间序列图(单/多指标)| `family`, `metrics`, `basis` |缺少值->图表中的空白|
|可视化分数| `plot_scores_clustered` |各股票代码得分的聚集条形图| `metrics`, `include_total` |使用评分DataFrame;旗帜飘扬|
|可视化倍数| `plot_peer_metric_boxplot` |使用peer_comp_detail+peer_multiple_bands_wide进行箱图+目标叠加| `metric`, `target_ticker` |即使从统计数据中排除,也会显示目标|
|DCF可视化| `plot_dcf_scenarios_vs_price` |绘制低/中/高DCF情景值| `ticker`,场景DataFrame|健康注释出现在图例/标签中|
|数据健康报告| `health_to_tables`, `health_to_markdown`, `save_health_report_excel` |规范并呈现所有功能的健康记录| `as_df`, `sort`,输出路径|新架构支持每个股票代码块(源代码、股票代码、数据不完整、注释)|
|自动编排器| `orchestrator_function` |运行完整的工作流程(基本面->分数->倍数->EV->股权->DCF)| `target_ticker`, `peer_tickers`, `basis`, `years`WACC/增长选项, `save_csv` |返回所有输出的结构化字典;data_health_report是块列表(每个函数和每个股票代码)|
**小贴士**:始终检查注释/数据运行状况输出。它们旨在揭示可能隐藏在数字中的问题(例如,缺失的beta、截断的生长窗口、NaN)。
# 12.自动估价编排器
这 `orchestrator_function` 提供了一种单一的调用方式来运行 **整个估值工作流程**:
- 计算历史价格锚(1d/30d/90d/180d)。
- 提取增长指标(收入/收益/FCF复合年增长率)。
- 计算基本面(实际值+得分因子)。
- 运行同行倍数并转换为隐含的每股价格。
- 比较隐含与观察到的企业价值。
- 比较隐含股权价值与市值。
- 运行DCF(三种情况:低/中/高)。
- 将数据健康记录聚合到标准化的模式中(每个函数或每个股票代码块的列表)。
这提供了一个适用于以下情况的单一呼叫快照:
- 快速筛选许多公司。
- 制作便于审计的汇总表。
- 立即为需要“大局”的下游应用程序或LLM代理提供数据。
## 选项和默认值
orchestrator_function( target_ticker: str, peer_tickers: list[str], *, include_target_in_peers: bool = False, years: int = 5, risk_free_rate: float = 0.0418, equity_risk_premium: float = 0.0423, growth: float | None = None, target_cagr_fallback: float = 0.02, use_average_fcf_years: Optional[int]=3, volatility_threshold: float = 0.5, basis: str = "annual", save_csv: bool = False, output_dir: str = "output", analysis_report_date: str | None = None, ) -> dict[str, Any]
## 输出
**输出键**:
- `analysis_report_date` ISO字符串
- `ticker` 目标收报机
- `peer_tickers` 同行列表(始终包括目标)
- `avg_price_1d` / `30d` / `90d` / `180d` 价格锚
- `growth_metrics` CAGR的DataFrame
- `fundamentals_actuals` / `fundamentals_scores`
- `peer_multiples` / `price_from_peer_multiples`
- `ev_vs_market` / `market_cap_vs_equity`
- `dcf_scenarios`
- `data_health_report` 带字段的字典列表:
- `source` (例如,“计算_基本面_实例”)
- `ticker` (如适用)
- `data_incomplete` (正确/错误/无)
- `notes` (字符串列表)
## 计算
import ValueInvestingTools as vit
res = vit.orchestrator_function( target_ticker="NVDA", peer_tickers=["NVDA","MSFT","META","GOOGL"], years=5 )
Show health notes in Markdown
print(vit.health_to_markdown(res["data_health_report"]))
Save to Excel
vit.save_health_report_excel(res["data_health_report"], path="output/NVDA_health.xlsx")
## 浏览输出
结果是一个嵌套结构(取决于as_df的DataFrames的dict或dict)。典型按键:
print(res.keys())
dict_keys(['fundamentals','scores','peer_multiples',
'dcf_scenarios','implied_ev','equity_value','health'])
res["fundamentals"] # raw metrics DataFrame. res["scores"] # scored fundamentals DataFrame (0-5 with rollups). res["peer_multiples"] # dict of PE / PS / EV-EBITDA valuation bands. res["dcf_scenarios"] # Low / Mid / High DCF per-share values. res["implied_ev"] # single float (implied EV). res["equity_value"] # DataFrame (equity bridge to per-share implied value). res["health"] # list of diagnostic notes collected from all sub-functions.
## 口译指南
当您需要在一次通话中获得完整的审计跟踪时,请使用此功能。适用于:
- 仪表板/报告(将每个键导出到CSV)。
- LLM或代理管道(一个函数调用返回整个估值图)。
- 输出可能很冗长;分析师仍应检查细分市场,而不是盲目依赖总体。
**不是黑盒子**:虽然便于筛选,但编排器不应被用作“设置后忘记”的估值工具。始终检查各个部件:
- **查看健康记录**:综合卫生领域标记了数据质量问题、不稳定的输入和方法限制
- **交叉验证结果**:将DCF方案与对等倍数和隐含EV进行比较,以保持一致性
- **评估假设敏感性**:不同方法的估值范围较大,表明存在高度不确定性
**当编排器结果可能误导时**:
- 高FCF波动性(CoV>0.5)使DCF和隐含EV都不可靠
- 缺少贝塔或债务数据迫使人们放弃假设
- 同行组包括具有不同商业模式或资本结构的公司
- 目标公司正在经历历史数据中未反映的重大转型
**最佳实践**:
1. 从编排器开始进行初步筛选
1. 深入了解重大投资决策的各个职能
1. 在得出结论之前,始终阅读并理解健康/注释标志
1. 在做出投资决策之前,考虑多种估值方法和业务背景
# 13.说明、路线图、贡献
## 状态和准备
为了明确预期,该项目分为几个层次:
- **稳定**:演示笔记本和测试套件中使用的核心MCP+估值工具包。
- **预览**:可用但可能更改的较新模块或工作流。
- **实验性**:尚未承诺长期支持的早期想法或峰值。
当前映射:
- **稳定**: `server.py` (STDIO MCP) `ValueInvestingTools.py` API `vitlib/` 基本面+评分、同行倍数、EV/股权桥梁、DCF情景、健康报告、图表、编排器。
- **预览**:中的提供者抽象 `providers/` (雅虎适配器+基础支架);先进的DCF控制和诊断。
- **实验性**:尚未发货的计划ADR功能(例如,预测对象、估值配置文件、HTTP/SSE传输)。
关于长期演变,请参阅路线图,该路线图跟踪了发展阶段和基本原理。
这些阶段描述的是计划顺序,而不是准备状态。
## 备注
- 这个图书馆仅供教育和分析使用。它不构成投资建议。
- 产出应始终与定性分析(管理质量、竞争动态、监管环境)一起解释。
- 历史财务数据通过yfinance从雅虎财经获取;偶尔会出现间隙或不一致。
- 假设原理和覆盖指导: `Methodology.md`.
## 路线图
未来修订的计划改进包括:
- 项目范围和护栏定位见 `docs/NORTH_STAR.md` (在提出主要新功能之前使用此选项)。
- 扩展健康诊断(覆盖率评分、特定部门警告)。
- 雅虎财经之外的可选替代数据源(提供商抽象已经搭建好)。
- 一旦需求得到验证,潜在的FMP(财务建模准备)提供商。
- 更丰富的可视化(灵敏度网格热图、因子雷达图)。
- 其他因素模块(收益质量、应计项目、营运资本强度)。
- CLI包装器,用于从命令行运行编排的工作流。
## 贡献
欢迎投稿!
- 分叉仓库,创建一个功能分支,并提交一个pull请求。
- 请将代码样式与现有模块对齐,并包括基本的自动化测试覆盖率(`unittest` 或 `pytest`).
- 特别感谢对新指标、可视化类型或健康检查的建议。
- 发布流程和语义版本控制:请参阅 `docs/RELEASE_PROCESS.md`.
- 变更日志: `CHANGELOG.md`.
### 本地验证命令
python -m py_compile server.py ValueInvestingTools.py vit/__init__.py vitlib/*.py python -m unittest discover -s tests -p "test_*.py" -v
# 14.许可证
本项目根据MIT许可证授权-您可以自由使用、修改和分发它,前提是原始版权声明和本许可声明包含在软件的所有副本或大部分中。
\*\*