stock-deep-research

股票深度研究工具 v11 - 基于westock-data(腾讯自选股,主)+妙想API(辅)+问财API(补)的专业级研究报告生成器。 当用户要求分析某只股票、生成股票研究报告、进行股票深度研究时使用此技能。 一键执行:generate_report.py 自动完成采集→补充→生成→上传IMA。 报告以PDF文件上传到IMA知识库「行业公司报告」文件夹,本地文件自动删除。 关键特性:collector.py v8 westock-data为主数据源(免费无限制),妙想/问财自动备选。

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "stock-deep-research" with this command: npx skills add imeiming/stock-deep-research

股票深度研究报告

股票深度研究报告

基于同花顺问财 OpenAPI + 东方财富妙想API 的股票深度研究数据采集与报告生成工具。

使用场景

当用户说以下关键词时,使用此技能:

  • "分析XX股票"
  • "生成XX的研究报告"
  • "XX股票深度研究"
  • "XX股票分析"
  • "帮我看看XX"

快速开始(一键执行)

# 完整流程:采集(含全部补充)→生成报告→上传IMA(推荐)
python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业

# 跳过采集(已有JSON时)
python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业 --skip-collect

# 不上传IMA(仅本地生成)
python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业 --keep-local

generate_report.py v10 完整流程(4步,全部自动化)

Step 1: collector.py v8 采集全部数据
  - 基础采集(13模块,westock-data为主+妙想/问财备选)
  - 补充采集(已内置,自动运行):
    ✓ 历史季度累计数据(2024/2025年Q1-Q4)→ reporter自动计算单季度
    ✓ 运营效率(应收账款/存货/总资产周转率)→ 问财401时自动切妙想API
    ✓ 现金流(经营现金流/企业自由现金流)→ 同上
    ✓ 估值字段(市销率/股息率/营收同比/净利同比/加权ROE)
    ✓ 行业平均PE/PB
    ✓ 历史PE详细(5年每年最高/最低/平均,妙想API)
  → JSON文件(0个N/A)

Step 2: reporter_v6.py 生成报告
  → Markdown报告(v6模板13个完整模块)

Step 3: ima_integration.py 上传IMA
  → MD→PDF→COS→知识库

Step 4: 清理旧文件
  ✓ 删除 output/ 下旧JSON(保留最新)
  ✓ 删除 miaoxiang/mx_finance_data/ 下所有 .xlsx 和 _description.txt
