Codex adapter note
This skill is generated from skills/investment-research.md so Claude Code and Codex users share one canonical workflow.
- Treat
$ARGUMENTS as the user's request in the current Codex thread.
- When the source mentions Claude-only surfaces such as Task, Agent, WebSearch, Bash, Read, or Write, use the closest Codex capability available in this session: subagents when available, web search when needed, shell commands for local tools, and normal file edits for workspace files.
- Use shared project tools from
tools/ in this repository. Prefer running commands from the repository root with paths like python3 tools/financial_rigor.py ...; if the current thread starts outside the repo, locate the actual checkout path first instead of assuming a fixed home-directory path.
- Before starting research, run the
date command to confirm today's date; treat it as the baseline for "latest" data and state the data cutoff date in the report header. Never assume the current date from training data.
- Preserve the research quality rules from
AGENTS.md: cross-check financial data, use exact arithmetic tools for valuation/math, and clearly label uncertainty and source gaps.
投资研究:巴菲特-芒格-段永平-李录 四大师综合分析框架
对 $ARGUMENTS 进行系统化投资研究分析。
研究框架
基于巴菲特、芒格、段永平、李录四位投资大师的方法论,按以下七个模块顺序执行研究:
前置步骤:AI研究偏见自觉(必须执行)
在开始研究前,先评估该公司的"AI可研究性",识别潜在的数据偏见:
信息丰富度评级:
| 等级 | 特征 | AI研究陷阱 | 应对策略 |
|---|
| A级(信息充裕) | 上市多年、券商覆盖多、媒体报道密集 | 共识过强,AI输出趋同于市场定价,alpha有限 | 重点做反面检验:聪明人为什么不买?被忽略的风险是什么? |
| B级(信息适中) | 上市1-3年、覆盖有限、部分数据需推算 | AI可能用"合理推测"填补空白,看起来完整实则虚假确定性 | 每个推算数据标注置信度,区分"有据推算"和"凭空填充" |
| C级(信息稀缺) | 刚上市/冷门股/新兴市场、几乎无覆盖 | AI会因资料不足而过度保守,误判为"看不清=不好" | 用第一性原理提问(见下方),从有限信息中提取商业本质 |
C级公司的第一性原理研究法:
当公开资料不足时,不要试图拼凑出"看起来完整"的报告,而是聚焦以下底层问题:
- 客户是谁?为什么付钱?有没有替代选择?
- 复购靠什么驱动?是习惯、锁定、还是持续创造新价值?
- 竞争对手拿100亿能复制这门生意吗?
- 管理层做过什么关键决策?这些决策反映了什么判断力和价值观?
偏见自查清单(研究全程保持警惕):
将信息丰富度评级结果写入报告开头,并在最终结论中注明"AI研究置信度"与"实际投资确定性"的区别。
第一步:数据收集
数据源规范:参见 skills/financial-data.md。所有财务数据必须来自两个独立来源,误差>1%须标记。
- 美股:macrotrends(主)+ stockanalysis(副)
- 港股:aastocks(主)+ macrotrends ADR(副)
- A股:东方财富(主)+ 巨潮资讯(副)
使用 Task 工具启动后台 Agent,从网络收集以下数据:
- 收入结构:最近财年及近4季度分部收入、增速、毛利率
- 财务指标:近5年收入、净利润、毛利率、经营利润率、自由现金流、现金储备
- 竞争格局:市场份额、主要竞争对手对比
- 商业模式与护城河:核心竞争优势来源
- 技术能力:核心技术栈、研发投入
- 管理层:创始人/CEO履历、持股比例、关键决策记录
- 行业前景:TAM(总可寻址市场)、增长预测
- 风险因素:地缘政治、监管、供应链等
- 当前估值:市值、PE、PS、PEG、EV/Revenue
- 多空双方核心论点
数据交叉验证(必须执行,使用金融严谨性工具)
数据收集完成后,必须调用 tools/financial_rigor.py 对关键数据进行程序化验证,杜绝LLM心算误差。
必须验证的数据点:
- 总股本(从交易所、Yahoo Finance、StockAnalysis 等至少2个源确认)
- 当前股价和市值(手动计算 股价×总股本 并与报告市值对比,防止单位错误)
- 最近财年收入和净利润(从公司年报+至少1个第三方源确认)
- 现金储备和净现金(现金+短期投资-总债务,注意口径差异)
- 管理层持股比例(区分经济权益和投票权,注意AB股结构)
强制验证步骤(使用Bash调用工具):
Step 1 — 市值验算(精确十进制,非浮点):
python3 tools/financial_rigor.py verify-market-cap \
--price {股价} --shares {总股本} --reported {报告市值} --currency {币种}
Step 2 — 关键数据多源交叉验证:
python3 tools/financial_rigor.py cross-validate \
--field {字段名} --values '{"来源1": 数值, "来源2": 数值}' --unit {单位}
对收入、净利润、现金储备分别执行。
Step 3 — 估值指标精确验算(PE/PB/ROE/FCF Yield 等):
python3 tools/financial_rigor.py verify-valuation \
--price {股价} --eps {EPS} --bvps {每股净资产} --fcf-per-share {每股FCF} --dividend {每股股息}
验证规则:
- 每个关键数据点至少2个独立来源
- 发现来源间有差异时,优先采用公司年报/交易所数据,并注明差异原因
- 所有涉及计算的数据必须通过工具验算,禁止LLM心算
- 工具输出结果直接嵌入报告附录"关键数据交叉验证记录"
- 如果工具报告 ❌ 偏差过大,必须排查原因后才能继续分析
常见错误防范:
- 市值单位:港币亿 vs 人民币亿 vs 美元亿,容易漏写/多写一个零
- FCF口径:不同来源对资本支出的定义可能不同(是否含租赁、收购等)
- 债务口径:是否包含经营租赁负债
- 持股比例:AB股公司的经济权益 ≠ 投票权
第二步:生意本质分析 — 段永平"对的生意"
分析要点:
- 用一句话定义这门生意的本质
- 收入结构拆解(图表)
- 5年盈利能力趋势(图表)
- 商业模式画布:一次性销售 vs 订阅/复购?硬件 vs 软件 vs 平台?
- 生态粘性/客户锁定强度
- 毛利率水平与同行对比,解释为什么高/低
- 经营杠杆分析
- 段永平式追问:这门生意好在哪?如果只能用一句话描述,是什么?
第三步:护城河评估 — 巴菲特"经济护城河"
逐一验证五类护城河:
| 护城河类型 | 验证方法 |
|---|
| 品牌/定价权 | 是否能在不损失销量的情况下提价? |
| 转换成本 | 客户迁移到竞品的成本有多高? |
| 网络效应 | 用户越多产品越好吗? |
| 规模效应 | 规模带来的成本优势有多大? |
| 技术/专利壁垒 | 技术领先几年?能否被复制? |
分析护城河趋势:过去5年变宽还是变窄?未来5年预判。
巴菲特式追问:10年后这条护城河还在吗?什么能摧毁它?
第四步:逆向思考与风险清单 — 芒格"反过来想"
- 列出"这家公司可能失败的所有路径"(表格:路径/概率/影响程度)
- 历史类比:找到历史上处于相似位置的公司,结局如何?
- 跨学科分析:用网络效应理论、技术采纳曲线、竞争博弈等模型交叉验证
- 偏误自查:叙事偏差、锚定效应、幸存者偏差
- 收集空方核心论点
芒格式追问:我最可能在哪里犯错?聪明人为什么会不买/做空这家公司?
第五步:管理层评估 — 段永平"对的人" + 巴菲特"管理层诚信"
- CEO/创始人关键决策复盘(表格:时间/决策/结果/评分)
- 资本配置能力:研发回报率、并购成功率、回购时机
- 股东利益一致性:管理层持股、薪酬结构、减持记录
- 组织能力:团队稳定性、关键人才风险
- 企业文化特征
段永平式追问:如果CEO退休,这家公司还能保持竞争力吗?
第六步:行业与文明趋势 — 李录"文明演进框架"
- 判断所在行业是否处于"文明级范式转移"
- 历史技术革命类比(蒸汽机/电力/互联网/AI)
- TAM增长曲线与天花板分析
- 公司在产业价值链中的位置
- 技术路线风险
- 客户/供应商集中度分析
李录式追问:站在20年后回看,这家公司是"这个时代的标准石油"还是"昙花一现的3Com"?
第七步:估值与安全边际 — 巴菲特"内在价值" + 段永平"对的价格"
- 当前市场定价(关键估值指标表格)—— 必须通过工具验算
- 反向DCF:当前股价隐含了什么增长预期?
- 三情景估值 —— 必须通过工具精确计算,禁止心算:
python3 tools/financial_rigor.py three-scenario \
--price {股价} --eps {EPS} --shares {总股本亿} \
--growth {乐观增速} {中性增速} {悲观增速} \
--pe {乐观PE} {中性PE} {悲观PE} --years 3 --currency {币种}
长期折现估值(十年尺度,必须执行)
角色分工(硬约束,禁止混用):
| 工具 | 回答的问题 | 不是什么 |
|---|
三年三情景(financial_rigor.py three-scenario) | "贵不贵"——相对内在价值/历史/同行,当前价有没有安全边际 | 重仓裁决、一票否决 |
十年折现(terminal_value.py) | 仓位压力测试——在声明的 r 下,十年期望 IRR 能否覆盖资本成本;用于组合仓位上限/是否值得加大仓位的压力测试 | 买入/持有/回避的唯一否决票 |
三年三情景回答"贵不贵";十年折现回答"在声明的折现率下,仓位能不能加到多重"。十年基准 IRR 低于 r,只能收紧仓位建议,不得单独把最终决策改成回避/观望。 最终买/持/回避必须由生意质量、护城河、管理层、风险、文明趋势与估值六个维度并列得出,十年模型只是估值维度里的压力测试输入。
方法论一致性优先于"调低 r 去买":敏感性和翻转检查是为了暴露"结论买的是公司还是折现率",禁止为了迎合 thesis 或主观买入冲动而把 r 调出币种合理区间。
凡是给出十年期 IRR 或终值倍数的研究,必须走这套流程,用 tools/terminal_value.py。
终值倍数只有一个合法来源——永续增长模型,不许用同业类比:
$$PE_{终值} = \frac{1 - g/ROIC}{r - g}$$
"帝亚吉欧 13 倍所以茅台给 16 倍"是循环论证:用别人今天的价格,证明我假设的价格合理。市场今天整体贵,类比法就把这份贵原封不动搬到十年后。
Step 1 — 定三个输入,逐个写出理由(这一步全是判断,不是计算,必须在报告里交代):
| 输入 | 怎么定 | 常见错误 |
|---|
| r 资本成本 | 无风险利率 + β × ERP。币种必须与现金流一致:人民币口径 6%–9%(主用 8%),美元/港元口径 9%–11.5%(主用 10%) | 跟着国债利率跑。中国国债 1.70% 折出来的 PE 会到 50 倍以上,那不是估值是放大偏见 |
| ROIC 稳态增量资本回报 | 夹在存量 ROIC(含不上表的无形护城河,偏高)与派息反解的隐含增量 ROIC(假设 capex 回报为零,偏低)之间 | 直接用存量 ROIC。等于假设新投的每块钱都能复制建立微信时的回报 |
| g 永续增速 | 不是未来十年增速(那已在终值利润里),是终值年之后到永远。硬天花板是长期名义 GDP:人民币口径基准档 ≤2%,美元口径 ≤4% | 用美元的 g 配人民币的 r。3% 名义增长在美国是 0.5% 实际(保守),在中国是 2% 实际(激进) |
g 不随 r 变——g 是对终值年之后经济的判断,r 是你要求的回报,两件独立的事。做敏感性时只动 r。
Step 2 — 三条硬约束准出检查(不通过不许把估值写进报告):
python3 tools/terminal_value.py audit \
--currency {CNY|USD|HKD} --r {资本成本} --roic {稳态ROIC} \
--g {悲观g},{基准g},{乐观g} --rf {无风险利率} --beta 1.0 \
--discrete-risks "{风险名}:{情景|尾部档|概率|未建模},..."
三条检查的内容与打回条件:
| # | 检查 | 打回条件 |
|---|
| C1 | r 与 g 必须同币种 | r 落在别的币种区间、或基准档 g 超过本币上限。工具会直接指出"这是 USD 的量级——r 用了本币而 g 用了外币" |
| C2 | 分母 r−g ≥ 5 个百分点 | 任一档不足 5pct。分母越窄 g 动一点点估值就翻天;分母 ≤0 直接判模型失效。确实要做上行/下行情景时加 --upside-only 显式声明,但报告里必须写明"这是情景不是估值" |
| C3 | 离散风险不得进 r 或 β | 任一风险归属写成 折现率/r/beta 一律打回。退市、VIE 失效、地缘断供、监管重击必须归 情景 或 尾部档。β 偏离 1.0 必须给 --beta-justification |
C3 为什么是硬的:抬 r 三个百分点,对第 10 年现金流的惩罚是第 1 年的 2.6 倍;而退市风险是大致均匀甚至前置的年度危害率。用折现率处理离散风险,会系统性地把风险的时间分布搞反。 正确做法是单列一个尾部情景档并给它一个概率。
C1/C2/C3 的完整论证见 reports/7公司10年投资价值横评-确定性调整后回报-20260814.md 第 3.4–3.6 节——三条都是那份报告实际踩过的坑。
Step 3 — 出数(准出后才能跑):
# 单点退出 PE,打印完整算式(留存率/分子/分母全部展开,便于报告引用)
python3 tools/terminal_value.py pe --roic {ROIC} --g {g} --r {r}
# 从零算 IRR
python3 tools/terminal_value.py irr \
--profit {终值年利润} --mcap {今日市值} --pe {退出PE} \
--years 10 --payout {股息率-稀释率}
多公司横评时把参数写成 JSON 传 --config,再用 table / sweep / check。
Step 4 — 报告里必须写出的五件事:
-
r 取值、币种、以及配对的 g 上限。不写明 r 就报 IRR,报的是自己的偏好。
-
r±2pp 敏感性与结论是否翻转(硬约束,写买入/持有/回避之前必须跑):
# 内置预设公司(腾讯/阿里巴巴/拼多多/贵州茅台/泡泡玛特/美团/MiniMax)
python3 tools/terminal_value.py flip \
--name {预设公司名} --r {基准r} --delta 0.02 \
--currency {CNY|USD|HKD} --g-shift {币种平移} --rf {无风险利率}
# 新公司:内联参数(字段含义同下方 --config)
python3 tools/terminal_value.py flip \
--name {公司名} --roic {稳态ROIC} --g {悲观g},{基准g},{乐观g} \
--p {悲观概率},{基准概率},{乐观概率} --irr10={悲观},{基准},{乐观} --k {股息率-稀释率} \
--r {基准r} --delta 0.02 --currency {CNY|USD|HKD} --g-shift {币种平移} --rf {无风险利率}
# 新公司:或写成 JSON 传 --config(多家公司可写在同一文件,--name 取其中的键)
python3 tools/terminal_value.py flip --config {配置.json} --name {公司名} \
--r {基准r} --delta 0.02 --currency {CNY|USD|HKD} --g-shift {币种平移} --rf {无风险利率}
--config 文件格式(与内置预设字段一致,k 可省略,默认 0):
{
"某公司": {
"roic": 0.18,
"g": [0.015, 0.030, 0.040],
"p": [0.35, 0.50, 0.15],
"irr10": [-2.0, 8.0, 14.0],
"k": 0.01
}
}
| 字段 | 含义 |
|---|
roic | 2036 稳态增量 ROIC(Step 1 的判断值),小数 |
g | 悲观/基准/乐观三档永续增速(平移前的原始口径),小数;币种换算用 --g-shift 显式表达 |
p | 三档概率,和为 1 |
irr10 | 在 r=10%、原始 g 下三档的十年 IRR(百分数,如 8.0 表示 8%),是换算其他 r 的锚点;用 Step 3 的 pe + irr 按 r=10% 逐档算出。内联时用等号写法 --irr10=-2,8,14(首项为负时必须) |
k | 股息率 − 稀释率,年化小数 |
--currency 必填,与 Step 2 audit 用同一币种。工具按 CURRENCY_BANDS(人民币 6%–9%,美元/港元 9%–11.5%,同 audit C1)判定每一档:区间外的档位标"区间外,仅供参考",不参与翻转判定;基准 r 本身在区间外直接【打回】。
- 必须同时报告
r−2pp / r / r+2pp 三档的期望 IRR,以及每一档相对"期望 IRR ≥ r"(覆盖资本成本)是否通过压力测试;区间外档位照抄"仅供参考"标注,不得用区间外档位的"通过"论证买入。
- 必须显式写出:结论是否在币种合理区间内随 Δr 翻转。 若 ±2pp 两侧都落在区间外(工具会提示"区间内只有基准一档参与判定"),再用
--delta 0.01 在区间内复核一次,两次结果都写进报告。若翻转,报告须标明"本结论对折现率敏感,仓位建议须降级;不得把单一基准 r 下的未通过当作买入否决"。
- 多公司横评时,另用
sweep 检验排序稳定性;绝对数字受 r 支配,排序才是稳健结论。
-
每一档的 r−g 分母宽度,凡低于 5pct 的必须标注"仅作情景参考"。
-
未建模的离散风险清单(audit 里标 未建模 的),写进"限制"章节。
-
分歧对账块(Reconciliation,条件强制):当十年压力测试结论(期望 IRR 相对 r)与三年三情景的"贵不贵"、或与仓库内既有 thesis / 本报告前六步综合倾向方向不一致时,报告必须单独开一节「估值分歧对账」,写清:
- 分歧双方各依据什么(三年安全边际 vs 十年 r 下 IRR);
- 哪一边是定价判断、哪一边是仓位压力测试;
- 最终买/持/回避如何综合六个维度得出,禁止用十年未覆盖 r 一票否决其他维度与 thesis 证据;
- 若选择维持买入/持有,须说明仓位上限如何被十年压力测试收紧(而非假装十年模型不存在)。
巴菲特式追问:这个 r 如果错 2 个百分点,我的结论会翻转吗?如果会,我的结论买的是公司还是折现率?(用 flip 的输出直接回答,禁止口头带过。)
段永平式追问:如果股市明天关闭5年,你愿意以这个价格持有吗?
第八步:综合决策备忘录
汇总表格(六个维度并列;估值一格须同时反映三年"贵不贵"与十年仓位压力测试,禁止只填十年 IRR 相对 r 的通过/未通过):
| 维度 | 结论 | 信心度 |
|---|
| 生意质量(段永平) | | |
| 护城河(巴菲特) | | |
| 管理层(段永平+巴菲特) | | |
| 最大风险(芒格) | | |
| 文明趋势(李录) | | |
| 估值(巴菲特+段永平) | 三年:… / 十年压力测试:…(附 flip 是否翻转) | |
估值解除语(硬约束):上表估值维度不是最终决策的唯一裁决。十年折现未覆盖 r,只能下调仓位建议,不得单独把空仓者/持仓者策略改成"回避/观望"。若十年结论与三年/thesis 分歧,必须已完成第七步的「估值分歧对账」块。
最终决策表格:
四位大师模拟点评(硬约束:先读原文,禁止发明引语)
写巴菲特 / 芒格 / 段永平 / 李录的模拟点评之前,必须对每位大师执行:
- Read 原始出处:优先读本仓库内与该公司相关的一手材料(如
reports/.../段永平雪球发言-*.md、大师公开信/演讲摘录、已引用的权威转载);若仓库无存档,用公开可核验来源(雪球原文、股东信、访谈实录)并在点评下标注 URL 或文件路径。
- 引用原话:每位至少给出 1 条可核验原话(短引 + 出处),模拟点评只能是对该原话立场的延伸,不得换成相反立场。
- 禁止发明引语:不得捏造大师未说过的句子,不得用大师名字给与其公开立场相反的结论背书。
- 冲突处理:若模拟点评为迎合本报告"观望/回避"而写出的立场,与已 Read 到的原话相反,必须二选一——(a) 改正点评使其与原话一致,或 (b) 在报告中显式标注「与大师公开立场冲突:原话=…;本报告估值压力测试=…」,禁止静默歪曲。
- 读不到就不代言:若某位大师对该公司/该议题无足够原文可 Read,写「资料不足,不模拟代言」,不得凭训练语料编一段"听起来像"的点评。
输出要求
- 所有分析必须有数据支撑,附数据来源
- 使用 Markdown 表格呈现关键数据
- 每个模块末尾必须有对应大师的"追问"
- 最终将完整报告写入
~/[公司名]投资研究报告.md
- 结论要明确,不回避给出买入/观望/回避的建议
- 估值部分必须给出具体的价格区间
- 报告开头必须包含"信息丰富度评级"(A/B/C)和"AI研究局限性声明"
- 报告结尾必须区分"AI分析置信度"与"投资确定性"——前者取决于资料量,后者取决于生意本质。明确告知读者:本报告的哪些结论基于充分数据,哪些基于有限信息的推理
- 如果公司属于C级(信息稀缺),报告末尾必须列出"需要一手验证的问题清单"——建议读者通过田野调查、产品体验、供应链访谈等方式补充AI的盲区
数据抽检(准出流程)
报告写入文件后,必须执行数据抽检,通过后方可发布:
Step 1 — 提取抽检清单(15%随机抽样):
python3 tools/report_audit.py extract \
--report <报告文件路径>
输出 JSON 模板,每项含 fetched_value(待填)。
Step 2 — 取数核验:
对清单中每个数据点,按 skills/financial-data.md 规范从可靠信源取数
(美股:macrotrends+stockanalysis;港股:aastocks+macrotrends;A股:东方财富+巨潮资讯),
填入 fetched_value / fetched_source / fetched_value2 / fetched_source2。
Step 3 — 输出判决:
python3 tools/report_audit.py verdict \
--results '<填好的JSON>' \
--report <报告文件名>
- 【准出】:所有抽检点偏差 ≤ 1% → 报告可发布
- 【打回】:任意点偏差 > 1% → 修正对应数据后重新抽检,直到准出
Step 4 — 估值口径复检(含十年折现估值的报告必须执行):
如果报告里出现了十年期 IRR 或终值倍数,把最终定稿用的参数再跑一遍 audit,确认写进报告的数字与准出时的一致:
python3 tools/terminal_value.py audit \
--currency {币种} --r {r} --roic {ROIC} --g {三档g} --rf {无风险利率} \
--beta {β} --discrete-risks "{风险归属清单}"
- 【准出】(退出码 0)→ 报告可发布
- 【打回】(退出码 1)→ 修正后重跑,直到准出
这一步不能跳过的原因:第七步的 audit 是在算数之前做的,而写报告的过程中经常会回头调 g 或 r。准出前的最后一次 audit 才是对报告负责的那一次。