股票分析报告
按公司归档
以下为 tongxm-stock-analyzer 的完整分析策略说明书,与 SKILL_MANUAL.html 同步。
tongxm-stock-analyzer Skill 说明书
更新时间:2026-06-27(v8:完整归母净利润桥、压力测试假设、多阶段银行估值、同业PB-ROE、回购证据与全量图表/产物门禁全部脚本化)。只要本 skill 的流程控制、周期路由、报告策略、strict、baseline、event_alert、脚本入口、输出 JSON 结构或正式发布流程发生变化,必须同步更新本说明书。
SKILL.md、references/analysis_framework.md 索引、对应 analysis_step_*.md 文件和脚本为准。
1. Skill 的职责边界
| 模块 | 职责 |
|---|---|
| tongxm-stock-analyzer | 对某家公司、某个财报周期或事件生成可信数据包和分析报告。 |
| tongxm-stock-monitor | 发现什么时候该分析:新财报、公告、新闻、监管事件、回购、盈警等。 |
| event_alert | 主要由 monitor 触发;analyzer 只核验事件来源并分析影响,不主动无边界扫新闻。 |
2. 多市场周期路由
所有市场先映射到两个主维度,不维护第三个评分策略字段。
canonical_period = FY / H1 / Q1 / Q2 / Q3 / Q4 / LTM / event_update report_depth = annual_rebuild / semiannual_check / quarterly_monitor / event_alert
--check-baseline 做无网络预检:已有有效年度 baseline 时使用 period=latest 和 step=all;缺失时先建议对最近年报执行 period=FY 和 step=all。
period 决定财报口径、分析深度和 baseline 策略;step 只负责过滤输出哪些步骤。用户明确说“只做第3步”时,仍使用指定周期或默认 latest 作为数据锚点。
| 市场 | 报告类型 | canonical_period | report_depth |
|---|---|---|---|
| A 股 | 年报 | FY | annual_rebuild |
| A 股 | 中报/半年度报告 | H1 | semiannual_check |
| A 股 | 一季报/三季报 | Q1/Q3 | quarterly_monitor |
| 美股 | 10-K | FY | annual_rebuild |
| 美股 | Q1/Q2/Q3 10-Q | Q1/Q2/Q3 | Q2 为 semiannual_check;Q1/Q3 为 quarterly_monitor |
| 港股 | Annual Report / Interim Report | FY/H1 | annual_rebuild / semiannual_check |
| 港股 | 主板 Q1/Q3 缺失 | event_update | event_alert,标记 not_required_by_market_rule |
3. 0-5 步与周期报告分配
| 步骤 | annual_rebuild | semiannual_check | quarterly_monitor | event_alert |
|---|---|---|---|---|
| 第0步 商业模式/文化 | 完整重评,更新 baseline | baseline 校验,不重新完整评分 | baseline 触发检查,不重新评分 | 只判断事件是否影响 baseline |
| 第1步 财务分析 | 完整做 | 完整做,按半年度/累计口径 | 完整做,按季度/累计口径 | 事件相关才做 |
| 第2步 竞争与结构分析 | 完整做 | 完整做 | 完整做 | 事件影响竞争格局才做 |
| 第3步 估值分析 | 完整做 | 完整做,用 TTM/累计/预期口径 | 完整做,禁止单季利润乘 4 | 事件影响估值才做 |
| 第4步 股东回报 | 完整做 | 更新本期资本动作 | 有动作就分析,无动作说明未变化 | 事件涉及资本动作才做 |
| 第5步 历史回撤 | 默认执行 | 用户明确指定时做 | 用户明确指定时做 | 重大市场冲击才做 |
annual_rebuild、semiannual_check、quarterly_monitor。正式财报周期必须完整执行第1步、第2步、第3步。
4. baseline 机制
baseline 是某家公司最近一次年报形成的研究基准档案,不是原始财务数据表。
baselines/{market}_{ticker}.json,不受 STOCK_ANALYZER_OUTPUT_DIR 影响。报告 JSON、图表和 HTML 仍写入外部输出目录。{
"ticker": "601398",
"name": "工商银行",
"baseline_period": "2025FY",
"industry": "financial",
"playbook_key": "banking",
"playbook_status": "active",
"business_model_rating": "...",
"moat_sources": ["规模经济", "监管牌照", "低成本负债"],
"main_risks": ["净息差下行", "资产质量恶化", "资本充足率下降"],
"company_specific_watchlist": [
{"metric": "nim", "why": "判断净息差是否企稳", "risk_trigger": "连续两期下行"}
],
"company_specific_thesis": ["高股息央企", "零售低成本负债优势"],
"company_specific_red_flags": ["关注类贷款占比持续上升", "核心一级资本逼近监管底线"]
}
schema v3 新增公司级字段:company_specific_watchlist(最该盯的指标+触发条件)、company_specific_thesis(投资逻辑)、company_specific_red_flags(触发重评红线)。行业 playbook 提供默认值,年报时按公司细化;中报/季报对照 watchlist 做触发检查。这些字段不进入商业模式评分(28/35),仅用于跨期跟踪和公司核心矛盾聚焦。
baseline_watch.py 自动比对本期+历史数据。trigger 字段是结构化规则 {direction, periods, threshold, manual_check}:能自动判的判定 triggered/not_triggered/insufficient_data,无法自动判的(双指标组合等)标 manual_check 需人工,数据缺失标「需人工」不硬猜。结果写入 watchlist_result,任一指标触发恶化 → recommend_rescore=true → 报告提示「建议重新做年报完整分析」。只提醒不自动升级周期。例:腾讯 ARPU 连续两期下降 → 季报自动标红 → 提示重评。字段职责:company_specific_watchlist 是跟踪权威(指标+触发条件,机器可判恶化);main_risks 是风险描述(人读,如「资产质量恶化」,一个风险靠多指标交叉判断)。两者职责不重复。
只有完整执行 annual_rebuild + step=all 且显式传入 --update-baseline 后才创建或更新 baseline。普通验证、strict 运行、年报单步分析、中报、季报和 event_alert 均不得无提示覆盖 baseline。
中报、季报分析前读取 baseline,并判断本期是否维持、观察或触发重评。缺少有效 baseline 时,先建议用户完成最近年报整体分析;用户拒绝后允许继续,但报告必须标记“缺少年度研究基准”。
5. 行业 playbook 受控扩展
行业 playbook 使用三种状态,状态权威来自 references/industry_playbooks/registry.json,不能仅凭目录里存在 Markdown 文件判断是否启用。
| 状态 | 含义 | 本次分析行为 |
|---|---|---|
| active | 行业路由、指标、评分、strict、baseline、HTML 和测试均已完成 | 读取并执行行业专属 playbook |
| candidate | 已有候选草案,尚未完成启用检查 | 候选只供审阅,继续使用 fallback |
| fallback | 没有匹配模板 | 使用通用框架,并记录行业不匹配点 |
分析前运行 python scripts/manage_playbook.py inspect <industry_key>。分析后若至少存在 3 条框架不匹配、5 个行业核心指标、3 类护城河和 3 项行业风险,则自动生成或更新 _candidates/ 下的草案。
已启用行业 playbook(7 个):银行(含国有大行/股份制零售行/城农商行3个子行业)、公用事业、消费品牌、互联网平台、电信运营商、医疗器械、制造出口。
指标契约:每个 playbook 包含 required_metrics(该行业必须分析的指标)和 forbidden_metrics(该行业禁用的指标),引用 references/metric_registry.yml 的 key。例如银行业 required=[nim, npl_ratio, provision_coverage, core_capital_adequacy],forbidden=[ocf, fcf_cashflow_statement, broad_fcf, cash_to_net_income, gross_margin]。strict 校验和报告审计会据此拦截缺失/误用。
ROE 口径:展示时使用百分数(如 15%);进入 PB-ROE、DDM 等公式计算时必须转换为小数(如 0.15),不得把 15 直接代入公式。
5a. 指标公式注册表(metric_registry)
所有关键财务指标(FCF、DPS、ROE、PB、NIM、净现比、capex 等)的公式、单位、适用行业、能否用于分红覆盖,统一登记在 references/metric_registry.yml。
| 规则 | 说明 |
|---|---|
| 口径唯一 | 引用任一登记指标时按注册表公式计算,不得另造口径;同指标多口径时必须写明用了哪一条 |
| 分红覆盖 | can_use_for_dividend_coverage=false 的指标(如 broad_fcf、ocf)禁止用于论证分红安全性 |
| 行业禁用 | 银行业禁用 OCF/FCF/净现比/毛利率;非银禁用 NIM/不良率/拨备覆盖率/资本充足率 |
| PB-ROE 联动 | PB 不单独使用,必须与 ROE 联动;ROE 用百分数、PB 用倍数 |
5b. 估值方法行业路由(valuation_policy)
第三步估值分析不再全行业套用同一套方法,按「行业/子行业专用路由 > 公司类型兜底」选择主估值方法,见 references/valuation_policy.md。
| 行业/公司类型 | 主估值方法 | 禁用/慎用方法 |
|---|---|---|
| 银行 | 多阶段 PB-ROE / 剩余收益 + DDM;历史/同业PB辅助 | DCF、PE、PS |
| 保险 | P/EV + SOTP;投资收益率敏感性辅助 | DCF、PS、纯PE |
| 券商 | PB + SOTP;ROE中枢/成交额周期辅助 | PS、单年PE |
| 消费品/家电 | DCF + PE + FCF收益率/股息率 | PB、PS |
| 成熟医药/器械 | PE + DCF;PEG/管线折现辅助 | PB、纯股息率 |
| 创新药/Biotech | rNPV + 管线估值;现金跑道辅助 | PE、PB、纯股息率 |
| 软件/SaaS/互联网平台 | PS/ARR + FCF收益率/单用户价值 | PB、单年PE、纯DCF |
| 半导体/硬科技 | PS + EV/EBITDA + 周期调整PE | 单年PE、纯DCF |
| 公用事业/运营商 | DCF + DDM + EV/EBITDA + 股息率 | PS、PEG |
| 房地产/资源品 | NAV/储量价值 + PB/EV-EBITDA + 周期调整 | 单年PE、纯DCF、PS |
| 金融型兜底 | 多阶段 PB-ROE / 剩余收益 + DDM | DCF、PE、PS |
| 稳定现金流型 | DCF(三情景) + 股息率 | PS、PEG |
| 成长型 | PE-G + PS | PB、纯DCF |
| 周期型 | PB + 吨盈利 | PE、单期DCF |
| 重资产制造 | EV/EBITDA + ROIC | PS、PEG |
| 互联网平台 | PS + 单用户价值 | PB、纯DCF |
| 医疗/制药 | PE + 研发管线折现 | PB、纯股息率 |
valuation_route 字段已提供结构化映射(company_type、primary_methods、auxiliary_methods、forbidden_methods、summary),直接引用即可。报告审计第5层校验该块是否存在且与 JSON 一致。5c. 报告质量审计框架(report_review_framework)
把「点评一份报告好不好」从临场发挥变成系统行为,见 references/report_review_framework.md。13 层审计维度:
报告各步骤结尾统一输出「发布前阻塞项 / 后续跟踪项」。网络效应、监管特许、医疗管线等行业分支也不得回退为单行「待验证问题」。
- 数据口径审计(来源、货币、双源)
- 公式与勾稽审计(是否符合 metric_registry)
- 行业 playbook 适配审计(required/forbidden 指标)
- 公司核心矛盾审计(是否抓到 watchlist 关键变量)
- 估值方法审计(是否符合 valuation_policy 路由)
- 风险识别审计(是否识别 red_flags)
- 结论边界审计(分级:确定事实/合理推断/主观判断)
- 可沉淀规则提取(反复性问题沉淀为 skill 规则)
三种报告模式:review_only(只审计)、formal_report(交付前必须自检第1-3层,拦截口径混用/公式算错/行业适配错误)、publish_ready(发布前必须跑全部13层 + 交付协议7项全绿,审计未过禁止发布)。
5d. 竞争分析行业路由(competition_policy)
第2步「竞争与结构分析」不再全行业固定套用波特五力,按公司类型路由(competition_policy.py):
| 公司类型 | 竞争分析框架 | 说明 |
|---|---|---|
| 金融型/银行 | 波特五力适配版 | 牌照/资本/风控门槛已适配,保留五力结构 |
| 互联网平台 | 网络效应 + 多边市场 | 网络效应强度/多边协同/赢家通吃/替代品/反垄断风险 |
| 公用事业/运营商 | 监管与特许经营框架 | 牌照稀缺/监管定价/市场化敞口/资本壁垒;运营商含频率资源 |
| 医疗/制药 | 集采与研发管线框架 | 集采韧性/管线深度/渠道结构/技术迭代/认证壁垒 |
| 其他(成长/周期/制造/通用) | 波特五力通用兜底 | ROE/负债率/增速近似五力评分 |
infer_competition_framework(industry, playbook_key) 完成;银行和通用走五力,互联网/公用事业/医疗走专属框架,与 valuation_policy 同构。6. event_alert 机制
event_alert 是财报周期之外的事件影响分析,默认由 tongxm-stock-monitor 触发。
| 事件类型 | 可能影响的步骤 |
|---|---|
| 盈利预警/盈喜 | 第1步、第3步、第0步触发检查 |
| 回购/增发/配股/分红变化 | 第4步、第3步 |
| 并购/资产出售 | 第0步、第1步、第3步 |
| 监管处罚/重大诉讼 | 第0步合规文化、第3步 |
| 价格战/监管变化/行业政策 | 第2步、第3步、第0步触发检查 |
analyzer 不主动无边界扫新闻;没有 monitor 事件载荷或用户提供事件链接时,不输出事件结论。
7. 输出 JSON 关键字段
{
"period_context": {
"canonical_period": "Q2",
"report_depth": "semiannual_check"
},
"playbook_resolution": {
"status": "active|candidate|fallback",
"requested_key": "telecom_operator",
"matched_key": "",
"fallback_key": "generic",
"candidate_path": "",
"required_metrics": ["fcf_official","dividend_yield","payout_ratio"],
"forbidden_metrics": ["nim","npl_ratio","broad_fcf"]
},
"watchlist_result": {
"triggered": [],
"recommend_rescore": false,
"summary": "watchlist 全部正常。"
},
"step": "all",
"report_plan": [
{"key": "business", "source_step": "step0", "mode": "baseline_check"},
{"key": "financial_trends", "source_step": "step1", "mode": "semiannual_full"},
{"key": "porter", "source_step": "step2", "mode": "full"},
{"key": "valuation", "source_step": "step3", "mode": "ttm_or_cumulative"}
],
"baseline_status": "loaded|missing|invalid|created|updated",
"strict_status": "passed|failed|skipped",
"report_status": "formal_report|draft",
"official_metrics": {
"fcf_official": {"value": null, "status": "missing", "confidence": "low"},
"capex_total": {"value": null, "status": "missing", "confidence": "low"}
},
"bank_calculations": {
"profit_bridge": {"status": "complete", "rows": []},
"asset_quality_stress": {"status": "complete", "rows": []},
"dividend_yield_ladder": {"status": "complete", "rows": []}
},
"baseline_recommendation": {
"code": "annual_baseline_required",
"suggested_period": "FY",
"suggested_step": "all"
}
}
8. 常用触发方式
分析中国移动 # 先查 baseline;缺失则建议先分析最近年报 分析工商银行 2025年报 分析工商银行 2026中报 分析工商银行 2026一季报 分析工商银行 2025年报,只做第3步 分析苹果 2026财年Q2 monitor 发现腾讯回购公告 -> event_alert
9. 项目目录与文件地图
下面按职责列出主要目录和文件。缓存目录(如 __pycache__/、.pytest_cache/)不属于业务资产,可随时重新生成。
9.1 顶层规则与入口
| 路径 | 作用 | 主要读取者 | 修改联动 |
|---|---|---|---|
SKILL.md | 全局执行规则:流程决策树、硬性约束、数据质量、报告与发布协议。 | 分析智能体 | 流程、strict、baseline、报告或发布规则变化时同步更新本说明书。 |
SKILL_MANUAL.html | 面向人类的完整说明书,帮助快速理解当前架构和分析策略。 | 维护者 | 不替代 SKILL.md;规则变化后必须同步。 |
env.txt | STOCK_ANALYZER_OUTPUT_DIR 的唯一配置源,也可保存本地数据源 Token。 | 路径与数据源代码 | 系统环境变量和 .env 不参与输出目录选择;相对路径以 env.txt 所在的 skill 根目录解析。 |
pyproject.toml | Python 项目和测试配置。 | Python、pytest | 依赖或测试规则变化时更新。 |
9.2 references:分析方法与行业知识
| 路径 | 作用 | 主要读取者 | 修改联动 |
|---|---|---|---|
references/analysis_framework.md | 方法论索引,按 report_plan 路由到 analysis_common.md 与 analysis_step_*.md。 | 分析智能体 | 新增/调整步骤文件时同步本索引、测试和本说明书。 |
references/analysis_step_*.md | 第0-5步和最终总评的实际方法论正文,按步骤渐进加载。 | 分析智能体 | 步骤方法变化时只改对应文件,并同步报告规范、测试和本说明书。 |
references/period_routing.md | A股、港股、美股报告期到 canonical_period 与 report_depth 的映射。 | 分析智能体、周期代码维护者 | 同步 periods.py、报告计划和测试。 |
references/data_collection_guide.md | 数据源映射、采集顺序、降级策略和双源核验指南。 | 分析智能体、数据层维护者 | 数据源变化时同步 provider 和 API 参考。 |
references/*_api_reference.md | A股、港股、美股接口参数和调用说明。 | 数据层维护者 | 接口字段或服务变化时更新对应 provider。 |
references/analysis_template.md | 聊天或消息平台场景的输出格式参考。 | 分析智能体 | 报告结构仍以分析框架和正式 Markdown 为准。 |
references/developer_guide.md | 行业注册、PDF 提取、报告结构和测试等开发说明。 | 开发维护者 | 工程入口或 JSON 结构变化时同步。 |
references/playbook_lifecycle.md | 行业 playbook 的 active、candidate、fallback 生命周期和启用门槛。 | 分析智能体、manage_playbook.py 使用者 | 同步注册表、候选生成逻辑和测试。 |
industry_playbooks/ 回答“这门生意应该怎样理解和评分”,影响商业模式、护城河、企业文化、风险和禁用项;
industry_indicators/ 回答“这个行业必须额外检查哪些财务指标,以及如何解释阈值”。
| 路径 | 作用 | 主要读取者 | 修改联动 |
|---|---|---|---|
references/industry_playbooks/registry.json | 行业 playbook 路由权威,登记 active、candidate、aliases 和 fallback。 | playbook_registry.py | 不能仅新增 Markdown;正式启用还需行业识别、指标、strict、baseline、HTML 和测试。 |
references/industry_playbooks/*.md | 行业商业模式变量、评分表、护城河来源、文化观察点、风险和禁用项。 | 分析智能体 | 新增行业先走 candidate;银行还需按子行业路由。 |
references/industry_playbooks/banking/ | 银行子行业模板:国有大行、股份制零售行、区域银行。 | 分析智能体 | 与 banking/_router.md、银行识别和评分口径保持一致。 |
references/industry_indicators/banking.md | 银行 NIM、不良率、拨备、资本充足率、流动性等专项指标的含义、阈值和图表口径。 | 分析智能体、指标代码维护者 | 真正生效还需同步 industry.py、PDF 提取、strict、图表和测试。 |
9.3 scripts:执行入口与核心分析模块
| 路径 | 作用 | 主要读取者 | 修改联动 |
|---|---|---|---|
scripts/analyze_stock.py | 正式数据入口:识别证券、采集与核验数据、周期路由、行业指标、strict、baseline 和 JSON 输出。 | 命令行、分析智能体 | 参数或 JSON 变化时同步 SKILL.md、本说明书、HTML 和测试。 |
scripts/manage_playbook.py | 检查行业 playbook 状态并生成 candidate 草案。 | 分析智能体、维护者 | 同步生命周期文档和注册表测试。 |
scripts/render_report.py | 读取 JSON、唯一增强 Markdown 和图表目录;先把遗漏图表引用补回对应步骤,再生成 base64 单文件 HTML。默认拒绝 strict 未通过的正式渲染;草稿预览须显式 --allow-draft。 | 分析智能体 | 同步 article_report.py、产物校验和报告测试。 |
scripts/validate_artifacts.py | 最终产物门禁:JSON、Markdown、HTML 必须存在,charts/ 至少一张图,且每张图均在 Markdown 引用并在 HTML 内嵌。 | render_report.py 自动调用 | 任何缺失、漏引或漏嵌入均返回失败。 |
scripts/build_report_site.py | 构建按公司和报告期分组的静态站点目录、索引、安全响应头和发布清单。 | publish_report.py、维护者 | 目录规则变化时同步 Cloudflare 发布说明和测试。 |
scripts/publish_report.py | 先读取同名或 --data 指定 JSON,只有 strict 通过且无阻塞项才检查重复并调用 Wrangler;草稿一律拒绝。 | 分析智能体 | 覆盖规则或项目配置变化时同步发布章节和测试。 |
| 核心模块 | 职责 |
|---|---|
stock_analyzer/models.py | 财务、行情、估值、分红等结构化数据模型。 |
normalize.py / periods.py / paths.py | 证券身份标准化、报告期路由和路径解析。 |
verify.py / strict_rules.py | 双源核验、差异判定和严格模式拦截。 |
industry.py | 行业自动识别和行业专项指标采集;这是指标功能真正落地的代码层。 |
bank_calculations.py | 银行确定性计算层:完整归母净利润桥、三档资产质量压力测试、多阶段剩余收益/PB-ROE、DDM D0/D1、分组同业回归、价格条件与股息率阶梯;输出写入 JSON 的 bank_calculations,审计时重新计算比对。 |
playbook_registry.py | 读取行业注册表,解析 active、candidate 与 fallback。 |
baseline_store.py | 检查、创建、更新和读取年度研究 baseline。 |
pdf_extractor.py | 从官方报告 PDF 中补充银行等专项指标,并参与交叉核验。 |
buffett_judge.py / porter.py / competition_policy.py | 六维质量评分、波特五力(通用兜底)和竞争分析行业路由(网络效应/监管框架/集采管线)。 |
report_planner.py | 根据周期和用户指定步骤生成本次 report_plan。 |
report_generator.py / report_sections.py | 生成结构化数据预览使用的自动 Markdown;不替代正式增强 Markdown。 |
html_report.py | 结构化数据预览看板渲染器。 |
article_report.py | 正式文章型 HTML 渲染器:章节锚点、Markdown 表格、Markdown 图片语法渲染(<figure><img>)和图表 base64 内嵌。 |
9.4 providers、tools 与 tests
| 路径 | 作用 |
|---|---|
scripts/stock_analyzer/providers/eastmoney.py | A股行情、财务摘要、三表明细和分红。 |
providers/xueqiu.py | A/H股行情和财务交叉验证来源。 |
providers/official_reports.py | 发现巨潮、港交所、SEC 等官方报告及报告期。 |
providers/market_data.py | 历史 K 线、基准指数和回撤数据。 |
providers/sec.py | 美股 SEC companyfacts、三表、分红和回购。 |
providers/akshare_provider.py | 港股财务数据补充来源。 |
scripts/tools/generate_charts.py | 生成通用财务、估值和股东回报图表。 |
scripts/tools/bank_report_extractor.py | 下载并提取银行报告中的专项指标。 |
scripts/tools/bank_charts.py | 生成 NIM、不良率、拨备、存贷比等银行专项图。 |
scripts/tools/fetch_lpr.py | 获取 LPR 历史,供银行息差背景分析。 |
scripts/review_report.py | 报告质量审计入口(report_review_framework):13 层框架的可执行门禁 + review_only/formal_report/publish_ready 模式。 |
scripts/tests/ | 周期、行业、核验、strict、baseline、报告、发布等自动测试;行为修改后必须补测试。 |
9.5 assets、状态数据、配置与输出
| 路径 | 作用 | 读写与安全边界 |
|---|---|---|
assets/article_report_template.html | 正式文章型 HTML 模板。 | article_report.py 读取;修改后做桌面和移动端视觉验证。 |
assets/report_template.html | 结构化数据预览看板模板。 | html_report.py 读取;不是正式分析正文来源。 |
baselines/ | 每家公司最近完整年报形成的研究基准。 | 程序读写;只有 annual_rebuild + step=all 可创建或覆盖。 |
config/cloudflare_pages.json | Pages 项目名、生产域名、分支和本地站点目录。 | 程序读取;site_dir 相对 STOCK_ANALYZER_OUTPUT_DIR 解析;不得保存 Cloudflare Token。 |
config/sec_company_tickers.json | SEC ticker 与 CIK 映射缓存。 | 美股 provider 读取,可重新获取。 |
config/lpr_history.json | LPR 历史缓存(工具 fetch_lpr.py 写入)。 | 工具读写,可重新生成,不属于正式报告。 |
env.txt 中 STOCK_ANALYZER_OUTPUT_DIR 指向的外部目录 | JSON、增强 Markdown、HTML、图表、Cloudflare Pages 本地站点和后续新增 artifact。 | 报告统一强制写入 <股票代码>-<公司名称>/<周期>/ bundle;公司名称缺失时回退到 <股票代码>/<周期>/;系统环境变量和 .env 不得覆盖。 |
reports-manifest.json | Cloudflare 已发布公司与周期的权威清单,用于重复检测和防误覆盖。 | 本地与线上共同校验;同公司同周期默认拒绝覆盖。 |
9.6 一次完整分析的数据流
SKILL.md + analysis_framework index + selected analysis_step_*.md + industry playbook
↓
analyze_stock.py
↓
providers → verify / strict → industry metrics → baseline
↓
结构化 JSON + 图表输入
↓
唯一增强 Markdown
↓
render_report.py → 补齐 Markdown 全量图表引用 → 单文件文章型 HTML
↓
validate_artifacts.py → JSON/Markdown/HTML/charts 全量门禁
↓
用户确认发布
↓
publish_report.py → Cloudflare Pages
10. 维护规则
- 修改周期路由时,同步更新
references/period_routing.md和本说明书。 - 修改 0-5 步方法论时,同步更新对应
references/analysis_step_*.md、references/analysis_framework.md索引和本说明书中相关段落。 - 修改输出 JSON 字段时,同步更新本说明书“输出 JSON 关键字段”。
- 修改 event_alert 或 monitor 协议时,同步更新本说明书“event_alert 机制”。
- 新增行业模板时先生成 candidate;未经用户确认和完整启用检查,不得写入 active 注册表。
- 修改 Markdown 报告段落时,禁止硬编码单家公司、单个案例或历史买卖动作;所有公司事实必须来自本次 JSON、baseline 或明确来源。
- 巴菲特视角段落只评价生意质量、护城河和管理层,不能代言“巴菲特会买/卖”,也不能输出买入价、仓位或回调阈值。
- 银行/金融企业评分与报告不得使用普通企业的资产负债率警戒线、OCF/净现比或 FCF 作为生意质量核心判断;应使用 ROE 稳定性、资本充足、资产质量、NIM、存款成本等银行口径。
--strict默认开启(数据完整性、银行风险穿透、指标口径、估值路由、比率公式、信用成本分子分母、本地绝对资源路径等),任一不过即 fail;需关闭时用--no-strict。- 2026-06-21 新增框架规则:①第1.5步最新季报边际验证(年报分析时Q1/Q3进主线);②估值信号一致性(概览/估值/总评措辞统一);③多模型冲突解释(PB-ROE vs DDM 分歧本质);④分红节奏拆分(中期+末期);⑤触发器式跟踪清单(正常区间/警戒信号);⑥分投资者类型结论;⑦政策性让利评分拆分(系统重要性正向 vs 定价约束负向);⑧发布前硬校验清单(通用14项+行业附加)。
- 估值图优先读取年度
year_end_price;缺失时必须回退到valuation_history,不能在已有估值历史时跳过第 3 步图表。 - 股东回报报告和图表按财年只保留一个每股分红值:优先使用东财财年合计,其他来源只做交叉校验,不能把同一年多个来源相加。
- 【硬性规则 #16】交付协议是强制行为,不是可选说明 —— 分析步骤全部完成后,必须执行:① 聊天正文 ② 图表生成 ③ 增强 Markdown ④ JSON ⑤ HTML ⑥ 产物完整性与全图引用校验 ⑦ 仅在 strict 通过时询问发布。
charts/每张交付图必须在 Markdown 引用并在 HTML 内嵌;草稿不得询问或执行发布。 - 【硬性规则 #17】跨周期口径分列规则(2026-06-21 新增,防 NIM/口径混用)—— 同一指标在不同财报周期(年报 vs 季报年化 vs 半年报)口径不同时,报告里必须分列标注。例:年报 NIM 1.28%、2026Q1 年化 1.29%,不得只写"NIM 1.29%",必须标注"2025FY 1.28%;2026Q1 年化 1.29%"。净息差(NIM)与净利差(spread)是两个不同指标,不得混用。违反 = report_review 第 1 层判高。
- 【硬性规则 #18】公式勾稽校验规则—— DDM/PB-ROE 必须可复算,偏差 >2% 判高;PB-ROE 矩阵必须由
valuation_math.py代码生成,ROE 情景围绕公司当前值和下行压力设置。银行信用成本必须展示分子、平均贷款分母、单位和期间。 - 【硬性规则 #19】评分一致性校验规则(2026-06-21 新增,防评分体系自相矛盾)—— 评分表总分=各项加总、评级=按标准表映射、不同评分体系(50分制/30分制/星级)必须分别标注分母,不得交叉引用。标题声明的总分必须与维度数×每项满分一致。违反 = report_review 第 7 层判高。
- 【硬性规则 #22】净利润归因禁用现金流因果(2026-06-21 新增)—— 禁止用 OCF 变化解释净利润变化。净利润下降必须先拆利润表七层(收入/毛利率/折旧摊销/费用率/税费/投资收益/减值)。OCF 只能放「盈利质量」段。违反 = strict_rules.check_net_income_attribution fail + report_review 第 2 层判高。
- 【硬性规则 #23】DCF 真实性门槛(2026-06-21 新增)—— 标题/正文写 DCF 必须含 7 要素(基准FCF双口径/5年预测/折现率/永续增长/终值/每股价值/敏感性矩阵),否则须声明"不采用完整DCF主估值"。戈登永续公式 FCF1/(COE-g) 不算真DCF。违反 = strict_rules.check_dcf_completeness fail。
- 【硬性规则 #24】回撤窗口口径(2026-06-21 新增)—— 回撤分析"近N年"须=当前上市地实际上市年数。回A不足10年写"A股上市以来",不写"近10年"。需更长历史须用另一上市地并单列币种/复权/汇率。违反 = strict_rules.check_drawdown_window fail。
- 【硬性规则 #25】行业路由 generic fallback 降级(2026-06-21 新增)—— 行业路由为 generic fallback 时禁止输出 annual_rebuild,须降级为 preliminary_review 并列明缺失指标;报告头部须输出结构化路由结果块;generic fallback 不得打9分以上。
- 【硬性规则 #26】最新季报边际验证规则(2026-06-21 新增)—— 年报分析的数据截止日晚于年报披露日且存在更新季报时,必须执行「第 1.5 步:最新季报边际验证」。季报指标必须标注口径(年化/单季/累计),禁止单季利润直接乘 4。
- 【硬性规则 #27】估值信号一致性规则(2026-06-21 新增)—— 报告所有位置的估值定性判断必须统一;多模型信号矛盾时必须输出综合定性结论 + 模型分歧本质解释 + 多模型对比表。统一用 🔴高估/🟠偏贵/🟡合理/🟢偏低估/🟢🟢显著低估 分级。
- 【硬性规则 #28】跟踪触发器规则(2026-06-21 新增)—— 总评必须含触发器式跟踪清单(跟踪项/正常区间/警戒信号/投资含义),不得只写"关注 XX"而不给阈值。银行业必含 NIM/ROE/核心一级资本充足率/逾期/地产不良/派息率/股息率。
- 【硬性规则 #29】发布前硬校验清单规则(2026-06-21 新增)—— 报告标记 publish_ready=true 前,必须逐项确认 report_review_framework.md §7「发布前硬校验清单」(通用14项 + 行业附加)全部通过。
- 【硬性规则 #30】同业对比样本数下限(2026-06-21 新增)—— 第二步竞争分析和第三步估值的同业样本数必须达下限:银行业 ≥8 家(3大行+3股份行+2区域行)、非银行 ≥5 家。样本不足时禁用「龙头/第一梯队/行业第一/显著领先」,降级为「处于前列/具备优势」。违反 = report_review 第 5 层判高。
- 【硬性规则 #31】投资结论总览前置(2026-06-21 新增)—— 报告正文第一段必须是「投资结论总览」(TL;DR),≤150 字,含 5 要素:公司类型/估值位置/买入区间/核心风险/仓位定位。不得从第零步商业模式直接开始。
- 【硬性规则 #32】评分一致性封顶(2026-06-21 新增)—— 最终评分必须先过封顶检查(report_review §8):分红口径错误→综合≤8.0、估值未闭环→估值≤8.0、资产质量未穿透→综合≤8.5、同业样本不足→竞争≤8.0、用市赚率→估值≤7.5、强判断无证据→竞争≤8.0。原始评分超封顶值时强制下调。
- 【硬性规则 #33】银行单阶段 PB-ROE 降级—— 单阶段 Gordon 只作稳态理论锚;ROE 下行或派息率与 g 不一致时改用多阶段剩余收益。主反推变量为长期 ROE,隐含 g 不作主解释。
- 【硬性规则 #34】银行利润与风险传导闭环—— 必须输出银行利润桥、资产质量→信用成本→ROE→PB 传导链,以及盈利/风险/资本回报三张压力表。
- 【硬性规则 #35】银行回撤评分拆分—— 分开评价基本面抗风险与股价抗跌/回撤,禁止用基本面稳健覆盖 40%-50% 级股价回撤事实。
- 【硬性规则 #36】银行利润桥金额与方向勾稽—— 每行必须含本期金额、上期金额、变动额、同比、对利润方向、解释和来源;NIM 与平均生息资产规模拆开,收入拆分需勾稽营业收入。金额或方向冲突即阻塞发布。
- 【硬性规则 #37】同比对象明确—— 同表出现多个指标时禁用裸“同比/同比增速”,必须写营收同比、归母净利润同比、EPS 同比等,并能由本期/上期复算。
- 【硬性规则 #38】银行估值隐含假设与股息率算术—— 合理价逐情景列长期 ROE/COE/g/派息率/BPS/PB/价格/股息率;价格触发表注明 DPS 口径并逐档复算,价格与股息率误差超过 0.1 个百分点即阻塞发布。安全边际不超过 20% 时,不得仅凭折价给出重仓/强买入。
- 【硬性规则 #39】银行资产质量三档压力测试—— 年度完整报告必须用不良率 +25bp/+50bp/+100bp 三档情景,传导到拨备缺口、税后利润、ROE、核心一级资本和分红;新增不良金额不得直接等同利润损失。
- 【硬性规则 #40】银行完整归母利润桥—— 利润桥必须覆盖经营成本、营业外、所得税和少数股东损益并闭环归母净利润;不得用未解释残差凑平。
- 【硬性规则 #41】银行估值结构化—— 多阶段ROE、DDM D0/D1、历史PB、同业PB-ROE、模型权重和价格条件全部来自
bank_calculations.valuation;手填即阻塞。 - 【硬性规则 #42】同业证据门槛—— 至少3家直接估值组、3家防御组、2家经营质量组具备PB/ROE;不足时禁用同业均值、PB溢价和散点结论。
- 【硬性规则 #43】回购证据门槛—— 回购金额、注销股数、注销状态、总股本占比和EPS/BPS影响缺失时,不得把回购作为加分项。
- 【硬性规则 #44】最终产物门禁—— Markdown、HTML、JSON 必须存在,
charts/非空且全图被 Markdown 引用、HTML 内嵌;任一失败不得结束交付。 - 【硬性规则 #3 更新】市赚率全行业禁用(2026-06-21 新增)—— 第三步估值不再含"市赚率(PE/ROE)",改用 PB ≈ PE × ROE 一致性校验。市赚率无量纲意义且 ROE 小数化易算错,全行业禁用。strict
check_earnings_yield_banned扫描拦截。 - 【硬性规则 #7a 新增】排名性形容词证据门槛(2026-06-21 新增)—— 使用「龙头/第一梯队/行业第一/最强/显著领先/绝对领先」必须紧跟排名证据(CR3/市场份额/同业散点/行业排名),否则降级为「处于前列/具备优势/相对较强」。strict
check_superlative_claims扫描拦截。 - 修改 HTML 报告字段、模板结构、tab 分组、图表嵌入方式时,同步更新
assets/report_template.html、html_report.py和本说明书。
11. HTML 分析报告
HTML 是正式输出物之一,用于完整阅读、归档和分享。正式报告是增强 Markdown 的文章型阅读器,保留连续正文、章节锚点和对应图表;结构化看板仅用于数据预览。
| 输出物 | 用途 | 存放目录(由 env.txt 的 STOCK_ANALYZER_OUTPUT_DIR 决定) |
|---|---|---|
| 聊天正文 | 当前智能体直接发送分析内容 | 不落盘(对话即交付) |
| JSON | 结构化数据和核验结果 | $STOCK_ANALYZER_OUTPUT_DIR/<股票代码>-<公司名称>/<周期>/<股票代码>_<周期>.json |
| PNG/SVG 图 | 图表素材 | $STOCK_ANALYZER_OUTPUT_DIR/<股票代码>-<公司名称>/<周期>/charts/ |
| 增强 Markdown | 正式分析正文和结论的唯一来源,同时用于聊天交付与 HTML 渲染。 | $STOCK_ANALYZER_OUTPUT_DIR/<股票代码>-<公司名称>/<周期>/<股票代码>_<周期>.md |
| HTML | 完整可读文章报告 | $STOCK_ANALYZER_OUTPUT_DIR/<股票代码>-<公司名称>/<周期>/<股票代码>_<周期>.html |
STOCK_ANALYZER_OUTPUT_DIR 只从 skill 目录下的 env.txt 读取;系统环境变量和 .env 不参与输出目录选择。缺少配置时程序立即报错,不回退到项目目录或临时目录。
公司名称不可用时,报告 bundle 回退为 $STOCK_ANALYZER_OUTPUT_DIR/<股票代码>/<周期>/。文件名始终保留股票代码前缀,便于脚本稳定处理。
所有 CLI artifact 参数只允许使用当前股票/周期 bundle 内的相对路径;绝对路径和 .. 逃逸会被拒绝。
python scripts/analyze_stock.py 601398 --name 工商银行 --period 2025FY --html
analyze_stock.py --html 生成结构化数据预览看板,用于检查 JSON、数据质量和图表归属。正式交付报告使用 scripts/render_report.py,模板为 assets/article_report_template.html,渲染器为 scripts/stock_analyzer/article_report.py。
正式报告采用“增强 Markdown + HTML 阅读器”模式。增强 Markdown 是唯一分析正文和结论来源;HTML 直接渲染同一份 Markdown,并增加核心指标摘要、章节锚点导航和章节图表。JSON 继续作为结构化数据与核验依据,但不得由 HTML 模板另写一份简版结论。
HTML 默认使用连续阅读布局:增强报告若以一级标题划分步骤则按一级标题建导航,否则回退二级标题;移动端导航变为顶部横向章节栏。渲染前会把 charts/ 中漏引图表补回对应步骤,随后全部以 data URI 写入 HTML。
python scripts/render_report.py \ --data 600036/2025FY/600036_2025FY.json \ --analysis 600036/2025FY/600036_2025FY.md \ --html-out 600036/2025FY/600036_2025FY.html \ --chart-dir 600036/2025FY/charts
正式渲染前先对增强 Markdown 执行 publish_ready 审计;JSON strict 或正文审计任一失败时,只有显式 --allow-draft 才能生成带草稿标识的预览。渲染完成后自动执行 validate_artifacts.py:JSON、Markdown、HTML 必须存在,图表目录非空,且全图完成 Markdown 引用和 HTML 内嵌。
| 组成 | 用途 |
|---|---|
| 页头摘要 | 公司、周期、市场、行业及股价、PE、PB、股息率、ROE、净利润。 |
| 章节导航 | 优先按增强 Markdown 的一级步骤标题生成锚点;无一级步骤时回退二级标题。 |
| 正文 | 完整渲染唯一 Markdown 分析,支持标题、列表、引用、代码和原生 HTML 表格。 |
| 章节图表 | 财务、估值、分红和回撤图自动嵌入对应章节,不另起图表页。 |
重点信号必须用文字和颜色双重表达:danger 为红色危险,warning 为琥珀关注,good 为绿色正常,neutral 为信息。普通企业净现比低于 0.8 应标红;银行/金融企业不以净现比作为核心风险红灯,应优先使用不良贷款率、拨备覆盖率、核心一级资本充足率和 NIM。
图表优先保证可读性:同一步只有一张图时占满内容区;图像生成时禁止因越界数据标签产生大面积空白。柱状图标签使用 point padding 或 bar_label,不使用固定数据值偏移。
12. Cloudflare Pages 发布
正式分析与 HTML 生成完成、产物校验通过且 strict_status=passed 后,固定询问:“报告已生成,是否需要发布到 Cloudflare Pages?发布后将获得公开访问链接。”草稿固定说明存在阻塞项,不得询问或执行发布。
站点固定项目为 stock-analysis-reports,生产域名为 https://stock-analysis-reports-4u0.pages.dev。报告按 /companies/{company_slug}/{period} 归档,公司报告列表位于 /companies/{company_slug}/reports。
Cloudflare Pages 本地站点目录由 config/cloudflare_pages.json 的 site_dir 指定,且必须位于 STOCK_ANALYZER_OUTPUT_DIR 下;默认是 $STOCK_ANALYZER_OUTPUT_DIR/cloudflare-pages。
发布状态由线上与本地 reports-manifest.json 共同校验。若同一公司、同一周期已存在,必须停止并询问:“Cloudflare Pages 已存在「{公司} {报告期}」报告:{现有链接}。是否覆盖?”只有用户明确确认后才能使用 --overwrite。
python scripts/publish_report.py \ --report 600036/2025FY/600036_2025FY.html \ --data 600036/2025FY/600036_2025FY.json \ --company-slug 600036-cmb \ --company-name 招商银行 \ --ticker SH600036 \ --period 2025fy \ --period-label "2025 年报" \ --check-only
发布只包含最终 HTML、目录页、安全响应头和公开报告清单;不得上传 JSON、Token、持仓或账户信息。Wrangler 使用 OAuth 凭据,Cloudflare 配置中不得保存 Token。