```bash
# 完整流程:采集(含全部补充)→生成报告→上传IMA(推荐)
python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业

# 跳过采集(已有JSON时)
python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业 --skip-collect

# 不上传IMA(仅本地生成)
python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业 --keep-local

分步执行(调试用)

# 1. 采集数据(v8 westock-data为主)
python3 ~/.hermes/scripts/stock-research/collector.py -c 601899 -n 紫金矿业

# 2. 生成报告
python3 ~/.hermes/scripts/stock-research/reporter_v6.py \
  --json-path output/601899_紫金矿业_*.json \
  --output output/紫金矿业_深度研究报告.md

# 3. 上传IMA
python3 ~/.hermes/scripts/stock-research/ima_integration.py \
  --report-path output/紫金矿业_深度研究报告.md \
  --stock-name 紫金矿业 --stock-code 601899

数据覆盖度(v10 - 13模块+3补充模块,60+查询)

collector.py v6已直接集成13个模块的数据采集,无需额外手动调用mx-finance-data补充基础数据。

✅ collector.py 直接采集的数据(13个模块)

#模块查询数数据源技能
1报告摘要5hithink-finance-query + hithink-industry-query
2宏观与行业7hithink-industry-query + hithink-sector-selector
3公司基本面7hithink-finance-query + hithink-business-query
4公司治理与股东9hithink-management-query + hithink-business-query + news-search
5机构持仓与市场情绪4hithink-insresearch-query
6估值分析3hithink-finance-query
7重大事件与风险3hithink-management-query + hithink-business-query
8资金流向2hithink-sector-selector
9新闻资讯4news-search
10技术面3hithink-market-query
11营收结构与成本4hithink-business-query + hithink-finance-query
12杜邦分析与盈利质量3hithink-finance-query
13历史估值与同行对比3hithink-finance-query

总计:57个查询,13个模块全覆盖

✅ 仍可使用mx-finance-data补充的高级数据

数据项数据源技能调用方式
详细K线数据mx-finance-data--query "XX股票 近20日K线数据 MACD RSI KDJ"
历史估值详细mx-finance-data--query "XX股票 近5年市盈率PE最高最低平均"
宏观数据mx-macro-data--query "中国GDP增速 近5年"
金融资讯/研报mx-finance-search"XX股票 最新研报与公告"

⚠️ 仍无法获取的数据

数据项说明
ESG评级需要专门的ESG数据源

⚠️ 注意:collector.py v7 已内置全部补充查询(季度历史/运营效率/现金流/估值字段/历史PE/行业平均),大部分情况下无需额外调用mx-finance-data。

⛔ reporter_v6.py 零硬编码强制规则(2026-05-11 确立)

核心原则:reporter_v6.py中不得有任何"不管数据是什么都输出固定文字"的代码。

两层硬编码风险

层级表现危险程度检测方法
第一层:数据矛盾结论与上方数据不一致(如净流出写"净流入")📌结论逐条核对
第二层:公司绑定结论绑定到特定公司(如"黄金冶炼"对所有股票输出)极高grep公司特定关键词

第二层更危险:代码"运行正常"但对非目标公司输出完全错误结论。

禁止的写法

# ❌ 硬编码公司描述
w(f"- 行业地位:{sn},消费电子精密零组件龙头")
w("- 宏观环境:消费电子行业复苏,AI终端需求增长")
w("1. **AI终端驱动:** AI手机、AI眼镜等新品渗透率提升")
w("- 🚀 国际金价高位运行,黄金冶炼利润有保障")

# ❌ 硬编码通用模板
w("- ✅ 行业龙头地位,市场份额领先")
w("- ✅ 全球化布局完善,海外产能占比高")
w("**核心竞争壁垒:** 全球化壁垒+技术壁垒+客户壁垒+品牌壁垒")

必须的写法

# ✅ 从数据动态生成
mktcap_val = sf(mktcap)
if mktcap_val > 1000:
    w(f"- **行业地位:** {sn},所属行业大型企业")
elif mktcap_val > 300:
    w(f"- **行业地位:** {sn},所属行业骨干企业")
else:
    w(f"- **行业地位:** {sn},所属行业参与者")

# ✅ 从营收结构推断驱动因素
if rp:
    top1 = rp[0].get("项目名称", "核心业务")
    top1_pct = float(rp[0].get("业务收入", 0) or 0) / total_product_rev * 100
    w(f"1. **{top1}驱动:** 占收入{top1_pct:.1f}%,是业绩核心增长引擎")

# ✅ 从实际数据推断结论
pe_ratio = sf(pe) / sf(pe_iv) if sf(pe_iv) > 0 else 1
if pe_ratio > 1.5:
    w(f"- ⚠️ PE-TTM {pe}倍,显著高于行业均值{pe_iv}倍")

验证检查清单

# 1. 检查硬编码公司特定描述残留
grep -c "黄金\|锑品\|贵金属\|金价\|消费电子\|AI终端\|汽车电子\|全球化布局\|国产替代\|并购整合\|外延式" report.md
# 期望:仅剩分析师研报原文和真实人名(≤5处)

# 2. 检查📌结论是否与数据一致
grep '📌' report.md
# 逐条验证

# 3. 检查N/A和待确认
grep -c "待确认\|N/A" report.md
# 期望:0

修复详情:

  • 第一轮(2026-05-10):38处数据矛盾修复 → references/reporter-hardcoded-conclusion-fixes.md
  • 第二轮(2026-05-11):28处公司绑定修复 → references/reporter-hardcoded-conclusion-fixes-round3.md

已知Bug与修复记录

  1. safe_get函数默认值bugsafe_get(sections, "key1", "key2", "key3", [])[] 被当作key而非default,必须用 default=[] 关键字参数
  2. 股东字段名不一致大股东名称 vs 股东名称,需同时兼容两个字段名
  3. 持股比例字段名持股比例[20260331] vs 持股占流通股比例[20260331],需兼容
  4. croniter依赖:Hermes venv需要单独安装croniter包
  5. 季度数据缺口(2026-05-05,已修复):collector.py已直接采集季度财务数据(模块1),通过 quarterly_financials 查询获取。如仍需更详细的8季度历史数据,可用mx-finance-data补充。
  6. PDF中文乱码(2026-05-07,已修复):系统缺少中文字体,安装 fonts-noto-cjk + fonts-wqy-microhei 解决。CSS font-family 以 "Noto Sans CJK SC" 为首选。
  7. PDF emoji乱码(2026-05-07,已修复):weasyprint不支持彩色emoji,ima_integration.py自动将emoji替换为纯文本标记([OK]/[!]/[X])。

报告结构

生成的报告严格遵循以下框架:

  1. 报告摘要 - 核心投资逻辑、风险提示、目标价位
  2. 深度分析
    • 宏观环境与行业分析
    • 公司基本面分析(财务、治理、股东)
    • 估值分析(PE/PB/同行对比)
    • 技术面分析(需额外数据)
    • 风险与机会评估
  3. 投资建议 - 操作策略、入场/止损/目标价位

文件结构(v11 - 最终版)

/root/.hermes/scripts/stock-research/
├── generate_report.py     # v10 一键编排(4步:采集→生成→上传→清理)
├── collector.py           # v8 数据采集(westock-data为主+妙想/问财备选,13模块全覆盖)
├── reporter_v6.py         # v8.4 报告生成(JSON→固定格式MD,含sf()+季度计算+N/A安全处理)
├── ima_integration.py     # v2 IMA上传模块(MD→PDF→COS→知识库)
├── miaoxiang/             # 妙想API输出目录(每次成功后清理xlsx文件)
│   └── mx_finance_data/   # mx-finance-data输出(报告成功后必须清空)
├── output/                # 输出目录(上传后自动清理.md/.pdf,保留最新JSON)
└── README.md              # 说明文档

⚠️ 清理规则:每次成功生成报告后,删除 output/ 下旧JSON + miaoxiang/mx_finance_data/ 下所有xlsx和txt文件

collector.py v8 数据源策略(2026-05-08 确立,v8升级)

数据源优先级:westock-data(腾讯自选股)> 妙想API > 问财API
降级机制:query_with_fallback() 自动切换
westock-data适用场景:K线、财务报表、公司概况、股东结构、分红、资金流向、技术指标(免费无限制)
问财API适用场景:行业数据、机构研究、新闻资讯(妙想/westock覆盖不到的)

westock-data调用方式:通过 subprocess 调用 npx -y westock-data-skillhub@1.0.3 <command> <code>,解析返回的 Markdown 表格。

westock-data支持的命令:kline, finance, profile, shareholder, dividend, asfund, technical, search, minute, chip, lhb, blocktrade, margintrade, hot, board, calendar, ipo, etf

Pitfalls & 开发经验

⛔ P0 Critical: 季度财务数据缺口(已由generate_report.py v9自动修复)

问题描述: 报告中季度财务数据只有最新一期(如2026Q1),缺失历史季度数据。

根因: hithink-finance-query 查询季度数据时API只返回最新一期,不返回历史季度。

v9自动修复方案(generate_report.py已内置):

generate_report.py v9的Step 2a自动执行以下补充:

  1. 分两次查询获取2024年和2025年的累计数据
  2. 从累计值计算单季度值(Q1=累计, Q2=H1-Q1, Q3=9M-H1, Q4=FY-9M)
  3. 写入JSON的quarterly_cumulative字段
  4. reporter_v6.py自动读取并计算9个季度的单季度值

验证方法: 生成报告后,检查季度财务数据表格是否有9行数据(2024Q1-Q4 + 2025Q1-Q4 + 2026Q1)。


⛔ P0 Critical: 报告生成必须使用collector.py(数据质量事故教训)

问题描述(2026-05-04通富微电事故): 系统报告中股价写"约15元",实际为51.77元,偏差3.45倍!市值230亿 vs 实际800亿。

根因分析:

  • 报告是通过LLM手动调用mx-finance-data查询生成,没有使用collector.py
  • 无JSON数据文件,无法追溯数据来源
  • LLM解读API返回数据时产生幻觉(Hallucination)
  • 关键指标(股价、市值、资产负债率)全部错误

必须遵守的规则:

⛔ 禁止:直接调用mx-finance-data生成报告
✅ 必须:使用collector.py采集数据 → 生成JSON → 使用reporter_v6.py生成报告

验证方法: 生成报告后,检查output目录是否有对应的JSON文件。如果没有,说明数据质量不可靠。

数据验证清单(报告生成后必须执行):

指标合理范围异常处理
股价A股:5-500元低于5元或高于500元需人工核实
总市值与股本匹配市值/股本 应≈当前股价
资产负债率20-80%超出范围需核实数据口径
净利润增速-100% ~ +500%超出范围需核实

⛔ P0 Critical: 修改数据源时禁止修改数据采集模块结构(2026-05-08用户明确纠正)

用户原话:「数据模版不要修改 只修改数据源」

问题描述: 修改collector.py的数据源时,错误地修改了数据采集模块(collect_summary_data、collect_fundamental_data等)的内部结构,导致reporter_v6.py无法正确读取数据。

必须遵守的规则:

⛔ 禁止:修改collect_xxx_data()方法内部的section字典结构
⛔ 禁止:改变数据写入JSON的key路径(如 sections.1_报告摘要.current_price)
✅ 必须:只修改query_xxx()查询函数和query_with_fallback()降级逻辑
✅ 必须:新增数据源函数(如query_westock_xxx())时,保持返回格式与query_iwencai()一致:{success: bool, datas: [...], query: str}

正确做法:

  1. 新增数据源查询函数(如 query_westock_kline()
  2. 修改 query_with_fallback() 的降级顺序
  3. 数据采集模块内部结构完全不动

错误做法:

  • 修改 collect_summary_data()section["current_price"] 的赋值逻辑
  • 改变 self._add_section() 的调用方式
  • 重组JSON的section层级结构

⛔ P0 Critical: 行业竞争格局表格列对齐bug(2026-05-11正泰电器发现)

问题描述: 行业竞争格局表格中,同行公司的PE-TTM值被错误地放在了"最新价"列。

根因: peer_detailed数据中有最新价字段,但reporter_v6.py中行业竞争格局部分的代码没有提取该字段。

必须遵守的规则:

⛔ 禁止:表格列数与表头不匹配
✅ 必须:每列数据都对应表头中的字段
✅ 必须:添加新列时同步提取对应字段

修复方法:

ppl = v(pd.get("最新价"))  # 最新价
pp = v(pd.get(f"市盈率(pe,ttm)[{actual_date}]"))  # PE-TTM
ppb = v(pd.get(f"市净率[{actual_date}]"), "", 2)  # PB
pmk = v(pd.get(f"总市值[{actual_date}]"), "", 0)  # 市值
w(f"| {pn} | ¥{ppl} | {pp} | {ppb} | ¥{pmk}亿 | - |")

⛔ P0 Critical: 变量作用域导致UnboundLocalError(2026-05-11修复)

问题描述: 多个变量在定义前被使用,导致运行时崩溃:

  1. overseas_pct 在"国内宏观"使用但定义在"国际宏观"
  2. hny_trend 在表格行使用但定义在下一行
  3. pe_iv 在SWOT劣势使用但定义在估值分析部分

必须遵守的规则:

⛔ 禁止:变量在定义前使用
✅ 必须:高频计算的变量(如overseas_pct)提前到数据加载区域
✅ 必须:表格行中使用的变量(如hny_trend)在该行之前定义
✅ 必须:如果变量在后文才定义,在前文用局部变量从JSON直接提取

1. safe_get 默认参数陷阱

safe_get(data, "a", "b", "c", [{}]) 会把 [{}] 当作第4个key查找,而不是默认值。必须用关键字参数:

# ❌ 错误 — [{}] 被当作 key
safe_get(sections, "1_报告摘要", "current_price", "datas", [{}])

# ✅ 正确 — default 作为关键字参数
safe_get(sections, "1_报告摘要", "current_price", "datas", default=[{}])

2. 问财API字段名不统一

不同技能返回的同类数据字段名可能不同:

数据字段名1字段名2
股东名称股东名称大股东名称
持股比例持股占流通股比例[YYYYMMDD]持股比例[YYYYMMDD]
行业分类所属同花顺行业所属同花顺二级行业

解决方案:get_field(item, "字段1", "字段2", default="N/A") 做多字段回退。

3. hithink-sector-selector 的双重用途

hithink-sector-selector 可以同时查询:

  • 行业估值(PE/PB分位点):"{行业} 行业PE 行业PB 估值分位"
  • 资金流向(主力/大单):"{股票} 主力资金净流入 资金流向"
  • 北向资金:"{行业} 北向资金 净买入"

4. news-search API 端点不同

新闻搜索使用 /v1/comprehensive/search,不是 /v1/query2data。请求体结构也不同:

# 数据查询(其他技能)
{"query": "...", "page": "1", "limit": "10"}

# 新闻搜索(news-search)
{"channels": ["news"], "app_id": "AIME_SKILL", "query": "..."}

5. QQ Bot附件文件位置(2026-05-04验证)

QQ Bot会自动下载用户发送的附件到本地:

  • 路径~/.hermes/cache/documents/
  • 文件名格式doc_{uuid12}_{原始文件名}(如 doc_17de7c238669_通富微电.md
  • 查找命令find ~/.hermes/cache/documents/ -name "*.md" -mmin -30

注意:不要在 /tmp 或其他位置查找,QQ Bot附件固定存储在上述路径。

6. mx-finance-data数据解读陷阱

mx-finance-data返回的xlsx数据中:

  • 股价可能是除权除息价,不是当前市价
  • 财务数据可能是合并报表母公司报表,需注意口径
  • 字段名包含日期后缀(如 收盘价[20260430]),表示该日期的数据

建议:始终用 最新价 字段获取当前股价,不要用历史日期字段。

9. company_overview字段可能是Python列表(2026-05-08紫金矿业发现)

问题: company_overview 中的 主营产品 字段返回的是Python列表 ['产品A', '产品B', ...],直接输出会显示为 ['产品A', '产品B'] 格式。

解决方案:

products = co.get('主营产品', [])
if isinstance(products, list):
    products_str = '、'.join(products)
else:
    products_str = products

10. 营收结构必须包含营业收入金额+毛利率(2026-05-08用户明确要求)

用户原话: 「主营业务销售占比部分必须同时包含营业收入金额和毛利率,当前报告只有利润率(毛利率)没有营业收入」

正确格式:

| 业务板块 | 营业收入(亿) | 收入占比 | 毛利率 | 利润占比 |
|---------|-------------|---------|--------|---------|
| 产品A   | 123.45      | 45.2%   | 33.9%  | 50.1%   |

错误格式(缺少营业收入):

| 业务板块 | 毛利率 | 利润占比 |
|---------|--------|---------|

8. weasyprint PDF中文乱码(2026-05-07紫金矿业事故)

问题描述: 生成的PDF在IMA客户端显示为□□□□方块乱码,中文全部无法识别。

根因分析:

  • 系统未安装CJK中文字体,weasyprint无法渲染中文
  • ima_integration.py CSS中 font-family 首选 SimSun(Windows字体),Linux上不存在
  • 即使安装了字体,字体名拼写或顺序错误也会导致fallback失败

必须遵守的规则:

✅ 必须:系统安装 fonts-noto-cjk 和 fonts-wqy-microhei
✅ 必须:ima_integration.py CSS中 font-family 以 "Noto Sans CJK SC" 开头
✅ 必须:安装字体后执行 fc-cache -f 刷新字体缓存
⛔ 禁止:CSS中首选 SimSun/SimHei 等Windows专有字体

修复方法:

# 1. 安装CJK字体
apt-get install -y fonts-noto-cjk fonts-wqy-microhei

# 2. 刷新字体缓存
fc-cache -f

# 3. 验证字体可用
fc-list :lang=zh | head -3

ima_integration.py CSS正确配置:

body { font-family: "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; }

验证方法: 生成PDF后用 pdftotext 提取文本,确认包含中文字符。或直接在IMA客户端预览确认无乱码。

7. sf()安全浮点转换 + f-string中float("N/A")崩溃(2026-05-08紫金矿业事故)

问题描述: reporter_v6.py在f-string中使用 float(ps or 0) 做比较,当 ps="N/A" 时,"N/A" 是truthy字符串,or 0 不生效,float("N/A") 抛出ValueError崩溃。

根因: Python中 "N/A" or 0 返回 "N/A"(非空字符串为truthy),不是0。

必须遵守的规则:

⛔ 禁止:在f-string中直接写 float(var or 0) — 当var="N/A"时会崩溃
✅ 必须:使用 sf() 安全转换函数

sf()函数定义(reporter_v6.py已内置):

def sf(val, default=0.0):
    """安全浮点转换,N/A/None/空字符串返回default"""
    if val is None or val == "N/A" or val == "":
        return default
    try:
        return float(str(val).replace('%', '').replace(',', ''))
    except (ValueError, TypeError):
        return default

用法:

# ❌ 错误 — var="N/A"时崩溃
f"{'偏高' if float(ps or 0) > 3 else '合理'}"

# ✅ 正确 — sf()安全处理N/A
f"{'偏高' if sf(ps) > 3 else '合理'}"

使用流程(v10 - 最终版)

generate_report.py v10 自动执行(3步):
  Step 1: collector.py v7 采集全部数据(13模块+3补充模块,~60秒)
  Step 2: reporter_v6.py v8.2 从JSON生成固定格式MD报告
  Step 3: ima_integration.py v2 转PDF上传IMA

一键执行:

python3 ~/.hermes/scripts/stock-research/generate_report.py -c 601899 -n 紫金矿业

collector.py v7 已内置全部补充查询,无需手动调用mx-finance-data reporter_v6.py v8.2 保证相同JSON输入=相同MD输出 Agent不再手写报告,完全由脚本生成,消除人为差异

妙想技能集成(v3新增)

已安装14个妙想金融技能(路径:~/.hermes/skills/miaoxiang/),可补充以下数据:

# 技术面数据(K线、MACD、RSI、KDJ)
export EM_API_KEY="em_5BXZUDwGSFOli2ITXe0b4WhHjOsZMJSo"
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py --query "贵州茅台 近20日K线数据 MACD RSI KDJ"

# 历史估值区间
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py --query "贵州茅台 近5年市盈率PE最高最低平均"

# 宏观数据
python3 ~/.hermes/skills/miaoxiang/mx-macro-data/scripts/get_data.py --query "中国GDP增速 近5年"

# 金融资讯
python3 ~/.hermes/skills/miaoxiang/mx-finance-search/scripts/get_data.py "贵州茅台 最新研报与公告"

完整配置见:~/.hermes/skills/miaoxiang/CONFIG.md

报告模版 (v8 - 专业机构级)

基于三花智控(002050)、三安光电(600703)、卧龙电驱(600580) 三份报告合并确立的标准模板v8。详见 references/merged-report-template.md

用户提供的标准研究报告模版包含以下完整框架:

核心投资逻辑部分必须包含:

📊 股价与估值概览

  • 最新股价、总市值、PE-TTM、PB、股息率

📈 最新季度财务数据

  • 营业收入(及同比增长)
  • 归母净利润(及同比增长)
  • 扣非净利润
  • 毛利率(对比行业平均)
  • 净利率(对比行业平均)
  • ROE(Q1)
  • 资产负债率

📅 季度财务数据明细

  • 最近8个季度的营收/净利润/扣非净利润表格

📊 近三年全年财务数据

  • 最近三年的全年营收/净利润/扣非净利润
  • 营收趋势分析

🏭 行业平均指标对比

  • 毛利率 vs 行业平均
  • 净利率 vs 行业平均
  • ROE(Q1) 评估
  • 资产负债率评估

💡 核心投资逻辑总结

  1. 盈利能力分析
  2. 成长性分析
  3. 财务健康分析
  4. 股东回报分析
  5. 估值水平分析

完整报告框架:

一、报告摘要(Executive Summary)
  - 核心投资逻辑(Key Investment Thesis)- 包含上述所有指标
  - 核心风险提示(Key Risk Factors)
  - 目标价位与周期(Target Price & Horizon)
  - 目标投资者画像(Target Investor Profile)

二、深度分析(In-Depth Analysis)
  1. 宏观环境与行业分析(国内和国际分开)
  2. 公司基本面分析
     - 公司概况与商业模式
     - 财务健康状况(盈利/营运/偿债/成长/现金流)
     - 公司治理与股东情况
     - 机构持仓与市场情绪
  3. 估值分析(绝对估值+相对估值)
  4. 技术面分析(日线/周线/趋势/形态/指标/量价)
  5. 风险与机会综合评估

三、明确的投资建议与操作策略
  - 入场策略/仓位建议/止损策略/目标价位

数据来源与时效性说明

实战验证记录

测试股票:贵州茅台(600519)

  • 采集时间:2026-05-04
  • 查询成功率:36/36(100%)
  • 数据覆盖:9大模块全部成功

测试股票:通富微电(002156)

  • 采集时间:2026-05-04
  • 使用技能:mx-finance-data + mx-macro-data + mx-finance-search
  • 报告输出:完整研究报告(含财务/宏观/行业/技术面/资金流向/机构评级/新闻)
  • 数据覆盖率:100%

已验证的mx-finance-data查询语句(补充数据用)

以下查询仅在需要更详细数据时使用,collector.py已覆盖大部分基础数据。

# 基础财务数据(补充详细K线)
--query "通富微电 002156 最新股价 市盈率 市净率 营业收入 净利润 毛利率 ROE"

# 详细K线数据(20日)
--query "通富微电 002156 近20日K线 MACD RSI KDJ"

# 历史估值详细
--query "通富微电 002156 近5年市盈率PE最高最低平均"

collector.py 新增模块(13模块全覆盖 - 2026-05-06)

collector.py直接集成13个模块的数据采集,无需额外手动调用mx-finance-data:

# 模块10:技术面分析(新增)
section["technical_indicators"] = query_iwencai("market",
    f"{self.stock_name} RSI MACD KDJ 布林带", limit="1")
section["support_resistance"] = query_iwencai("market",
    f"{self.stock_name} 支撑位 压力位", limit="1")
section["kline_20d"] = query_iwencai("market",
    f"{self.stock_name} 近20日K线 成交量 成交额", limit="20")

# 模块11:营收结构与成本分析(新增)
section["revenue_by_product"] = query_iwencai("business",
    f"{self.stock_name} 按产品营收 收入构成 毛利率", limit="10")
section["revenue_by_region"] = query_iwencai("business",
    f"{self.stock_name} 按地区营收 国内国外收入", limit="5")
section["rd_investment"] = query_iwencai("finance",
    f"{self.stock_name} 研发费用 研发投入占比 专利", limit="5")
section["capacity"] = query_iwencai("business",
    f"{self.stock_name} 产能 产量 利用率 扩产", limit="5")

# 模块12:杜邦分析与盈利质量(新增)
section["dupont"] = query_iwencai("finance",
    f"{self.stock_name} ROE 净利率 总资产周转率 权益乘数", limit="1")
section["earnings_quality"] = query_iwencai("finance",
    f"{self.stock_name} 扣非净利润 非经常性损益 经营现金流净利润比", limit="1")
section["growth_trend"] = query_iwencai("finance",
    f"{self.stock_name} 近三年营收增速 净利润增速 ROE变化", limit="3")

# 模块13:历史估值与同行对比(新增)
section["pe_history_5y"] = query_iwencai("finance",
    f"{self.stock_name} 近5年市盈率PE最高最低平均", limit="5")
section["pb_history_5y"] = query_iwencai("finance",
    f"{self.stock_name} 近5年市净率PB最高最低", limit="5")
section["peer_detailed"] = query_iwencai("finance",
    f"{self.stock_name} 同行业对比 PE PB 市值 营收 净利润", limit="10")

注意:需要在SKILLS配置中添加 market 技能类型(hithink-market-query)。


已验证的mx-macro-data查询语句

--query "中国GDP增速 近5年"
--query "中国GDP增速 CPI"
--query "中国CPI 近3年"

已验证的mx-finance-search查询语句

"通富微电 最新研报与公告"
"通富微电 002156 最新公告研报"
"贵州茅台 最新研报与公告"

已验证的mx-stocks-screener查询语句

--query "股价大于100元,主力流入" --select-type A股
--query "白酒主题基金" --select-type 基金

已验证的mx-financial-assistant查询语句

# 标准模式
--query "用户问题"

# 深度思考模式
--query "用户问题" --deep-think

关键发现与经验

1. v10架构:collector.py内置全部补充

collector.py v7 已将所有补充查询直接写入,无需外部补充脚本。generate_report.py v10 只是薄编排层。

2. 零N/A原则

报告中不允许出现任何N/A值。collector.py v7 通过内置补充查询确保数据完整。生成后必须 grep "N/A" 验证。

3. 问财API限流

连续大量查询后问财API可能返回401。collector.py v7 的运营效率查询有妙想API自动备选。

4. 字段名不一致

不同API返回的字段名可能不同(如 市销率[20260506] vs 市销率[20260507])。reporter_v6.py v8.2 使用多字段回退处理。

5. sf()安全浮点转换

f-string中 float("N/A" or 0) 会崩溃。reporter_v6.py v8.2 内置 sf() 函数处理所有N/A安全转换。

报告对比与完善工作流

当用户提供外部报告(来自其他AI工具)要求完善系统报告时,使用以下流程:

步骤

  1. 定位外部报告文件:检查 ~/.hermes/cache/documents/ 目录(QQ Bot附件自动下载位置)
    • 文件名格式:doc_{uuid12}_{原始文件名}
    • find ~/.hermes/cache/documents/ -name "*.md" -mmin -30 查找最近的文件
  2. 读取两份报告:系统旧报告 + 外部新报告
  3. 生成差异分析:逐章节对比,列出新报告独有的数据/观点/分析
  4. 修正错误数据:特别注意股价、市值、资产负债率等核心数据
  5. 整合完善:将新报告的有价值信息整合到旧报告中,生成V2版本
  6. 输出:保存到 output/<股票名称>_深度研究报告_v2.md

差异分析关注点

  • 数据修正:股价、市值、利润率、负债率等核心指标是否一致
  • 信息增量:目标价、PEG、国际竞争格局、股东变动、催化剂时间窗口
  • 分析深度:护城河分析、盈利模式拆分、技术面具体点位
  • 保留优势:旧报告中更详细的表格、数据来源验证等

数据验证要点

⚠️ 报告可能出现数据错误,必须与最新数据交叉验证:

  • 股价:使用 mx-finance-data 查询最新价
  • 财务数据:核对最新季报/年报
  • 估值指标:PE/PB/PEG 需要与同行对比验证
  • 验证方法:检查output目录是否有JSON数据文件,确保数据来源可靠

技能打包与发布到GitHub

当需要将股票研究功能作为独立技能发布时,使用以下流程:

打包结构

hermes-stock-research/
├── SKILL.md                 # Hermes技能说明文档
├── README.md                # GitHub项目说明
├── LICENSE                  # MIT License
├── .gitignore               # 忽略output/*.json等敏感数据
├── requirements.txt         # Python依赖
├── scripts/
│   ├── collector.py         # 数据采集脚本(13模块)
│   └── ima_integration.py   # IMA上传脚本
├── examples/
│   └── <股票名称>_深度研究报告.md  # 示例报告
└── output/
    └── .gitkeep             # 输出目录占位

发布步骤

# 1. 创建目录并复制文件
mkdir -p /tmp/hermes-stock-research/{scripts,examples,output}
cp /root/.hermes/scripts/stock-research/{collector.py,ima_integration.py} /tmp/hermes-stock-research/scripts/
cp /root/.hermes/scripts/stock-research/output/*_深度研究报告.md /tmp/hermes-stock-research/examples/
touch /tmp/hermes-stock-research/output/.gitkeep

# 2. 创建SKILL.md、README.md、LICENSE、.gitignore、requirements.txt

# 3. 初始化git并推送
cd /tmp/hermes-stock-research
git init && git branch -m main
git add -A && git commit -m "feat: 初始化Hermes股票深度研究技能"
gh repo create hermes-stock-research --public --source . --push

# 4. 添加标签(可选)
gh repo edit imeiming/hermes-stock-research --add-topic "stock,finance,python,iwencai"

SKILL.md 格式要求

  • 必须以 --- 开头(无前导空行)
  • 必须包含 namedescription 字段(description ≤ 1024字符)
  • 推荐包含 versionauthorlicensemetadata.hermes.tags
  • body部分非空

注意事项

  • output/*.json 包含API返回的原始数据,应加入 .gitignore
  • 示例报告应选择数据完整的报告,展示报告质量
  • 如有敏感API Key,不要硬编码,使用环境变量说明

IMA知识库集成 (v2 - PDF文件上传)

更新于 2026-05-07:从笔记上传改为PDF文件上传,本地.md文件生成PDF后直接以文件形式上传到知识库

生成报告后,自动转为PDF并上传到IMA知识库「行业公司报告」文件夹。

上传流程

生成报告(MD) → weasyprint转PDF → COS上传 → IMA知识库 → 删除本地文件

ima_integration.py v2 功能

功能说明
MD→PDF转换使用weasyprint生成专业排版PDF
Emoji清理自动将emoji替换为纯文本标记([OK]/[!]/[X]),防止PDF乱码
重名检测自动检测同名文件,添加时间戳
COS上传通过IMA临时凭证上传到COS
添加知识库自动添加到「行业公司报告」文件夹
删除本地文件上传成功后自动删除.md和.pdf

使用方式

python3 /root/.hermes/scripts/stock-research/ima_integration.py \
  --report-path output/紫金矿业_深度研究报告.md \
  --stock-name 紫金矿业 \
  --stock-code 601899

系统依赖(必须安装)

# 中文字体(weasyprint渲染中文必须)
apt-get install -y fonts-noto-cjk fonts-wqy-microhei

# Python依赖
pip install weasyprint markdown

⚠️ 系统默认没有中文字体,不安装会导致PDF全部显示为□□乱码

Emoji处理规则

weasyprint不支持彩色emoji渲染,会导致PDF显示为⊠框框。ima_integration.py会自动将emoji替换为纯文本:

原始emoji替换为说明
[OK]成功/通过
⚠️[!]警告/风险
[X]失败/不适合
⭐ 🌟*星级
📊📈📅等(移除)装饰性emoji直接移除

IMA知识库集成 (v2 - PDF文件上传)

报告生成后自动转为PDF,以文件形式上传到IMA知识库「行业公司报告」文件夹。

自动化流程

生成报告(MD) → weasyprint转PDF → COS上传 → IMA知识库 → 删除本地文件

ima_integration.py v2 关键参数

# 目标知识库
KB_ID = "W80hJmK98SC2GTUlPtnKK6MyKBE75MwMqFBJK8z0wyo="

# 目标文件夹
TARGET_FOLDER_ID = "folder_7403588502444840"

# 上传流程
1. preflight-check.cjs → 检查文件类型
2. check_repeated_names → 检查重名(自动添加时间戳)
3. create_media → 创建媒体,获取COS凭证
4. cos-upload.cjs → 上传PDF到COS
5. add_knowledge → 添加到知识库

⚠️ 已删除旧的笔记上传方式(md_to_ima.py),统一使用PDF文件上传

⛔ 禁止发送文件给用户(用户明确要求)

用户原话:「之前不需要发送文件的 怎么这次发送文件给我了」

生成报告后:

  • ✅ 只报告「已上传到IMA知识库」+ 文件名
  • ✅ 提供关键数据摘要
  • ❌ 不要用 MEDIA: 发送文件给用户
  • ❌ 不要用 send_message 发送文件

报告上传到IMA后,本地.md和.pdf文件自动删除(ima_integration.py 默认行为)。


24. reporter_v6.py 硬编码结论与数据矛盾(2026-05-10湖南黄金事故)

问题描述: reporter_v6.py中大量结论文字是硬编码的,不管实际数据如何都输出固定结论。用户发现资金流向数据为负(净流出)但结论写"主力资金净流入,市场看好",引发全面排查。经两轮修复,共修复38处硬编码结论。

第一轮修复(15处)— 数据与结论矛盾:

#位置硬编码内容实际应为
1-2资金流向(行业+个股)"主力资金净流入,市场看好"根据数值正负判断净流入/净流出
3ROE判断"盈利能力强"根据ROE>15/8/0分档
4估值分析"当前PE高于行业均值"与行业PE对比后判断
5成长分析"净利润连续高增长"根据近三年增速判断
6偿债分析"处于合理水平"根据资产负债率分档
7营运分析"处于行业合理水平"根据总资产周转率分档
8现金流分析"现金创造能力强"根据经营现金流/净利润比值判断
9法律风险"法律风险较低"根据涉诉/处罚数量判断
10评级分布"市场看好"根据实际评级统计
11-12营收/净利增速"放缓"/"强劲回升"根据相邻年份增速趋势判断
13-15风险提示(3处)"营收增速放缓"根据实际增速>20/0/<0分档

第二轮修复(23处)— 通用模板文字与公司实际不符:

#位置硬编码内容问题
1核心驱动因素"全球化布局/并购整合/行业景气"不是所有公司都有全球化布局和并购
2国内宏观环境"产业升级/国产替代"通用文字,不反映行业特性
3国际宏观环境"海外产能布局成效显现"湖南黄金海外收入仅0.39%
4行业驱动因素"国产替代加速/需求旺盛"贵金属行业驱动是金价+资源
5竞争格局硬编码"行业龙头"不是所有公司都是龙头
6公司概况"全球布局:中国、海外多国"应从实际地区数据提取
7历史沿革"外延式并购扩张"应反映公司真实历史
8营收结构结论"核心业务是收入主要来源"应根据实际占比描述
9竞争格局总结"技术优势和规模效应"应根据市值/地位判断
10产业链地位"行业龙头,覆盖全产业链"应根据实际业务描述
11SWOT优势5条通用模板应根据实际财务数据生成
12SWOT机会"行业景气度/产业升级"应反映行业真实驱动
13机构认可度"认可度高"应根据持股比例判断
14行业周期"部分领域具有成长属性"应反映行业真实周期特征
15趋势判断"趋势向好/长期看好"应根据RSI/涨跌幅判断
16情景分析"行业景气超预期"应用公司具体假设
17催化剂"新产品/海外客户"应用公司具体催化剂
18投资逻辑"行业龙头+全球化+并购"应反映公司真实竞争力
19风险矩阵"行业竞争加剧"应用公司具体风险
20目标投资者"看好行业发展趋势"应反映公司具体特征
21风险应对"等待PE回调/分散投资"应根据当前数据动态生成
22估值消化"高于/接近行业均值"应根据PE/行业PE比值判断
23行业规模"新兴应用领域需求旺盛"应反映行业真实情况

必须遵守的规则:

⛔ 禁止:reporter_v6.py中使用硬编码结论文字
⛔ 禁止:使用通用模板文字(如"全球化布局""并购整合""行业龙头")
✅ 必须:所有结论性文字根据实际数据动态生成
✅ 必须:数值型结论用条件判断(if sf(x) > threshold)
✅ 必须:趋势型结论用相邻数据对比(如增速加速/放缓)
✅ 必须:分类统计型结论用计数(如评级:买入count vs 卖出count)
✅ 必须:公司描述从实际数据提取(主营产品、地区收入、市值排名等)

验证方法(必须执行): 生成报告后,执行以下检查:

# 1. 检查是否有硬编码通用文字残留
grep -c "全球化布局\|并购整合\|外延式扩张\|国产替代\|行业龙头\|协同效应\|海外产能占比高" report.md
# 期望结果:0

# 2. 检查📌结论是否与数据一致
grep '📌' report.md
# 逐条检查:资金流向净流入/净流出是否与数值正负匹配、估值与行业均值对比是否准确

# 3. 检查是否有"待确认"或N/A
grep -c "待确认\|N/A" report.md
# 期望结果:0

详细修复清单:references/reporter-hardcoded-conclusion-fixes.md


22. reporter_v6.py pe_iv N/A 崩溃(2026-05-08湖南黄金事故)

问题描述: reporter_v6.py 在估值消化测算中使用 float(pe_iv or 20) 格式化字符串,当 pe_iv="N/A" 时,"N/A" 是truthy字符串,or 20 不生效,float("N/A") 抛出 ValueError 崩溃。

根因: Python中 "N/A" or 20 返回 "N/A"(非空字符串为truthy),不是20。

修复方法(已应用到reporter_v6.py v8.3):

# ❌ 原代码(崩溃)
w("- 若PE回归至合理区间({:.0f}-{:.0f}倍)".format(float(pe_iv or 20), float(pe_iv or 30) * 1.2))

# ✅ 修复后
pe_iv_val = 20 if pe_iv == 'N/A' or not pe_iv else float(pe_iv)
w(f"- 若PE回归至合理区间({pe_iv_val:.0f}-{pe_iv_val * 1.2:.0f}倍)")

必须遵守的规则:

⛔ 禁止:在f-string/格式化中直接写 float(var or default) — 当var="N/A"时会崩溃
✅ 必须:先检查 var == 'N/A' 或 not var,再转换为float
✅ 必须:或使用 sf() 安全转换函数

19. 妙想API数据格式导致reporter_v6.py崩溃(2026-05-08洛阳钼业事故)

问题描述: 妙想API返回的Excel数据带有单位后缀(如"113.3亿元""22.88%"),直接写入JSON后reporter_v6.py在f-string中对这些字符串做数学运算时崩溃。

报错示例:

ValueError: could not convert string to float: '113.3亿元'
ValueError: Unknown format code 'f' for object of type 'str'

必须遵守的规则:

⛔ 禁止:直接将妙想API返回的带单位字符串写入JSON
✅ 必须:写入JSON前用clean_number()去掉单位后缀,转换为float/int
✅ 必须:clean_number()处理 '亿元'、'%'、'次'、'倍'、',' 等后缀

clean_number()实现:

def clean_number(value):
    if value == 'N/A' or value is None:
        return None
    s = str(value)
    s = re.sub(r'[亿元次倍%]', '', s)
    s = s.replace(',', '')
    try:
        num = float(s)
        return int(num) if num == int(num) else num
    except:
        return None

验证方法: JSON生成后执行 grep -c '"N/A"' output/*.json 检查N/A数量,确认数值字段类型正确。


20. 妙想API字段名与reporter_v6.py期望不一致(2026-05-08洛阳钼业事故)

问题描述: 妙想API返回的字段名与reporter_v6.py中硬编码的字段名不一致,导致大量N/A。这是手动补充数据时最耗时的问题(20+轮patching)。

字段名映射表(已验证):

reporter_v6.py期望妙想API实际返回影响模块
市盈率(pe,ttm)[20260507]市盈率PE(TTM)current_price
销售净利率[20260331]净利润/营业总收入fundamentals_snapshot
净资产收益率[20260331]净资产收益率ROEdupont
扣非归母净利润[YYYYMMDD]扣非净利润 / 扣除非经常性损益后归属于母公司股东的净利润quarterly_cumulative
归母净利润同比增长率净利润同比financial_history
营业收入同比增长率营收同比financial_history
经营活动产生的现金流量净额[20260331]经营现金流earnings_quality
研发支出[20260331] / 营业收入[20260331]研发费用占比rd_investment
加权净资产收益率[20260331]净资产收益率ROE(加权)fundamentals_snapshot

必须遵守的规则:

⛔ 禁止:假设妙想API返回的字段名与reporter_v6.py一致
✅ 必须:写入JSON前将妙想API字段名重命名为reporter_v6.py期望的格式
✅ 必须:参考上方映射表进行字段名转换

21. 妙想API与问财API同时限流的应急方案(2026-05-08发现,2026-05-08更新)

问题描述: 两个API可能同时达到使用上限:

  • 问财API:返回 HTTP Error 401: Unauthorized
  • 妙想API:返回 code=403, message=使用次数已达上限
  • 东方财富直接API:返回 RemoteDisconnected 连接被拒

应急方案(按优先级):

✅ 方案1:等待API配额重置(通常24小时)
✅ 方案2:使用之前已成功采集的JSON数据(如已有同股票的历史数据)
✅ 方案3:使用generate_report.py的--skip-collect参数,跳过采集直接用现有JSON生成报告
✅ 方案4:紧急查询股价等基础信息时,使用Tavily搜索API作为最后手段

方案4 - Tavily紧急查询(2026-05-08验证有效):

import requests
url = 'https://api.tavily.com/search'
data = {
    'api_key': os.environ.get("TAVILY_API_KEY", ""),
    'query': '通富微电 002156 今日股价 最新价格',
    'search_depth': 'basic',
    'max_results': 3
}
resp = requests.post(url, json=data, timeout=15)
# 返回结果包含最新价格信息(来自搜索引擎索引)

验证方法: 运行collector.py后检查输出摘要,如果成功查询数<20/38,说明API可能限流。


⛔ 旧脚本已删除

当前唯一文件(v10):

  • generate_report.py v10 — 一键编排(3步:采集→生成→上传)
  • collector.py v7 — 数据采集(13模块+3补充模块,全部内置)
  • reporter_v6.py v8.2 — 报告生成(JSON→固定格式MD,含sf()+季度计算)
  • ima_integration.py v2 — IMA上传(MD→PDF→COS→知识库)

禁止使用:

⛔ reporter.py — 已删除
⛔ reporter_v4.py — 已删除
⛔ md_to_ima.py — 已删除
⛔ initiation-of-coverage-or-deep-dive — 禁止用于用户报告请求
✅ 唯一入口:generate_report.py v10(自动处理全流程)

参考文件

  • references/merged-report-template.md - v8模板(基于三花智控+三安光电+卧龙电驱对比确立)
  • references/v9-data-supplementation.md - v9数据补充策略(季度历史/运营效率/现金流/历史估值)
  • references/ima-api-integration.md - IMA API集成说明
  • references/operational-metrics-401-issue.md - 问财API运营效率指标401问题
  • references/data-quality-incident-20260504.md - 数据质量事故记录
  • references/westock-data-integration.md - westock-data数据源集成说明(v8新增)
  • references/westock-json-restructuring.md - iwencai限流时westock-data JSON重构方案
  • references/reporter-v6-date-fix-20260509.md - reporter_v6.py硬编码日期修复记录(v8.4新增)

⛔ 报告完整性强制要求(用户明确要求)

用户原话:「你可以在我原有的模版上增加数据和模块,禁止删除和省略」

完整报告框架:

一、报告摘要(Executive Summary)
  ✅ 核心投资逻辑(Key Investment Thesis)- 含完整财务指标表格
  ✅ 核心驱动因素(3-5个关键点)
  ✅ 核心风险提示(Key Risk Factors)- 具体风险+概率+影响
  ✅ 目标价位与周期(Target Price & Horizon)- 含机构评级表
  ✅ 目标投资者画像

二、深度分析(In-Depth Analysis)
  ✅ 1. 宏观环境与行业分析
     - 国内宏观环境(GDP、CPI表格)
     - 国际宏观环境
     - 行业基本信息
     - 行业估值水平(含分位点)
     - 行业资金流向
     - 行业竞争格局(同行对比表格)
     - 产业链地位(上游/中游/下游+议价能力)
     - 【新增】市场规模与增长(全球/中国市场规模、增速、预测)
     - 【新增】行业周期分析(周期特征、当前阶段)
     - 【新增】行业驱动因素(政策、技术、需求)
  ✅ 2. 公司基本面分析
     - 公司概况与商业模式
     - 【新增】历史沿革与发展里程碑
     - 营收结构分析(按产品/地区分类)
     - 财务健康状况深度剖析
       - 盈利能力(表格)
       - 成长能力(近三年对比表格)
       - 偿债能力(表格)
       - 营运能力(表格)
       - 现金流量(表格)
     - 【新增】杜邦分析(ROE分解)
     - 【新增】盈利质量分析(非经常性损益、应收款质量)
     - 公司治理与股东情况
       - 实际控制人
       - 【新增】董事长/法人代表信息
       - 前十大股东(表格)
       - 【新增】控股股东减持动态(近6个月减持记录)
       - 【新增】股权质押情况(质押比例、质押风险)
       - 机构持仓
     - 【新增】法律风险与负面消息
       - 债务纠纷(诉讼、仲裁)
       - 监管处罚(证监会、交易所)
       - 信息披露违规
       - 关联交易风险
       - 其他负面舆情
     - 【新增】管理层分析(核心高管背景、激励计划)
     - 【新增】产能布局(各基地产能、利用率、扩产计划)
     - 【新增】产品结构(各产品线毛利率、高端产品占比)
     - 【新增】成本结构(原材料/能源/人工成本占比)
     - 【新增】研发投入(研发费用、专利、技术优势)
  ✅ 3. 竞争优势分析(SWOT分析)
     - 优势(Strengths)
     - 劣势(Weaknesses)
     - 机会(Opportunities)
     - 威胁(Threats)
     - 核心竞争壁垒
  ✅ 4. 估值分析
     - 当前估值水平(含行业平均对比)
     - 历史估值区间(近5年PE表格)
     - 同行可比公司对比(表格)
     - 【新增】国际对标(与国际巨头估值对比)
     - 【新增】分部估值(按业务板块分别估值)
     - 【新增】绝对估值(DCF模型简述)
     - 估值结论
  ✅ 5. 技术面分析
     - 关键技术指标(RSI/KDJ/布林带表格)
     - 趋势判断(短/中/长期)
     - 支撑与阻力
  ✅ 6. 资金流向分析
     - 主力资金动向
  ✅ 7. 风险与机会综合评估
     - 风险矩阵(概率+影响表格)
     - 【新增】情景分析(乐观/中性/悲观)
     - 潜在催化剂(含时间窗口)
     - 【新增】风险应对策略
### 8. 新闻资讯
     - 公司最新动态

### 9. 报告质量一致性检查(2026-05-07 正泰vs紫金对比发现)

**问题描述:** 同一流程生成的两份报告,紫金矿业(6266字)比正泰电器(7854字)少1588字,且缺失8个子模块。

**缺失模块清单(紫金矿业报告):**
- 盈利质量分析、控股股东减持动态、股权质押情况
- 产能布局、产品结构、成本结构、机构持仓与市场情绪、估值消化测算

**根本原因:** Agent生成报告时因上下文长度或数据量大,省略了部分子模块。

**必须遵守的规则:**

⛔ 禁止:报告字数<7000字(v6模板最低标准) ✅ 必须:生成报告后执行子模块完整性检查(见下方清单) ✅ 必须:公司基本面分析必须包含全部8个子模块 ✅ 必须:用户明确要求「每次生成报告请自动核对是否是13个模块」


**公司基本面分析 - 必须包含的子模块(缺一不可):**
1. 公司概况与商业模式
2. 历史沿革与发展里程碑
3. 营收结构分析(按产品/地区)
4. 财务健康状况(盈利/成长/偿债/营运/现金流/杜邦/盈利质量)
5. 公司治理与股东(实控人/董事长/前十大股东/减持动态/质押情况)
6. 法律风险与负面消息
7. 管理层分析 + 产能布局 + 产品结构 + 成本结构 + 研发投入
8. 机构持仓与市场情绪

**估值分析 - 必须包含:** 当前估值、历史估值区间、同行对比、估值消化测算、估值结论

**报告生成后自动核对清单(13个模块):**
| # | 模块 | 关键子模块 |
|---|------|-----------|
| 1 | 报告摘要 | 股价概览、季度财务、近三年、行业对比、投资逻辑5维度、驱动因素、风险提示、目标价位、投资者画像 |
| 2 | 宏观与行业 | 国内/国际宏观、行业估值、资金流向、竞争格局同行对比表、产业链地位 |
| 3 | 公司基本面 | 概况、历史沿革、营收结构(产品/地区)、财务健康(7项)、公司治理(5项)、法律风险、产能、产品结构、成本结构、研发投入、机构持仓 |
| 4 | SWOT分析 | 优势、劣势、机会、威胁、核心壁垒 |
| 5 | 估值分析 | 当前估值、历史区间、同行对比、估值消化、结论 |
| 6 | 技术面 | RSI/KDJ/MACD/布林带、趋势判断、支撑阻力 |
| 7 | 资金流向 | 主力/大单/特大单 |
| 8 | 风险与机会 | 风险矩阵、情景分析、催化剂、应对策略 |
| 9 | 新闻资讯 | 公司最新动态 |
| 10 | 财务预测 | 盈利预测(2026-2028)、估值推导、敏感性分析 |
| 11 | 投资建议 | 评级、逻辑总结、操作策略、监测指标、退出策略 |
| 12 | 数据来源 | 来源表、免责声明 |
| 13 | 附录 | 可比公司、假设说明、数据明细 |

### 10. delegate_task 生成报告超时(2026-05-07发现)

**问题描述:** 使用delegate_task让子Agent生成完整v6报告时,600秒超时仍未完成。

**根因:** 完整v6报告(13模块,≥10000字)生成耗时远超600秒。

**解决方案:**

✅ 分段生成:将报告拆分为3-4个独立任务分别生成,最后合并

  • 任务1:报告摘要 + 宏观行业 + 公司基本面(含SWOT)
  • 任务2:估值分析 + 技术面 + 资金流向 + 风险评估 + 新闻
  • 任务3:财务预测 + 投资建议 + 数据来源 + 附录 ✅ 或直接在主Agent上下文中生成(不使用delegate_task) ⛔ 不要将完整13模块报告委托给单个delegate_task

三、财务预测与估值模型
  ✅ 【新增】盈利预测(2026-2028年)
     - 营业收入预测
     - 净利润预测
     - EPS预测
  ✅ 【新增】估值推导
     - PE估值区间
     - 目标价计算
  ✅ 【新增】敏感性分析
     - 关键假设变化对估值的影响

四、明确的投资建议与操作策略
  ✅ 投资评级
  ✅ 投资逻辑总结
  ✅ 操作策略
     - 入场策略(含具体价格区间)
     - 仓位建议(具体配置比例)
     - 止损策略
     - 目标价位(短/中/长期)
  ✅ 【新增】监控指标(需定期跟踪的关键指标清单)
  ✅ 【新增】退出策略

数据来源与时效性
数据获取完整性验证表格

【新增】附录
  - 可比公司列表
  - 关键假设说明
  - 数据来源明细

三数据源策略(v11 collector.py v8内置全部补充)

collector.py v8 已内置全部补充查询,无需手动调用任何技能。

collector.py v8 数据源优先级

优先级数据源特点适用场景
🥇 主westock-data(腾讯自选股)免费无限制K线、财务报表、公司概况、股东、分红、资金流向、技术指标
🥈 辅妙想API(东方财富)有使用限制行业对比、历史PE区间、运营效率(问财401时备选)
🥉 补问财API(同花顺)有频率限制行业数据、机构研究、新闻资讯
补充数据采集方式失败时备选
历史季度累计数据问财API分年查询无(必须有)
运营效率(周转率)问财API优先自动切mx-finance-data
现金流(经营/自由)问财API优先自动切mx-finance-data
估值字段(PS/股息率/同比)问财API
行业平均PE/PB问财行业查询
历史PE详细(5年)mx-finance-data

数据源分工(已固化到collector.py v7)

数据类型采集方说明
基础财务/估值/股东collector.py 基础模块问财API
技术面/资金流向collector.py 基础模块问财API
新闻/研报collector.py 基础模块问财API
运营效率+现金流collector.py 补充模块问财优先→妙想备选
历史季度数据collector.py 补充模块问财API分年查询
历史PE区间collector.py 补充模块妙想API
行业平均PE/PBcollector.py 补充模块问财行业查询

⚠️ collector.py v7 已内置的补充查询(2026-05-08永久固定)

以下数据已由 collector.py v7 自动采集,无需手动调用:

# 以下查询已内置到 collector.py v7 的补充模块中:
# 1. 历史季度累计数据(2024/2025年)→ 自动计算单季度
# 2. 运营效率(应收账款/存货/总资产周转率)→ 问财401时自动切妙想API
# 3. 现金流(经营现金流/企业自由现金流)→ 同上
# 4. 估值字段(市销率/股息率/营收同比/净利同比/加权ROE)
# 5. 行业平均PE/PB
# 6. 历史PE详细(5年每年最高/最低/平均,妙想API)

如需手动补充(调试用):

# 运营效率 + 现金流(5项指标一次查询)
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py \
  --query "股票名称 股票代码 应收账款周转率 存货周转率 总资产周转率 经营活动现金流净额 企业自由现金流"

# 历史估值区间(近5年PE最高最低平均)
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py \
  --query "股票名称 股票代码 近5年市盈率PE最高最低平均"

mx-finance-data返回xlsx格式:用openpyxl读取,第一行是表头(报告期列),第二行起是数据。

⚠️ 问财API 401错误(2026-05-06发现)

问财API对以下查询可能返回401:应收账款周转率、存货周转率、总资产周转率、经营活动现金流净额、企业自由现金流。必须用mx-finance-data获取

执行顺序

  1. 运行 collector.py 采集全部13个模块数据(JSON)
  2. 检查效率指标和现金流数据是否获取成功
  3. 如有401错误,调用 mx-finance-data-fallback 补充
  4. Agent读取JSON + v6模板,手动生成报告
  5. 运行 ima_integration.py 上传IMA

IMA知识库配置 (v2 - PDF文件上传)

目标位置

配置项
知识库名称Mei Ming的知识库
知识库IDW80hJmK98SC2GTUlPtnKK6MyKBE75MwMqFBJK8z0wyo=
文件夹名称行业公司报告
文件夹IDfolder_7403588502444840

自动化流程 (v2)

生成报告(MD) → weasyprint转PDF → preflight-check → COS上传 → 添加到知识库 → 删除本地文件

ima_integration.py v2 关键参数

# 目标文件夹ID
TARGET_FOLDER_ID = "folder_7403588502444840"

# 上传流程(PDF文件)
1. md_to_pdf() → weasyprint生成PDF
2. preflight-check.cjs → 检查文件类型
3. check_repeated_names → 检查重名
4. create_media → 创建媒体,获取COS凭证
5. cos-upload.cjs → 上传PDF到COS
6. add_knowledge → 添加到知识库(media_type=1)

generate_report.py 文件名匹配

⚠️ 已修复的bug:reporter.py生成的报告文件名格式为 {股票代码}_{股票名称}_*_report.md,不是 {股票名称}_深度研究报告*.md

正确的匹配逻辑

# 先尝试第一种格式
report_file = find_latest_file(f"{stock_name}_深度研究报告*.md")
# 如果没找到,尝试第二种格式
if not report_file:
    report_file = find_latest_file(f"{stock_code}_{stock_name}_*_report.md")

v2上传流程ima_integration.py 自动将.md转为PDF并上传,无需手动处理文件名。

  • 最新季度财务数据(营收、净利润、扣非净利润、毛利率、净利率、ROE(Q1)、资产负债率)
  • 季度财务数据明细(最近8个季度)
  • 近三年全年财务数据(营收、净利润、扣非净利润)
  • 行业平均指标对比(毛利率、净利率 vs 行业平均)
  • 核心投资逻辑总结(5个维度)
  1. 宏观环境与行业分析(国内/国际宏观、行业基本信息、竞争格局、产业链地位、市场规模、周期分析、驱动因素)
  2. 公司基本面(公司概况、历史沿革、营收结构、财务健康状况、杜邦分析、盈利质量、公司治理与股东、管理层、产能布局、产品结构、成本结构、研发投入)
  3. 竞争优势分析(SWOT分析、核心竞争壁垒)
  4. 估值分析(当前估值、历史估值区间、同行可比公司对比、国际对标、分部估值、DCF简述、PEG指标)
  5. 技术面分析(RSI/KDJ/布林带具体数值、趋势判断、支撑阻力位)
  6. 资金流向分析
  7. 风险与机会综合评估(风险矩阵、情景分析、催化剂时间窗口、风险应对策略)
  8. 新闻资讯
  9. 财务预测与估值模型(2026-2028年盈利预测、估值推导、敏感性分析)
  10. 投资建议与操作策略(入场/仓位/止损/目标价位、监控指标、退出策略)
  11. 数据来源与时效性 + 数据获取完整性验证
  12. 附录(可比公司列表、关键假设说明、数据来源明细)

数据补充要求(v6 增强版)

核心规则:生成报告时如发现N/A数据,必须自动调用技能补充数据

必须调用的技能查询:

  1. 扣非净利润查询(hithink-finance-query):

    python3 /root/.hermes/skills/finance/hithink-finance-query/scripts/cli.py \
      --query "XX股票 扣除非经常性损益后的净利润 2026年一季度" --limit "5"
    
  2. 近三年全年数据查询(hithink-finance-query):

    python3 /root/.hermes/skills/finance/hithink-finance-query/scripts/cli.py \
      --query "XX股票 全年营业收入 全年净利润 全年扣非净利润 2023年 2024年 2025年" --limit "5"
    
  3. 季度财务数据查询(hithink-finance-query):

    python3 /root/.hermes/skills/finance/hithink-finance-query/scripts/cli.py \
      --query "XX股票 单季度营业收入 单季度净利润 单季度扣非净利润" --limit "8"
    
  4. 行业平均毛利率/净利率(hithink-industry-query):

    python3 /root/.hermes/skills/finance/hithink-industry-query/scripts/cli.py \
      --query "XX行业 平均毛利率 平均净利率 2026年一季度" --limit "5"
    
  5. 技术面数据(mx-finance-data):

    # 日线/周线K线数据、MACD RSI KDJ
    
  6. 历史估值(mx-finance-data):

    # 近5年市盈率PE最高最低平均
    
  7. 同行对比(mx-finance-data):

    # 同行业对比 竞品A 竞品B
    
  8. 机构评级(mx-finance-data):

    # 券商研报评级 目标价
    

数据整合流程:

  1. 先用 collector.py 采集基础数据
  2. 检查报告中是否有N/A字段
  3. 如有N/A,自动调用上述技能补充
  4. 整合所有数据生成完整报告
  5. 确保所有字段已填充后上传IMA

报告文件名
生成的报告文件名必须包含股票名称,格式:{股票名称}_深度研究报告.md 不要使用 {股票代码}_{股票名称}_*_report.md 格式(会导致ima_integration.py找不到文件)。

上传流程ima_integration.py 自动将.md转为PDF并上传到IMA知识库「行业公司报告」文件夹。

⛔ 合并报告模板 v6(2026-05-05 三花智控 vs 三安光电对比后确立)

对比三花智控和三安光电两份报告后,用户要求合并为统一模板。v6模板包含13个完整模块:

一、报告摘要

  • ✅ 股价与估值概览表格
  • ✅ 最新季度财务数据表格(含行业平均对比)
  • ✅ 季度财务数据明细表格(最近4个季度)
  • ✅ 近三年全年财务数据表格
  • ✅ 行业平均指标对比表格
  • ✅ 核心投资逻辑总结(5个维度)
  • ✅ 核心驱动因素列表(emoji + 加粗标题 + 说明)
  • ✅ 核心风险提示列表
  • ✅ 目标价位与周期表格(机构/评级/目标价/核心观点)
  • ✅ 投资周期建议
  • ✅ 目标投资者画像

二、深度分析

  1. 宏观环境与行业分析

    • ✅ 国内宏观环境(要点列表 + 总结句)
    • ✅ 国际宏观环境(要点列表)
    • ✅ 行业基本信息
    • ✅ 行业估值水平(表格:指标/数值/行业分位)
    • ✅ 行业资金流向(表格 + 分析句)
    • ✅ 北向资金动态
    • ✅ 行业规模与增速
    • ✅ 行业周期分析
    • ✅ 行业驱动因素
    • 行业竞争格局(同行对比表格:公司/股价/PE/PB/市值/主要优势)
    • 产业链地位(位置/上游/下游/议价能力)
  2. 公司基本面分析

    • ✅ 公司概况与商业模式
    • ✅ 历史沿革与发展里程碑
    • 营收结构分析(按产品分类表格 + 按地区分类表格 + 分析句)
    • ✅ 财务健康状况深度剖析
      • 盈利能力(表格 + 同比变化)
      • 成长能力(近三年对比表格 + 分析句)
      • 偿债能力(表格 + 判断)
      • 营运能力(表格)
      • 现金流量(表格 + 分析句)
      • 杜邦分析(ROE分解)
      • 盈利质量分析
    • ✅ 公司治理与股东情况
      • 实际控制人信息
      • 董事长/法人代表信息
      • 前十大股东表格(含持股比例/数量/变动)
      • 控股股东减持动态(近6个月)
      • 股权质押情况
    • 法律风险与负面消息(重大法律风险汇总表格)
    • ✅ 管理层分析
    • ✅ 产能布局
    • ✅ 产品结构
    • ✅ 成本结构
    • ✅ 研发投入
    • 机构持仓与市场情绪(分析师评级汇总表格)
  3. 竞争优势分析(SWOT分析)

    • ✅ 优势(Strengths)
    • ✅ 劣势(Weaknesses)
    • ✅ 机会(Opportunities)
    • ✅ 威胁(Threats)
    • ✅ 核心竞争壁垒
  4. 估值分析

    • ✅ 当前估值水平表格(指标/数值/行业平均/判断)
    • 历史估值区间表格(近5年)
    • 同行可比公司对比表格
    • 估值消化测算(基于业绩增长的远期PE预测)
    • ✅ 估值结论
  5. 技术面分析

    • ✅ 关键技术指标表格(RSI/KDJ/MACD/布林带)
    • ✅ 趋势判断(短/中/长期)
    • 支撑与阻力(具体价位)
  6. 资金流向分析

    • ✅ 个股资金流向表格(含主力/大单/特大单)
    • ✅ 分析句
  7. 风险与机会综合评估

    • 风险矩阵表格(风险类型/描述/概率/影响程度)
    • 情景分析表格(乐观/中性/悲观)
    • 潜在催化剂列表(emoji + 加粗标题 + 说明)
    • 风险应对策略
  8. 新闻资讯

    • ✅ 公司最新动态(按机构/日期列出)

三、财务预测与估值模型

  • 盈利预测表格(2026-2028年)(营收/净利润/EPS)
  • 估值推导(PE估值/PB估值/综合目标价)
  • 敏感性分析表格

四、明确的投资建议与操作策略

  • ✅ 投资评级(emoji星级)
  • ✅ 投资逻辑总结(3点)
  • ✅ 操作策略
    • 入场策略(含具体价格区间)
    • 仓位建议
    • 止损策略
    • 目标价位(短/中/长期)
  • 关键监测指标(5个编号列表)
  • 退出策略(止损/止盈/基本面退出)

数据来源与时效性

  • ✅ 数据来源表格
  • ✅ 免责声明

📊 数据获取完整性验证

  • ✅ 模块状态表格(13个模块全部✅)
  • ✅ 数据覆盖率100%

完整模板见:references/merged-report-template.md(v6 基于三花智控+三安光电对比确立的标准模板)

IMA知识库集成 (v2 - PDF文件上传)

报告生成后自动上传到IMA知识库「行业公司报告」文件夹,本地.md文件自动删除。

IMA完整流程

# 步骤1:采集数据(13模块全覆盖)
python3 /root/.hermes/scripts/stock-research/collector.py -c <股票代码> -n <股票名称>

# 步骤2:Agent按v6模板手动生成报告

# 步骤3:上传IMA(MD → PDF → COS → 知识库)
python3 /root/.hermes/scripts/stock-research/ima_integration.py \
  --report-path output/<股票名称>_深度研究报告.md \
  --stock-name <股票名称> \
  --stock-code <股票代码>

IMA配置

  • Client ID: 0b8ad89306b75e1dabf520676577b101
  • API Key: 已预配置
  • 目标知识库: Mei Ming的知识库
  • 目标文件夹: 行业公司报告 (folder_id: folder_7403588502444840)
  • 上传方式: PDF文件(非笔记)

ima_api.cjs 未安装时的替代方案

如果Node.js环境缺少ima_api.cjs,使用Python直接调用IMA API上传PDF文件。参考 references/ima-api-integration.md

Pitfalls

⛔ P0 Critical: PDF中文乱码(2026-05-07紫金矿业事故)

问题描述: 生成的PDF文件中所有中文显示为□□□方块。

根因分析: 系统未安装中文字体,weasyprint默认使用SimSun(不存在于Linux服务器)。

必须遵守的规则:

⛔ 禁止:假设系统已有中文字体
✅ 必须:首次使用前执行 apt-get install -y fonts-noto-cjk fonts-wqy-microhei
✅ 必须:ima_integration.py CSS中 font-family 以 "Noto Sans CJK SC" 为首选

修复命令:

apt-get install -y fonts-noto-cjk fonts-wqy-microhei
fc-cache -f

验证方法: 生成PDF后用pdftotext提取文本,检查是否包含中文字符。


⛔ P0 Critical: PDF emoji乱码(2026-05-07紫金矿业事故)

问题描述: PDF中emoji字符显示为⊠框框(带X的方块)。

根因分析: weasyprint不支持彩色emoji字体(Noto Color Emoji),即使安装了emoji字体也无法渲染。

必须遵守的规则:

⛔ 禁止:在报告MD中使用emoji字符(📊📈🏆✅⚠️等)
✅ 必须:ima_integration.py自动将emoji替换为纯文本标记
✅ 替换规则:✅→[OK]  ⚠️→[!]  ❌→[X]  ⭐→*  装饰性emoji→移除

已修复: ima_integration.py v2已内置emoji清理逻辑,无需手动处理。


1. generate_report.py 文件名匹配bug

generate_report.py 内部调用 collector.py 采集数据,但报告文件名格式可能不匹配。 解决方案:手动执行ima_integration.py时,使用正确的文件路径

python3 ima_integration.py \
  --report-path output/中国巨石_深度研究报告.md \
  --stock-name 中国巨石 \
  --stock-code 600176

0. 文件上传规则(v2 - PDF文件)

上传方式:Markdown → PDF → 文件上传到知识库(不再通过笔记)

用户原话:「直接把md的文件生成pdf 然后把pdf以文件的形式上传到ima的知识库中,不需要经过笔记」

  • ✅ 使用 ima_integration.py 自动转换并上传PDF
  • ❌ 不要使用 import_doc 创建笔记
  • ❌ 不要用 MEDIA: 发送文件给用户

2. ⛔ 技能文件修改禁令(用户原话:「技能模版未经我运行 禁止变动,私自修改 要变动请先请示我」)

禁止未授权修改以下任何文件:

  • SKILL.md(技能说明文档)
  • references/ 目录下的模板文件(merged-report-template.md 等)
  • scripts/ 目录下的脚本(collector.py、reporter.py、reporter_v4.py、generate_report.py 等)
  • templates/ 目录下的任何文件
⛔ 禁止:未经用户明确授权,私自修改任何技能文件(SKILL.md、模板、脚本、配置)
⛔ 禁止:patch/edit/create/delete 技能文件前不先请示用户
✅ 必须:先向用户请示修改内容和原因,获得批准后才能执行
✅ 必须:遇到执行不了的任务,明确告诉用户卡在哪里,让用户授权

3. 不要自作主张绕过限制

如果某个操作失败,不要尝试修改代码绕过,而是告诉用户具体问题,让用户决定如何处理。

5. 问财API对法律/风险数据覆盖不全 + news-search补充(2026-05-05三安光电事故)

问题描述: 三安光电报告中法律风险、股份冻结、实控人留置等关键信息全部显示"待确认",用户质疑数据采集不充分。

根因分析:

  1. 问财API的 business 技能对司法冻结、拍卖、留置等特定事件覆盖不全
  2. 原始查询语句过于通用(如"诉讼 仲裁 债务纠纷"),未包含"司法冻结""拍卖""留置"等精准关键词
  3. news-search技能没有被集成到数据采集流程中作为风险数据的补充来源

必须遵守的规则:

⛔ 禁止:报告中出现"待确认"字段 — 代表数据采集不充分
✅ 必须:collector.py使用精准关键词查询(含"司法冻结""拍卖""留置""调查")
✅ 必须:在collect_news_data()中调用news-search搜索负面新闻作为补充
✅ 必须:生成报告前检查所有字段,如有"待确认"立即补充

修复方案:

  1. collector.py查询语句增加精准关键词(已修复)
  2. 新增 negative_news 新闻搜索模块(已修复)
  3. 报告生成前交叉验证:问财数据 + 新闻搜索数据

验证方法: 生成报告后搜索"待确认",如存在则说明数据采集不充分,需重新采集或补充查询。

6. 数据完整性要求(用户明确要求)

用户原话:「你生成的报告为什么又少了很多的数据,而且很多n值」

生成报告时必须确保所有关键数据已填充,不得出现N/A值。如果发现N/A:

  1. 立即调用补充查询

    • 扣非净利润 → hithink-finance-query
    • 季度财务数据 → mx-finance-data(优先,能获取历史8个季度)
    • 行业平均数据 → hithink-industry-query
    • 历史估值 → mx-finance-data
  2. 季度数据获取策略

    • 问财API只返回最新一期,不要依赖
    • 妙想API能返回历史季度数据,优先使用
    • 查询语句:"XX股票 季度营业收入 季度净利润 季度扣非净利润 2024年 2025年"
  3. 报告生成前检查

    • 读取JSON数据文件确认字段完整
    • 如有N/A,先补充数据再生成报告
    • 不要用占位符或"待确认"

5. 模板版本管理

用户原话:「你为什么又使用旧版模版,昨晚已经要求更新最新的模版」

  • 当前模板版本:v6 专业机构级
  • 模板位置:~/.hermes/skills/finance/stock-deep-research/references/merged-report-template.md
  • 生成报告前必须确认使用最新模板
  • v6新增模块:公司治理深度分析、法律风险与负面消息、SWOT分析、财务预测(2026-2028)、估值推导、敏感性分析、情景分析、风险应对策略、监控指标、退出策略、数据完整性验证 让用户决定如何处理。

4. 报告完成后不要发送文件(用户明确要求)

报告上传到IMA后,禁止通过MEDIA:发送文件给用户。 正确做法:只报告「已上传到IMA知识库「行业公司报告」文件夹」+ 核心数据摘要。 用户会在IMA客户端自行查看完整报告。

⛔ P0 Critical: 禁止使用 initiation-of-coverage-or-deep-dive 生成报告(2026-05-06特变电工事故)

问题描述: 用户要求"深度研究报告"时,AI错误调用了 initiation-of-coverage-or-deep-dive 技能的妙想API脚本,而非 stock-deep-research 的 collector.py + reporter_v4.py 流程。生成的报告是妙想API的通用模板(仅含核心投资逻辑和1-2个数据表格),完全缺失v6模板的13个完整模块。

用户原话:「你是不是没按我之前的脚本模版创建报告 怎么单独使用了妙想创建了」「我的模板已经是v6了 你是不是搞错了」

根因分析:

  • initiation-of-coverage-or-deep-dive 技能的SKILL.md描述为"深度研究报告",触发词与 stock-deep-research 高度重叠
  • 但两者产出质量天差地别:前者是简单API调用(1页摘要),后者是完整的13模块v6报告(15000+字)
  • AI未仔细对比两个技能的适用场景,直接选了看起来"更快"的那个

必须遵守的规则:

⛔ 禁止:用户说"深度研究""研究报告"时使用 initiation-of-coverage-or-deep-dive
⛔ 禁止:用妙想API的简单脚本替代 stock-deep-research 流程
✅ 必须:始终使用 collector.py + mx-finance-data补充 + v6模板生成报告
✅ 必须:generate_report.py 生成后检查输出是否为v6格式(13个模块)

两个技能的本质区别:

技能适用场景产出质量使用时机
initiation-of-coverage-or-deep-dive快速获取妙想API的标准化摘要低(1-2页,通用模板)❌ 不用于用户请求
stock-deep-research完整深度研究报告高(13模块,v6模板)✅ 始终使用

验证方法: 生成报告后,检查是否包含v6的13个模块(报告摘要/宏观行业/公司基本面/SWOT/估值/技术面/资金流向/风险矩阵/新闻/财务预测/投资建议/数据验证/附录)。如果缺失,说明使用了错误的流程。


⛔ P0 Critical: generate_report.py 输出v4模板,非v6(2026-05-06特变电工发现)

问题描述: generate_report.py 内部调用 reporter_v4.py,输出的报告是v4模板格式(约300行/11KB),远不及v6模板(13个完整模块/15000+字)。v4模板缺少:SWOT分析、财务预测、敏感性分析、情景分析、退出策略、数据完整性验证等关键模块。

必须遵守的规则:

⛔ 禁止:直接把 generate_report.py 的输出当作最终报告
✅ 必须:generate_report.py 只作为数据采集步骤(collector.py的封装)
✅ 必须:报告生成必须基于v6模板手动整合,不能依赖 reporter_v4.py 的自动输出

正确流程:

  1. generate_report.pycollector.py → 采集数据(JSON)
  2. mx-finance-data → 补充季度数据、技术面、历史估值
  3. 基于 references/merged-report-template.md(v6)手动整合报告
  4. 检查13个模块是否齐全,N/A是否已填充
  5. ima_integration.py → 自动MD→PDF→上传IMA知识库

验证方法: 最终报告字数应≥10000字,包含13个模块标题。如<5000字且缺少SWOT/财务预测等,说明使用了v4模板。 虽然SKILL.md记录了双格式匹配逻辑,但实际运行时仍可能出现不匹配。 兜底方案:如果generate_report.py的IMA上传失败,手动执行:

python3 /root/.hermes/scripts/stock-research/ima_integration.py \
  --report-path /root/.hermes/scripts/stock-research/output/<实际文件名>.md \
  --stock-name <股票名称> \
  --stock-code <股票代码>

9. IMA笔记提取丢失所有markdown格式(2026-05-07发现)

问题描述: 通过IMA API get_doc_content 提取的笔记内容,所有markdown格式(表格|、标题#、加粗**、列表-、分割线---)全部丢失,变成纯文本。

表现: 提取的文本中:

  • 标题 ## 一、报告摘要 变成 一、报告摘要
  • 表格 | 指标 | 数值 | 变成 指标数值
  • 加粗 **盈利能力** 变成 盈利能力
  • 列表 - 项目1 变成 项目1
  • 换行也被压缩,整段文字连在一起

根因: IMA笔记使用自有富文本格式存储,get_doc_content API返回的是纯文本版本,不包含markdown标记。

必须遵守的规则:

⛔ 禁止:从IMA笔记提取内容来对比报告格式(会丢失所有markdown)
✅ 必须:如需对比报告格式,使用本地MD文件或JSON数据文件
✅ 必须:reporter_v6.py生成标准markdown,ima_integration.py转PDF时保留格式

验证方法:get_doc_content 提取的文本中如果找不到 |#,说明格式已丢失。


10. weasyprint不支持彩色emoji字体(2026-05-07验证)

问题描述: 即使安装了 fonts-noto-color-emoji,weasyprint仍然无法渲染彩色emoji,显示为⊠框框。

根因: weasyprint使用Cairo渲染引擎,不支持CBDT/CBLC格式的彩色emoji字体。Noto Color Emoji是彩色位图字体,Cairo无法解析。

解决方案:

⛔ 禁止:尝试安装emoji字体来解决weasyprint的emoji问题
✅ 必须:在ima_integration.py中将emoji替换为纯文本标记
✅ 替换规则:✅→[OK]  ⚠️→[!]  ❌→[X]  ⭐→*  📊📈等装饰emoji→移除

已修复: ima_integration.py v2已内置emoji清理逻辑,无需手动处理。


12. 扣非净利润字段名不一致(2026-05-08紫金矿业发现)

问题: 问财API返回的累计数据字段名为 扣非归母净利润[YYYYMMDD],但reporter_v6.py中使用 扣非净利润[YYYYMMDD],导致历史季度扣非净利润全部N/A。

解决方案: reporter_v6.py中读取quarterly_cumulative时,必须用 扣非归母净利润 而非 扣非净利润

13. 估值字段日期后缀不一致(2026-05-08紫金矿业发现)

问题: 不同API返回的估值字段日期后缀不同:

字段collector.py用问财API返回
市销率市销率[20260506]市销率[20260507]
股息率股息率[20260506]年度股息率[20251231]

解决方案: reporter_v6.py中用多字段回退:

ps = v(cv.get("市销率[20260507]", cv.get("市销率[20260506]")))
div = v(cv.get("股息率[20251231]", cv.get("年度股息率[20251231]", cv.get("股息率[20260506]"))))

14. 用户要求零N/A值(2026-05-08用户明确要求)

用户原话: 「报告中还是有na值,请了解技能工能,再次全部补全」

必须遵守的规则:

⛔ 禁止:报告中出现任何N/A值
✅ 必须:generate_report.py v9 的 Step 2d 自动补充所有缺失字段
✅ 必须:生成报告后 grep "N/A" 验证,如有则立即补充
✅ 必须:使用 hithink-finance-query 补充 市销率/股息率/营收同比/净利同比/加权ROE
✅ 必须:使用 hithink-industry-query 补充 行业平均PE/PB

16. 问财API限流导致采集失败(2026-05-08紫金矿业发现)

问题描述: 连续大量查询后问财API返回401 Unauthorized,导致collector.py采集的JSON中部分模块为空。

表现: 6_估值分析12_杜邦分析等模块为空,报告中出现大量N/A。

解决方案:

✅ collector.py v7 已内置妙想API自动备选(运营效率+现金流)
✅ 估值/基本面缺失字段由 collector.py v7 的 collect_supplementary_valuation() 自动补充
✅ 行业平均PE/PB 由 collector.py v7 的 collect_supplementary_valuation() 自动查询
⚠️ 如遇限流,等待5-10分钟后重试

验证方法: 生成报告后 grep -c "N/A" report.md,如果>0说明有模块采集失败。

19. 妙想API补充数据的字段映射陷阱(2026-05-08洛阳钼业事故)

问题描述: 问财API限流后,用妙想API补充数据并写入JSON,但reporter_v6.py读取时大量N/A,原因是字段名和数据类型不匹配。

根因分析:

  1. 字段名不一致:妙想API返回 净利润/营业总收入,reporter_v6.py期望 销售净利率
  2. 数据类型不一致:妙想API返回字符串 "664亿元" / "22.88%",reporter_v6.py期望浮点数
  3. 层级结构不一致:collector.py的问财查询返回 success: true, datas: [...],但限流时返回 success: false, error: ...,手动写入需重建整个结构
  4. 子字段名不一致扣非净利润 vs 扣非归母净利润市盈率PE(TTM) vs 市盈率(pe,ttm)

必须遵守的规则:

⛔ 禁止:直接把妙想API的xlsx数据dump到JSON就期望reporter_v6.py正常工作
✅ 必须:按照字段映射表逐字段转换(见 references/miaoxiang-field-mapping.md)
✅ 必须:所有数值字段转换为float/int,去掉"亿元""次""倍""%"等单位
✅ 必须:写入前重建完整的section结构 {success: true, datas: [{...}]}

reporter_v6.py期望的关键字段名(与妙想API输出的映射):

reporter_v6.py字段妙想API返回字段备注
市盈率(pe,ttm)[20260507]市盈率PE(TTM)[20260507]大小写+括号
销售净利率[20260331]净利润/营业总收入[20260331]完全不同的字段名
净资产收益率[20260331]净资产收益率ROE[20260331]后缀差异
营业收入[20260331]单季度.营业收入需要加日期后缀
归母净利润[20260331]单季度.归属母公司股东的净利润名称差异大
扣非归母净利润[20260331]单季度.扣除非经常损益后的净利润名称差异大
单季度_营业收入[20260331]单季度.营业收入下划线vs点号
单季度_归母净利润[20260331]单季度.归属母公司股东的净利润同上
单季度_扣非净利润[20260331]单季度.扣除非经常损益后的净利润同上
营业收入[20251231] (quarterly_cumulative)营业收入(年报列)需要加日期key
扣非归母净利润[20251231] (quarterly_cumulative)扣除非经常性损益后归属于母公司股东的净利润需要加日期key
经营活动产生的现金流量净额[20260331]经营活动产生的现金流量净额需要加日期后缀
企业自由现金流量[20260331]企业自由现金流量FCFF(反推法)名称差异大

数据清理函数(必须使用):

def clean_number(value):
    """妙想API数据 → reporter_v6.py可用的float"""
    if value in ('N/A', None, '-'):
        return None
    import re
    s = str(value)
    s = re.sub(r'[亿元次倍%]', '', s).replace(',', '')
    try:
        num = float(s)
        return int(num) if num == int(num) else num
    except:
        return None

完整的JSON写入模板:

# 正确的section结构
data['sections']['1_报告摘要']['current_price'] = {
    'success': True,
    'datas': [{
        '最新价': 'N/A',
        '总市值[20260507]': 4249,
        '市盈率(pe,ttm)[20260507]': 17.59,
        '市净率[20260507]': 4.781,
    }]
}

验证方法: 写入JSON后执行 python3 reporter_v6.py,如仍有N/A则检查字段名是否完全匹配。

教训: 妙想API补充数据需要完整的字段映射+类型转换+结构重建,不能简单dump。


18. 问财API全面限流应急方案(2026-05-08紫金矿业事故)

问题描述: 连续大量查询后问财API全面返回401,collector.py采集的JSON中核心模块(current_price/fundamentals_snapshot/financial_history等)全部为空,导致报告138个N/A。

根因: 问财API有频率限制,短时间内发起60+查询会触发限流,恢复时间5-30分钟。

应急方案(按优先级):

✅ 方案1(推荐):等待5-10分钟后重新运行 generate_report.py
✅ 方案2:用妙想API补充核心数据(股价/PE/PB/毛利率/同比等)
✅ 方案3:用已知正确数据手动写入JSON(仅限调试/紧急情况)

方案2具体操作(妙想API补充):

完整查询语句见 references/miaoxiang-field-mapping.md 附录。核心查询:

# 核心数据(一次获取估值+财务)
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py \
  --query "股票名称 股票代码 最新股价 总市值 市盈率 市净率 毛利率 净利率 ROE 资产负债率"

# 运营效率+现金流
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py \
  --query "股票名称 股票代码 应收账款周转率 存货周转率 总资产周转率 经营活动现金流净额 企业自由现金流"

# 历史PE区间
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py \
  --query "股票名称 股票代码 近5年市盈率PE最高最低平均"

# 累计季度数据(用于计算单季度值)
python3 ~/.hermes/skills/miaoxiang/mx-finance-data/scripts/get_data.py \
  --query "股票名称 股票代码 营业收入 归母净利润 扣非净利润 2024年一季报 2024年中报 2024年三季报 2024年年报 2025年一季报 2025年中报 2025年三季报 2025年年报"

⚠️ 关键:妙想API返回xlsx格式 + 字段名与reporter_v6.py不一致,必须按 references/miaoxiang-field-mapping.md 逐字段映射+清洗后写入JSON。

⚠️ mx-finance-data输出目录不固定:

  • 全局目录:~/miaoxiang/mx_finance_data/
  • 脚本目录:~/.hermes/scripts/stock-research/miaoxiang/mx_finance_data/
  • 搜索时需遍历所有可能目录:
search_dirs = [
    os.path.expanduser("~/miaoxiang/mx_finance_data/"),
    os.path.expanduser("~/.hermes/scripts/stock-research/miaoxiang/mx_finance_data/"),
]

方案3(手动写入JSON): 当API完全不可用时,可将已知正确数据直接写入JSON的对应section。这需要了解JSON结构:

  • sections.1_报告摘要.current_price.datas[0] → 股价/市值/PE/PB
  • sections.1_报告摘要.fundamentals_snapshot.datas[0] → 毛利率/净利率/ROE/负债率/同比
  • sections.1_报告摘要.quarterly_cumulative.datas[0] → 季度累计数据
  • sections.1_报告摘要.financial_history.datas[0] → 近三年全年数据
  • sections.3_公司基本面.efficiency.datas[0] → 周转率
  • sections.3_公司基本面.cash_flow.datas[0] → 现金流
  • sections.12_杜邦分析.dupont.datas[0] → 杜邦分解
  • sections.13_历史估值.pe_history_5y.datas[0] → 5年PE区间

25. miaoxiang/mx_finance_data 目录累积旧xlsx文件(2026-05-10发现)

问题描述: 每次使用mx-finance-data补充数据时,会在 ~/.hermes/scripts/stock-research/miaoxiang/mx_finance_data/ 目录下生成 .xlsx_description.txt 文件。这些文件不会自动清理,长期积累会占用大量磁盘空间。

必须遵守的规则:

✅ 必须:每次成功生成报告后,清理 miaoxiang/mx_finance_data/ 下所有 .xlsx 和 *_description.txt 文件
✅ 必须:同时清理 output/ 目录下的旧JSON文件(保留最新的)

清理命令:

# 清理妙想API输出文件
rm -f ~/.hermes/scripts/stock-research/miaoxiang/mx_finance_data/*.xlsx
rm -f ~/.hermes/scripts/stock-research/miaoxiang/mx_finance_data/*_description.txt

# 清理旧JSON(保留最新)
cd ~/.hermes/scripts/stock-research/output/
# 删除除最新以外的旧JSON文件
find . -name "*.json" -not -name "$(ls -t *.json | head -1)" -delete

验证方法: 报告生成后检查 miaoxiang/mx_finance_data/ 目录是否为空。


⛔ P0 Critical: reporter_v6.py 硬编码结论彻底清零(v8.6 最终修复)

问题历程: 经历四轮修复,从38处→0处:

  • 第一轮(v8.5):修复15处数据与结论矛盾(如资金流出写"净流入")
  • 第二轮(v8.5):修复23处通用模板文字(如"全球化布局""行业龙头")
  • 第三轮(v8.6):修复28处公司特定描述(如"消费电子精密零组件龙头""AI终端渗透率")
  • 第四轮(v8.6):修复行业竞争格局表格列对齐bug

根本教训: 永远不要用"A公司的描述"替换"B公司的描述"——正确的做法是让所有描述都从数据动态生成。

判断标准: 如果把JSON数据换成另一家公司的,报告文字是否会出错?如果会出错,就是硬编码。

必须遵守的规则(用户明确要求):

⛔ 禁止:报告中任何结论性文字硬编码,不管数据如何
⛔ 禁止:使用任何公司特定的行业描述(如"消费电子""贵金属""新能源")
⛔ 禁止:使用任何具体公司名、产品名、客户名作为通用描述
✅ 必须:所有结论100%从JSON数据动态生成
✅ 必须:行业描述从ind变量和营收结构推断
✅ 必须:公司地位从市值分档判断(大型/骨干/参与者)
✅ 必须:竞争优势从毛利率/ROE/海外占比/专利数动态推断
✅ 必须:SWOT机会/威胁从PE/营收增速/海外占比/负债率推断
✅ 必须:催化剂从营收结构+估值水平动态生成
✅ 必须:风险矩阵从实际风险指标推断

验证检查清单(每次修改后必须执行):

# 1. 检查硬编码通用文字残留(期望:0)
grep -c "全球化布局\|并购整合\|外延式扩张\|国产替代\|行业龙头\|协同效应\|海外产能占比高" report.md

# 2. 检查📌结论是否与上方数据一致
grep '📌' report.md
# 逐条验证

# 3. 语法检查
python3 reporter_v6.py --json-path test.json --output /dev/null
# 期望:无报错

修复详情:references/reporter-hardcoded-conclusion-fixes.md(38处修复完整清单)


24. reporter_v6.py 硬编码结论与数据矛盾(2026-05-10湖南黄金事故,已修复v8.5)

⛔ P0 Critical: reporter_v6.py 硬编码结论与数据矛盾(2026-05-10湖南黄金事故,已修复v8.5)

问题描述: reporter_v6.py中有38处硬编码结论文字,不管数据是什么都输出固定文字。例如资金流向数据为负(净流出),结论却写"主力资金净流入,市场看好"。

第二层风险(2026-05-11发现): 38处修复后仍有28处硬编码绑定到特定公司(湖南黄金),对领益智造等其他股票输出完全错误的结论(如"主营黄金+锑品"、"金价高位运行"等)。

必须遵守的规则(零硬编码原则):

⛔ 禁止:reporter_v6.py 中使用任何硬编码的定性结论
⛔ 禁止:假设公司是"行业龙头"、"全球化布局"、"并购整合"
⛔ 禁止:将特定公司描述(如"黄金冶炼"、"消费电子")用于所有股票
✅ 必须:所有📌结论必须根据实际数据动态生成(if/elif/else)
✅ 必须:行业地位/竞争壁垒/驱动因素从市值/毛利率/营收结构推断
✅ 必须:宏观环境从营收增速/海外占比/毛利率推断
✅ 必须:SWOT分析从实际财务数据生成5条优势/3条机会/3条威胁

重构时注意变量作用域:

# ❌ 变量在定义前使用(如overseas_pct在国际宏观定义但国内宏观使用)
# ✅ 将高频计算提前到数据加载区域,或在使用前独立计算
overseas_pct = overseas_rev / total_rev_r * 100 if total_rev_r > 0 else 0
pe_iv_local = sf(iv.get("最新市盈率ttm"))  # 独立计算,不依赖后续变量

验证方法(每次修改后必须执行):

# 1. 检查硬编码公司特定描述残留
grep -c "黄金\|锑品\|贵金属\|金价\|消费电子\|AI终端\|汽车电子\|全球化布局\|国产替代\|并购整合\|外延式" report.md
# 期望:仅剩分析师研报原文和真实人名(≤5处)

# 2. 检查📌结论是否与上方数据一致
grep '📌' report.md
# 逐条验证

# 3. 语法检查(含变量作用域)
python3 reporter_v6.py --json-path test.json --output /dev/null
# 期望:无报错

详细修复清单:

  • 第一轮(2026-05-10):38处数据矛盾 → references/reporter-hardcoded-conclusion-fixes.md
  • 第二轮(2026-05-11):28处公司绑定 → references/reporter-hardcoded-conclusion-fixes-round3.md

25. reporter_v6.py 全面去硬编码化(2026-05-11领益智造事故)

问题描述: reporter_v6.py中所有结论文字(宏观环境/行业分析/SWOT/风险/催化剂/投资逻辑等)都是针对特定公司的硬编码文字。第二轮修复时只是将湖南黄金的硬编码替换成了领益智造的硬编码,本质上没解决。

根因分析:

  • 脚本编写时使用了固定描述("消费电子精密零组件龙头"、"AI终端渗透率提升"、"汽车电子快速发展"等)
  • 这些描述只对一家公司正确,换其他公司就会出错

必须遵守的规则:

⛔ 禁止:用A公司的描述替换B公司的描述(只是换了硬编码内容)
✅ 必须:所有结论文字100%从JSON数据动态生成
✅ 必须:行业描述从ind变量+营收结构推断
✅ 必须:竞争优势从毛利率/ROE/市值/海外占比等数据推断
✅ 必须:SWOT/风险/催化剂等从实际财务指标条件判断

判断是否硬编码的简单方法: 如果把JSON数据换成另一家公司的,报告文字是否会出错?如果会出错,就是硬编码。

已修复28处,详细清单见: references/reporter-hardcoded-conclusion-fixes.md 第三轮修复


26. 行业竞争格局表格列对齐bug(2026-05-11正泰电器事故)

问题描述: 行业竞争格局表格中,同行公司的PE-TTM值被错误地放在了"最新价"列,导致数据看起来异常。

根因分析: peer_detailed数据中有最新价字段,但reporter_v6.py中行业竞争格局部分的代码没有提取该字段,直接把PE值放在了第一列数据位置。

修复方案:

# 修复前(缺少最新价列)
pp = v(pd.get(f"市盈率(pe,ttm)[{actual_date}]"))
w(f"| {pn} | ¥{pp} | {ppb} | - | ¥{pmk}亿 | - |")

# 修复后(添加最新价列)
ppl = v(pd.get("最新价"))  # 最新价
pp = v(pd.get(f"市盈率(pe,ttm)[{actual_date}]"))  # PE-TTM
ppb = v(pd.get(f"市净率[{actual_date}]"), "", 2)  # PB
pmk = v(pd.get(f"总市值[{actual_date}]"), "", 0)  # 市值
w(f"| {pn} | ¥{ppl} | {pp} | {ppb} | ¥{pmk}亿 | - |")

27. 变量作用域问题:overseas_pct/pe_iv提前使用(2026-05-11领益智造事故)

问题描述: 修改reporter_v6.py时,将overseas_pct的使用提前到了定义之前,导致UnboundLocalError

根因分析:

  • overseas_pct原在"国际宏观环境"部分计算
  • 修改后的"国内宏观环境"部分引用了它
  • Python在函数作用域中,变量赋值前引用会报错

修复方案: 将overseas_pct计算移到数据加载区域(所有报告内容之前),确保后续所有部分都能访问。

必须遵守的规则:

⛔ 禁止:在变量定义之前使用变量
✅ 必须:将跨多处使用的变量(overseas_pct/pe_iv等)提前到数据加载区域计算
✅ 必须:如果只需要在某一处使用,用本地变量(如pe_iv_local = sf(iv.get("最新市盈率ttm")))

28. hny_trend使用顺序错误(2026-05-11领益智造事故)

问题描述: hny_trend变量在定义之前被使用,导致UnboundLocalError

根因分析: 原代码中是:

w(f"| 归母净利润(亿) | {' | '.join(fhn)} | 高速增长 |")  # 硬编码
hny_vals = ...  # 计算hny_trend
hny_trend = ...

修改时将"高速增长"改为{hny_trend},但hny_trend的计算在下一行。

修复方案: 将hny_vals和hny_trend的计算移到使用之前。


23. reporter_v6.py 硬编码日期导致大量N/A(2026-05-09冠豪高新事故)

问题描述: reporter_v6.py中硬编码了日期后缀(如2026050720260506),但collector.py采集的数据使用实际日期(如20260508),导致字段名不匹配,报告出现49个N/A。

根因分析:

  • reporter_v6.py代码中直接写死 市盈率(pe,ttm)[20260507] 等日期后缀
  • collector.py采集的数据使用实际日期(如20260508
  • 两者日期不匹配,dict.get()返回None,最终显示N/A

必须遵守的规则:

⛔ 禁止:在reporter_v6.py中硬编码日期后缀(如[20260507])
✅ 必须:使用动态日期提取函数get_actual_date()从JSON数据中获取实际日期
✅ 必须:所有日期引用使用f-string格式化 f"字段名[{actual_date}]"

修复方案(已应用到reporter_v6.py v8.4):

def get_actual_date(data):
    """从JSON数据中提取实际日期"""
    import re
    sections = data.get('sections', {})
    for sec_name in ['1_报告摘要', '6_估值分析']:
        sec = sections.get(sec_name, {})
        for key in sec:
            val = sec[key]
            if isinstance(val, dict) and 'datas' in val:
                datas = val['datas']
                if isinstance(datas, list) and len(datas) > 0:
                    item = datas[0]
                    if isinstance(item, dict):
                        for k in item.keys():
                            match = re.search(r'\[(\d{8})\]', k)
                            if match:
                                return match.group(1)
    return '20260508'  # default

# 使用方式
actual_date = get_actual_date(d)
pe = v(cp.get(f"市盈率(pe,ttm)[{actual_date}]", cp.get("市盈率(pe,ttm)")))

额外修复:f-string前缀缺失 部分代码使用 "字段[{actual_date}]" 而非 f"字段[{actual_date}]",导致字符串未被格式化。

❌ 错误:stk.get("主力资金流向[{actual_date}]")
✅ 正确:stk.get(f"主力资金流向[{actual_date}]")

验证方法: 生成报告后执行 grep -c "N/A" report.md,如果>10说明可能存在日期不匹配问题。


17. 空响应错误处理(2026-05-08发现)

问题描述: Hermes Agent在处理工具调用结果时返回空响应,触发"Empty response from model"错误。

原因: Agent处理大量工具输出时可能超时或上下文过长。

规避方法:

✅ 工具调用后必须处理结果并输出摘要,不要返回空
✅ 复杂任务分步执行,每步输出明确结果
✅ 避免在一次调用中执行过多操作

问题描述: 用户要求"以卧龙电驱报告为准重新生成模板",但卧龙电驱报告存储在IMA笔记中,通过API提取后格式全丢失。

正确的处理方式:

⛔ 禁止:从IMA笔记提取markdown格式作为模板基准
✅ 必须:让用户直接发送MD文件,或使用本地references/目录下的模板文件
✅ 必须:如需对比两份报告的模块完整性,使用关键词检查而非格式对比

替代方案: 用正则检查关键词是否存在来验证模块完整性:

keywords = ["盈利质量分析", "控股股东减持", "股权质押", "产能布局", ...]
for kw in keywords:
    if kw in report_content:
        print(f"✅ {kw}")
    else:
        print(f"❌ 缺失: {kw}")

注意事项

  • 所有数据来源于同花顺问财 OpenAPI + 东方财富妙想API
  • 报告仅供参考,不构成投资建议
  • safe_get 函数必须使用 default=[] 关键字参数
  • mx-finance-data 每次查询最多返回5个实体的数据
  • QQ Bot附件文件存放在 ~/.hermes/cache/documents/,文件名格式 doc_{uuid}_{filename}
  • 上传到IMA后会自动删除本地.md和.pdf文件,如需保留使用 --no-delete 参数
  • IMA上传使用PDF文件格式(v2),不再使用笔记格式
  • 禁止删除或省略报告模板中的任何模块(用户明确要求)
  • 每次任务执行成功后,保留最新版本脚本,删除所有旧版本/备份文件(用户明确要求)
  • 不要用delegate_task生成完整报告(会超时600秒),应分段或在主Agent上下文中生成

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Biga

A股智能分析与选股工具。维护动态股票池(最多30支),按高科技×中小市值×好业绩原则筛选,推送买卖信号。含独立技术面择时分(-10~+10)用于判断买卖时机。

Registry SourceRecently Updated
General

Fliz Ai Video

Skip the learning curve of professional editing software. Describe what you want — trim the footage, add transitions, and generate captions automatically — a...

Registry SourceRecently Updated
General

Eyes

全球热点事件监控与影响分析。覆盖全球局势、地缘冲突、重大政策、创新技术等可能影响经济、市场和投资的事件,并按行业、汇率、大宗商品链路分析影响。也用于 Cron 定时推送热点摘要(早8点开盘前瞻/晚8点收盘复盘/整点扫描)。

Registry SourceRecently Updated
General

Ai Alt Text Accessibility Sheet

Create a batch alt text accessibility QA sheet for images before publishing, with image purpose, concise alt text, context notes, decorative-image decisions,...

Registry SourceRecently Updated