Documents

A-stock-report

Generate scheduled A-share reports and alerts from market data, then push them to WeCom.

What it does

Generate and send A-share morning reports, close summaries, evening reports, intraday alerts, IPO weekly reports, and weekend finance editions. Python scripts collect market data from Tencent, Sina, AKShare, Eastmoney, and iWencai; LLM-driven report types use runtime prompts. Reports can be pushed to WeCom through a webhook.

When to use it

  • Scheduled A-share morning briefings
  • Automated market-close summaries
  • Intraday market alerts
  • Weekly IPO and weekend finance coverage

The skill document

A股报告系统

A股数据驱动型报告自动生成与推送系统,支持晨报 / 收盘小结 / 晚报 / 盘中预警 / IPO周报 / 财经周末版


目录结构(v3.2.3+1 起明示,v3.5.0 简化)

clawhub publish.clawhubignore 排除 knowledge/ + *.bak(v3.4.4 立),其他整目录上传。装好后 ~/.hermes/skills/A-stock-report/ 结构:

A-stock-report/
├── SKILL.md                      ← 本文件(含完整执行流程 + 14 段护栏 + changelog 索引)
├── _meta.json
├── .clawhubignore                ← v3.4.4 立:排除 knowledge/ + *.bak
│
├── 🐍 scripts/                  ← 12 个 Python 脚本 + 3 个 JSON prompt 模板
│   ├── _lock.py / _send_lib.py  ← 共用库
│   ├── check_consistency.py     ← 14 段一致性护栏(A~H 段)
│   ├── skill_dispatcher.py      ← LLM 驱动型任务的 5d 数据抽取 + prompt 注入
│   ├── collect_{morning,evening}_data.py / send_{morning,close,evening,intraday,weekend,ipo}.py
│   ├── templates/{morning,evening,weekend}.json
│   ├── cron_jobs/{cron_mirror.json, README.md}
│   └── references/{config.json, fallback-chain-validation.md, weekend-4kb-budget.md}
│
└── 📚 knowledge/                ← changelog + 决策主题(**按需 skill_view 加载,不进默认 context**)
    ├── changelog/                ← 按版本号组织
    │   ├── README.md             ← 35 条 changelog 索引
    │   └── vX.Y.Z.md             ← 单版完整细节(v3.5.0 立,19 条新加)
    └── decisions/                ← 跨版本决策中心(按主题)
        ├── README.md
        ├── architecture.md       ← 架构演进
        ├── data-pitfalls.md      ← 数据源踩坑集
        ├── lessons-learned.md    ← 核心教训
        ├── guardrails.md         ← 护栏规则
        └── dispatcher-patterns.md

knowledge/ 为什么保留在 publish 包但不进默认 context (v3.4.4 改): .clawhubignore 排除后, 装上后无 knowledge/ — 用户需主动 skill_view 加载;本机开发保留完整 knowledge/ 不影响发布包大小。


版本历史(Changelog)

精简规则(v3.5.0 立):每条 ≤ 1 行索引,详细实战/根因/修法折到 knowledge/changelog/vX.Y.Z.md。完整 35 条索引见 knowledge/changelog/README.md

未发版段识别:标题含 (未发版) 的是当前 v3.5.0 待 bump 的小改集合。

v3.3.0 ~ v3.4.4(19 条,SKILL.md 主体)— 2026-06-11 晚 ~ 2026-06-16

  • v3.5.1 — send_evening_report.py 加 5 项内容质量硬校验 — 2026-06-18 晚(未发版)
  • v3.4.4 — 异常周(周二 cron)周末要闻端到端验证 — 2026-06-16(未发版)
  • v3.3.5+5 — fallback 链选 URL 原则:主题聚合页 > 单篇头条 — 2026-06-15 20:00 晚报(未发版)
  • v3.3.5+4 — web_search MCP 重试加固:覆盖 {"error": ...} 分支 — 2026-06-15 16:35(未发版)
  • v3.3.5+3 — 周末要闻 4 KB 截断修复 + 防幻觉 + 表格化 + H 段护栏 — 2026-06-15 下午(未发版)
  • v3.3.5+2 — 3 层 fallback 链 + 要闻段反例前置 — 2026-06-15 晨报(未发版)
  • v3.3.5+1 — 3 templates 加 batch_web_search 失败 fallback 机制 — 2026-06-13 晚(未发版)
  • v3.3.5 — 晨报渲染细节对齐 6/12 周五样本 + 删 v3.3.4 过头加固 — 2026-06-13 下午
  • v3.3.4 — 晨报过头加固(已废) — 2026-06-13 凌晨
  • v3.3.3 — 尝试加固晨报,未生效,无代码变更 — 2026-06-12 晚
  • v3.3.2 — 模板约束一体化 + check 段 H 护栏 — 2026-06-12 晚
  • v3.3.1 — 晚报可读性修复:财经要闻 1 空行 + 依据 ≤ 50 字符 — 2026-06-11 深夜
  • v3.3.0 — 财经要闻段"任务定位"协议:防"盘面数据"冒充"要闻" — 2026-06-11 晚
  • v3.2.9 — 3 个 dispatcher 任务 skills 字段清理 — 2026-06-11 下午
  • v3.2.8 — 收盘小结格式对齐:4 处拼接 bug — 2026-06-11
  • v3.2.7 — .env 路径根除:8 脚本多路径回退 — 2026-06-10 下午
  • v3.2.6 — 双副本根除 + jobs.json 隐藏运行时副本修复 — 2026-06-10 上午
  • v3.2.5 — 盘中预警 cron prompt 纯 bash 化 — 2026-06-09 深夜
  • v3.2.4 — 文档补全:明示 knowledge/ 被 clawhub publish 上传 — 2026-06-09 晚
  • v3.2.3 — send_ipo_report.py 迁移到 _send_lib 共用库 — 2026-06-09 晚

历史版本(v3.2.2 ~ v3.0.0,11 条 + v2.0.0 ~ v2.0.10,11 条 = 22 条已折叠)

完整索引见 knowledge/changelog/README.md —— vX.Y.Z.md 22 个详情文件保留。

v3.5.0 改动(本版本 = SKILL.md 精简 + 14 段护栏加严,2026-06-16)

触发: SKILL.md 50665 字节 / 778 行 / 15 个 skill 排名第 1, 是第 2 名 ima-skill (16KB) 的 3.2 倍. Changelog 段 13KB 占 26.3%, 违反 v3.2.0 立"≤ 3 行 / 25 行硬上限"规矩.

改法 (3 处):

  1. Changelog 段 19 条 v3.3.0+ ~ v3.4.4 全部折到 knowledge/changelog/vX.Y.Z.md 详情文件, SKILL.md 留 1 行 / 条索引
  2. ## 数据来源 (2.6KB) + ## IPO周报数据来源 (541B) 合并去重
  3. ## 目录结构 (1.7KB) 简化, 标 knowledge/ 索引外置
  4. frontmatter version: 3.4.43.5.0 (按 MEMORY #12 "结构变更触发 v 大版本号讨论" 例外)

未发版小改一并 bump 到 v3.5.0 (10 条): v3.3.5+1 ~ v3.3.5+5 + v3.4.4. 教训: "小改不刷 vX.Y.Z" 规则容易被滥用 (10 条小改 ≥ 2 个月), v3.5.0 立硬上限 — 未发版累积 ≥ 5 条必须下个结构变更 bump 走, 不许再攒.

MEMORY #12 立新约束: 任何 skill 的 SKILL.md 单文件 > 30KB 必须先瘦身再发版.

安全配置(必读)

所有外部密钥均通过环境变量注入,禁止硬编码。路径可通过 ENV_FILE / ENV_FILE_FALLBACK 环境变量覆盖(默认从脚本自带 + 项目级 _DEFAULT_ENV_PATH 加载)。

密钥白名单原则

每个脚本仅加载本任务实际需要的变量,不得全量注入 _DEFAULT_ENV_PATH 所有密钥。

脚本必需密钥(与 _REQUIRED_KEYS 同源,v3.2.7 修复)
collect_morning_data.pyIWENCAI_API_KEY(A50 期货问财查询用)
send_close_summary.pyWECOM_WEBHOOK_KEY, IWENCAI_API_KEY
collect_evening_data.pyWECOM_WEBHOOK_KEY
send_evening_report.pyWECOM_WEBHOOK_KEY, IWENCAI_API_KEY
send_morning_report.pyWECOM_WEBHOOK_KEY, IWENCAI_API_KEY
send_intraday_alert.pyWECOM_WEBHOOK_KEY
send_ipo_report.pyWECOM_WEBHOOK_KEY, IWENCAI_API_KEY
send_weekend_news.pyWECOM_WEBHOOK_KEY, IWENCAI_API_KEY

问财 API 直连约定(细节见 ## 数据来源 段):所有问财查询统一进程内直连 OpenAPI,不使用 subprocess 外部调用(避免通过 IENV 泄露环境变量给子进程);消费侧必须兼容多字段名(同义词 nlp 翻译可能返回 炸板家数涨停开板家数)。

自动推送说明

配置 WECOM_WEBHOOK_KEY 即表示授权自动推送报告至企业微信。推送是自动化报告系统的组成部分,非人工干预。

密钥环境变量最小权限来源
企业微信 WebhookWECOM_WEBHOOK_KEY仅发送(只写)微信企业版 → 应用 → Webhook
同花顺问财 API KeyIWENCAI_API_KEY只读查询同花顺 i问财 SkillHub

.env 文件格式示例:

WECOM_WEBHOOK_KEY=c4a1cd60-254e-4612-b365-c701482ae98c
IWENCAI_API_KEY=***

注意:本 skill 只用 2 个 key(WECOM + IWENCAI)。妙想 MX_APIKEY / Tushare TUSHARE_TOKEN 等由其他 skill(mx-data / mx-xuangu 等)使用,不要加进 A-stock-report 的 .env


##快速开始

手动跑一个报告(运维/补跑/测试用):

所有 6 个任务的完整命令(source .env + python3 脚本路径 + 可选参数)都集中在 cron_jobs/cron_mirror.jsontasks..prompt 字段

  • LLM 驱动型(晨报/晚报/财经周末版)→ templates/.json 的 prompt 模板 + cron_jobs/cron_mirror.json(无对应节点,由 jobs.json 直接调 dispatcher 注入)
  • 独立脚本型(收盘小结/盘中预警/IPO 周报)→ cron_jobs/cron_mirror.json# 节点

手动跑通用模式:

# 1. 读 cron_mirror.json 看 prompt 字段拿到完整命令
python3 -c "import json; print(json.load(open('/root/.hermes/skills/A-stock-report/cron_jobs/cron_mirror.json'))['tasks']['close_summary']['prompt'])"

# 2. 复制粘贴该命令到终端跑(已含 source .env + python3 路径 + 默认参数)

历史命令备查(v3.1.5 清理前): 见 git log / 备份 /workspace/archive/SKILL_md_pre_4segs_clean_*


执行模式

收盘小结、晚报、晨报 采用不同模式:

  • 收盘小结:单一 Python 脚本,内置全部逻辑(取数 → 打分 → 生成报告 → 推送),cron 直接触发,无需 LLM 生成内容。 晨报、晚报、周末要闻 采用两段式
  • 第一段(cron prompt):调用 dispatcher 生成带真实日期的 prompt,写入约定路径
  • 第二段(同一 session):读取 prompt 文件 → LLM 执行 → 写入内容文件 → 调用推送脚本

这样 SKILL.md 中的 prompt 模板只含通用占位符,日期在运行时由 dispatcher 动态注入。


数据来源

总则(v3.0+ 架构):3 类数据源 + 4 端真相。

3 类数据源(按密钥需求划分):

  • 零密钥:腾讯实时 API(qt.gtimg.cn) · 新浪 hq 数据(hq.sinajs.cn) · akshare 开源接口
  • IWENCAI_API_KEY:同花顺 i 问财 OpenAPI(进程内直连,无 subprocess)
  • 历史报告 MD(仅财经周末版用):/workspace/projects/A股报告系统/reports/

4 端真相(防漂移,详见 ## 定时任务 段):templates/ · cron_jobs/cron_mirror.json · ~/.hermes/cron/jobs.json · SKILL.md

晨报数据来源(collect_morning_data.py + LLM 生成)

数据来源接口 / 字段备注
隔夜美股 3 大指数腾讯实时 APIqt.gtimg.cn/q=usDJI,usINX,usIXIC字段含 name/price/pct
VIX 恐慌指数新浪 hq 数据hq.sinajs.cn/list=znb_VIXpaperCode=znb_VIX,CBOE VIX 指数本身(13 字段:现价/涨跌/52 周范围)⚠️ 2026-06 新浪反爬升级:User-Agent: Mozilla/5.0 太短被识别为爬虫 → 403;必须用完整浏览器 UA 字符串(详见 ~/.hermes/skills/devops/sina-hq-sinajs-403-ua/SKILL.md
富时 A50 期货新浪 hq 数据hq.sinajs.cn/list=...A50ETF(512550)偶发 HTTP 403(同 UA 原因),失败回退华夏 A50ETF;缺失按 v3.1.3 协议 ❌ 数据缺失 占位
港股恒生指数腾讯实时 APIqt.gtimg.cn/q=hkHSI复用 get_us_indices 模式
WTI 原油 + 现货黄金akshare 全球期货现货ak.futures.futures_hf_em.futures_global_spot_em()GC00Y=COMEX 黄金 / CL00Y=WTI

收盘小结数据来源(send_close_summary.py 独立脚本)

数据来源接口
6 大指数 + 成交额腾讯实时 + akshareqt.gtimg.cn + stock_zh_a_spot_em()
涨跌停家数 / 炸板率同花顺问财1 次查询(今日涨停家数 跌停家数 炸板家数
全市场主力净流入东方财富 RPT_MARKET_CAPITALFLOWINDEX_CODE="800000.EI"BONDTYPE="A股"
行业板块涨跌 / 主力资金hithink-sector-selector今日行业板块涨幅前10 / 近5日主力净流入前10行业板块
IF 期货基差新浪 nf_IF0(今日优先)+ akshare futures_main_sina 兜底hq.sinajs.cn

晚报数据来源(collect_evening_data.py + LLM 生成)

数据来源接口
6 大指数 + 成交额同收盘小结同上
亚太股市(日经/韩国综合)腾讯实时qt.gtimg.cn
两融余额 / 两融交易额AKSharemacro_china_market_margin_sh/sz
沪深300 PE / 股市风险溢价同花顺问财单次查询多字段
涨跌停家数同花顺问财复用收盘小结模式

IPO 周报数据来源(send_ipo_report.py

报告模块接口来源
一、排队情况ak.stock_register_kcb/cyb/bj/sh/sz东方财富注册制审核公示
二、本周期上会ak.stock_ipo_review_em东方财富 IPO 审核动态
三、本周期获批 + 四、终止撤回ak.stock_ipo_declare_em证监会公示
五、下周期上会ak.stock_ipo_review_em东方财富 IPO 审核动态
六、新股上市ak.stock_xgsr_ths同花顺(一次调用含上市信息/发行价/首日涨跌幅)

财经周末版数据来源

仅复用历史报告 MD(无新数据采集):/workspace/projects/A股报告系统/reports/收盘小结_YYYYMMDD.md(情绪打分/涨停家数)+ 晚报_YYYYMMDD.md(两融/PE/ERP)。两套以交易日 key 对齐合并,详见下表:

指标来源 MDkey 取法
涨停家数 / 情绪打分收盘小结_YYYYMMDD.md文件名 YYYYMMDD
两融余额 / 两融比例晚报_YYYYMMDD.md报告内两融余额行日期

问财 API 兼容性约定

坑 1 — 字段名同义词(2026-06-01 经验):问财 OpenAPI 在 query 含同义词时 nlp 翻译可能返回不同字段名(如 炸板家数涨停开板家数)。消费侧必须兼容多字段名,避免单一字段名失效导致数据缺失。已修复 send_close_summary.py:167(兼容 炸板家数 / 涨停开板家数)。未来遇到新同义词:在所有调用问财的脚本里加兼容分支,记到此节。

坑 2 — 返回值类型不稳定(2026-06-16 经验,send_close_summary.py:78)

问财同一字段可能不同时刻返回不同类型——同一 query,今天返 float、明天返 str、后天返 int(nlp 翻译后端不稳定)。直接 v > 0 比较会在 str/int/str 互换时炸:

# ❌ 错误写法 — TypeError: '>' not supported between instances of 'str' and 'int'
if "成交额" in k and v and v > 0:
    val_yi = float(v) / 1e8

正确写法 — 三重防御:

if "成交额" in k and v not in (None, "", 0, "0", "0.0"):
    try:
        v_num = float(v)        # 统一强转
    except (TypeError, ValueError):
        continue                # 转换失败跳过,不让一个坏字段拖垮整次查询
    if v_num > 0:               # 数值化后再比较
        val_yi = v_num / 1e8
        return v_num

症状:脚本异常分支 '>' not supported between instances of 'str' and 'int' → fallthrough 到兜底 → 兜底值 0 → 报告显示 全市场成交额:0亿

检测套路(写消费代码时):

  • 任何 iwencai 字段的 if v > 0 / if v < x / if v == y 都视为潜在 bug
  • 修法模板:v not in (None, "", 0) → try float(v) → 转换失败 continue → 数值比较

已修样本send_close_summary.py:78 (commit pre_20260616_turnover_typecompare.bak)


文件名日期规则

报告文件名日期取值
收盘小结--date 参数值;无参数则取当天
晚报--date 参数值;无参数则取当天
晨报生成当天
财经周末要闻生成当天

注意:晚报内容里的两融余额标注日期(如"两融余额(04月13日)")是数据对应的上一交易日,与文件名日期可能差1天。


周末要闻情绪轨迹数据来源

一周情绪轨迹从历史报告MD文件中提取,合并规则:

指标来源key取法
涨停家数/情绪打分收盘小结 收盘小结_YYYYMMDD.md从文件名提取 YYYYMMDD
两融余额/两融比例晚报 晚报_YYYYMMDD.md报告内容里两融余额行提取日期作为 key

两套数据以交易日 key 对齐合并,保证周一到周五趋势线一致。


防并发锁

各脚本使用独立的锁文件,同时运行互不干扰:

脚本锁文件
send_close_summary.py/tmp/a_stock_close_summary.lock
send_evening_report.py/tmp/a_stock_evening.lock
send_morning_report.py/tmp/a_stock_morning.lock
send_weekend_news.py/tmp/a_stock_weekend.lock
send_ipo_report.py/tmp/a_stock_ipo.lock
send_intraday_alert.py/tmp/a_stock_intraday.lock

锁残留检测(v2.0.1 起): 脚本有 finally: _unlock() 兜底,正常退出一定会释放。若锁文件残留

  1. 排查推送阶段异常日志(wx() 返回非 0 / 信号中断 / 网络超时)
  2. 确认无进程在跑(ps -ef | grep send_close)后,手动 rm /tmp/a_stock_close_summary.lock
  3. 残留超过 1 小时不重跑需要介入,避免重复推送

报告模板

晨报

📰 【股市晨报】YYYY年MM月DD日(周X)

━━━ 隔夜全球市场 ━━━
【美股收盘】
▪ 道琼斯:XXXXX.XX点,+X.XX%(精确数字,不得用"约")
▪ 标普500:XXXXX.XX点,+X.XX%
▪ 纳斯达克:XXXXX.XX点,+X.XX%(可附"X连涨/连跌X日")
▪ VIX恐慌指数:XX.XX(+X.XX%),恐慌等级:【低位(<20)/中位(20-30)/高位(>30)】

【港股及A50】
▪ 恒生指数:XXXXX.XX点,+X.XX%(附简要背景)
▪ 富时A50期货:XXXXX点,+X.XX%,偏强/偏弱运行【预判A股明日开盘】

【大宗商品】
▪ WTI原油:XXX.XX美元/桶,+X.XX%(精确数字,不得用"约")
▪ 现货黄金:XXXX.XX美元/盎司,+X.XX%(精确数字)

━━━ 财经要闻 ━━━
【1】(标题)|✅利好/❌利空/⚠️中性 对A股影响
  点评:(简洁分析,≤50字)
【2】(标题)|✅利好/❌利空/⚠️中性 对A股影响
  点评:(≤50字)
(**≤7条**,顺序编号,每条格式固定:
  【编号】(标题)|✅/❌/⚠️标签 对A股影响
  点评:(事件+分析,≤50字))

━━━ 今日操作建议 ━━━
【大盘研判】
(综合外围市场、宏观政策、量能等因素,给出2-3句综合判断)

【操作建议】
1. 【板块/策略】(期限):具体建议+附标的
2. 【板块/策略】(期限):...

【风险提示】
⚠️ (1-3条,最重要的风险)

⚠️ 仅供参考,不构成投资建议。股市有风险,投资需谨慎。

收盘小结

模板由 send_close_summary.py 脚本内置拼装build_report() 函数 f-string,L562+)—— SKILL.md 不再重复维护。改格式请直接改脚本。

协议说明

  • 6 段固定框架:①主要股指表现 ②板块行情 ③全市场主力资金 ④行业主力资金流 ⑤量化情绪打分 ⑥后市展望 + 数据来源落款
  • 量化情绪打分(满分 100,6 因子等权平均):
    • 涨停家数(10~100 家映射)
    • 涨跌停比(对数插值)
    • 炸板率(40%~10% 映射,越低越好)
    • 主力净流入占比(-5%~+5% 映射)
    • 全市场换手率(1%~4% 映射)
    • IF 基差(-300~+150 点映射)
  • 后市展望默认文本(脚本 L560):"市场震荡调整,风格偏向题材与成长,建议控制仓位、关注轮动节奏。"

晚报

📋 【A股晚报】YYYY年MM月DD日

━━━ A股收盘 ━━━
• 上证指数:XXXX.X,↑/↓X.XX%
• 深证成指:XXXX.X,↑/↓X.XX%
• 创业板指:XXXX.X,↑/↓X.XX%
• 科创50:XXXX.X,↑/↓X.XX%
• 沪深300:XXXX.X,↑/↓X.XX%
• 中证500:XXXX.X,↑/↓X.XX%
• 成交额:X.XX万亿元

━━━ 亚太股市 ━━━
• 恒生指数:XXXX,↑/↓X.XX%
• 日经225:XXXXX,↑/↓X.XX%
• 韩国综合:XXXX,↑/↓X.XX%

━━━ 市场风险偏好 ━━━
• 两融余额(MM月DD日):XXXXX亿,较前日+/-XXXX亿
• 两融余额/A股流通市值(MM月DD日)= X.XX%
  阈值:<3%安全 | 3-3.5%预警 | ≥3.5%高危
• 两融交易额/A股成交额(MM月DD日)= X.X%
  阈值:<7%保守 | 7-11%中性 | >11%过热
• 股市风险溢价(MM月DD日)= X.XX%
  阈值:<3%高估 | 3-6%中性 |>6%低估
• 沪深300 PE = XX.XX,近5年分位点 XX.X%

━━━ 财经要闻 ━━━
【1】(标题)|✅利好/❌利空/⚠️中性 对A股影响
  点评:(≤50字)
【2】...(**≤7条**,每条格式固定,点评≤50字)

━━━ 今日操作建议 ━━━
【大盘研判】(2-3句)
【操作建议】
1. 【板块/策略】(期限):具体建议
2. 【板块/策略】(期限):...
【风险提示】(1-3条)

⚠️ 仅供参考,不构成投资建议。股市有风险,投资需谨慎。

财经周末版(cron 触发后 LLM 生成)

📰 【财经周末版】{周六日期} + {周日日期}

━━━ 一周情绪轨迹(5 个交易日,来源:收盘小结 + 晚报)━━━

【1. 市场短期情绪】
• 量化情绪打分:周一XX → 周二XX → 周三XX → 周四XX → 周五XX

【2. 杠杆率】
• 两融余额(亿元):周一X → 周二X → ... → 周五X
• 两融余额占流通市值比例:周一X.XX% → ... → 周五X.XX%

【3. 估值水平】
• 沪深300PE:周一X.XX → ... → 周五X.XX
• 近5年分位点:周一X.X% → ... → 周五X.X%
• 股市风险溢价(ERP):周一X.XX% → ... → 周五X.XX%

【4. 市场预期】
• IF基差:周一X.XX → ... → 周五X.XX

【5. 一周市场解读】
{不超过50字,综合市场情绪/杠杆/估值/预期 4 个维度的一句话总结}

━━━ 数据规则(防错)━━━
数据源 + ❌/⚠️ 硬约束在模板顶部"2. 数据源"段统一定义(v3.3.0 + v3.1.3 合并版),不在此处重复

━━━ 整体市场情绪研判 ━━━
情绪指标总结 | 核心驱动因素 | 当前风险点 | 下周操作参考

⚠️ 仅供参考,不构成投资建议。

定时任务(cron)

7 个 cron 任务(A 股 6 任务 + 每周 Skill 复盘 1 任务)的完整 schedule / repeat / deliver / prompt 字段集中在以下两处真相源:

  • 生产配置(OpenClaw 读)~/.hermes/cron/jobs.json
  • 人类可读镜像(git track)cron_jobs/cron_mirror.json

SKILL.md 不再重复列 cron 表达式(v3.1.5 清理)—— 一处变→多处忘改是 v3.0 之前的痛点。

快速概览:

任务调度类型
A股晨报生成并推送周一至五 08:00LLM 驱动型(template: templates/morning.json
A股晚报生成并推送周一至五 20:00LLM 驱动型(template: templates/evening.json
A股收盘小结周一至五 15:30独立脚本(mirror: close_summary
A股盘中预警周一至五 09:00-14:55 每 5 分钟独立脚本(mirror: intraday
A股周末要闻生成并推送周日 20:00LLM 驱动型(template: templates/weekend.json
每周 Skill 复盘周日 18:00skill 自审
A股IPO周报周六 10:00独立脚本(mirror: ipo_report

安装与验证

配置完 cron 后,按以下顺序逐一检查:

Step 1:密钥检查

权威密钥白名单表在 ## 密钥白名单原则 段(每个脚本需哪些 env 变量)。

快速检查 2 个 env 变量是否就位:

# 应输出 2 行非空(本 skill 只需 2 个 key)
for key in WECOM_WEBHOOK_KEY IWENCAI_API_KEY; do
  grep "^${key}=" /workspace/.env && echo "  ✅ $key"
done

未配齐会怎样: 脚本在 except 块内捕获缺失,会 notify_failure() 发预警 + exit 1(v3.1.0 修复链),不会静默继续。

注意send_evening_report.py 的"财经要闻"和"明日操作建议"两个区块依赖 cron 中的 LLM 步骤生成,不是脚本自己能产出的。若未配置对应 cron task,这两个区块永远为空,这是设计预期,不是 bug。

Step 2:依赖检查

# 检查 akshare
python3 -c "import akshare; print('akshare', akshare.__version__)"

# 检查 tushare(IPO周报需要)
python3 -c "import tushare; print('tushare OK')"

# 检查 hithink-sector-selector CLI
python3 /workspace/skills/hithink-sector-selector/scripts/cli.py --help | head -3

Step 3:Cron 任务检查

跑护栏脚本一次性验证 4 端一致性(templates ↔ cron_mirror ↔ jobs.json ↔ SKILL.md):

python3 /root/.hermes/skills/A-stock-report/scripts/check_consistency.py
# 预期:✅ 全部 4/4 项通过,exit=0

不要再用"❌手对表"逐行核对——v3.1.5 之前 SKILL.md 这里有 7 行"应存在 ✅"表,靠人记得跑 1 个命令 + 7 行眼睛对——v3.1.5 改用护栏脚本机械检查,杜绝漂移。


Cron 任务配置指引

6 个任务分两类:

  • LLM 驱动型(3 个):晨报 / 晚报 / 财经周末版 — prompt 外置于 templates/,由 scripts/skill_dispatcher.py 读取注入 LLM,LLM 解读后调脚本落地推送。
  • 独立脚本型(3 个):收盘小结 / 盘中预警 / IPO 周报 — 无需 LLM,调度配置外置于 cron_jobs/,由 OpenClaw gateway 直接 source .env && python3 ... 跑脚本。盘中预警为每 5 分钟一次高频任务(必须无 LLM 介入)。

为什么用文件中转(LLM 型)? cron prompt 在独立 session 运行,无法直接将变量传给后续脚本。通过写入约定路径的文件,脚本读取后注入报告模板,实现解耦。

🛡️ 4 端一致性护栏(v3.1.5+):本 skill 有 4 端真相 — templates/(LLM 调度模板,机器读) / cron_jobs/cron_mirror.json(生产 cron 镜像,人读) / ~/.hermes/cron/jobs.json(生产 cron 真实配置,OpenClaw 读) / SKILL.md(文档)。改任何一端都可能造成幽灵模板(v3.1.3 的教训)。修改以下任一文件后必须跑 python3 scripts/check_consistency.py(exit 0=全过,exit 1=有错误):

  • templates/*.json(3 个 LLM 任务 prompt)
  • cron_jobs/cron_mirror.json(3 个独立脚本任务)
  • ~/.hermes/cron/jobs.json 中 3 个独立脚本任务的 prompt
  • SKILL.md 任务清单段(### N. 任务名(详见 ...) 格式)

| 报错时用 --fix-hint 看修复建议。脚本会检查 A) templates ↔ dispatcher 任务集、B) cron_mirror ↔ jobs.json prompt 字字一致、C) SKILL.md 引用真实存在、D) dispatcher 任务不在 mirror 出现、E) SKILL.md 主体无硬编码 cron 表达式 / .env 路径 / source+send 一行命令(v3.1.6+ E 段)。

1. 晨报(详见 templates/morning.json)

Prompt 模板外置于 templates/morning.json(v3.0 架构),由 scripts/skill_dispatcher.py 读取并注入。

2. 收盘小结(详见 cron_jobs/cron_mirror.json#close_summary)

独立脚本模式 —— 无需 LLM,调度配置外置于 cron_jobs/cron_mirror.json(v3.0 架构;v3.1.4 起 3 任务合为单文件,close_summary 为 tasks.close_summary 节点),由 OpenClaw gateway 直接读取。脚本路径见 json 内 prompt 字段。

3. 晚报(详见 templates/evening.json)

Prompt 模板外置于 templates/evening.json(v3.0 架构),由 scripts/skill_dispatcher.py 读取并注入。

4. 盘中预警(详见 cron_jobs/cron_mirror.json#intraday)

独立脚本模式 —— 无需 LLM,调度配置外置于 cron_jobs/cron_mirror.json(v3.0 架构;v3.1.4 起 3 任务合为单文件,intraday 为 tasks.intraday 节点),由 OpenClaw gateway 直接读取。脚本路径见 json 内 prompt 字段。v3.1.3 之前该任务的模板曾错误地放在 templates/intraday.json(LLM 驱动型设计),但实际 cron 早已是独立脚本模式;v3.1.3 已删除幽灵模板、归档到 cron_jobs/。

5. 财经周末版(详见 templates/weekend.json)

Prompt 模板外置于 templates/weekend.json(v3.0 架构),由 scripts/skill_dispatcher.py 读取并注入。

6. IPO周报(详见 cron_jobs/cron_mirror.json#ipo_report)

独立脚本模式 —— 无需 LLM,调度配置外置于 cron_jobs/cron_mirror.json(v3.0 架构;v3.1.4 起 3 任务合为单文件,ipo_report 为 tasks.ipo_report 节点),由 OpenClaw gateway 直接读取。脚本路径见 json 内 prompt 字段。

验证 3:端到端 cron 验证

实际 cron 跑过后,检查:

  1. 推送消息中"财经要闻"和"明日操作建议"区块是否有内容
  2. 内容日期是否与当天日期一致
  3. 报告文件名是否为当天日期

若发现为空,回到"验证 2"确认内容文件是否成功写入。

常见问题

Q1:生成后如何做质量检查? A:生成报告后必须检查以下四项:

  1. 日期检查:报告第一行日期 == 文件名日期 == 当天实际日期(三者必须一致)
  2. 星期检查:报告中的日期字符串(YYYY年MM月DD日(周X))与文件名中的日期 weekday() 对应周一~周五正确
  3. 数据完整性
    • 收盘小结:指数行情、情绪打分、板块资金流、风险偏好、操作建议五段落齐全
    • 晨报/晚报:涨跌停统计、风险偏好、操作建议三段落齐全
  4. 时效性:数据陈旧(>2个交易日)时在报告内注明

Q2:如何判断涨停情绪? A:涨停情绪由第4节打分函数统一评分(满仓风险系数 × 涨停家数权重 + 涨跌停比 × 炸板率综合得出 0-100 分),不再单独使用 emoji 分级。报告生成后通过"质量检查第3项"确认段落齐全即可。

  • 参考:情绪总分 ≥ 70 → 🟢做多;≥ 55 → 🟡偏多;≥ 40 → ⚪分歧;≥ 25 → 🟠偏空;< 25 → 🔴冰点

Q3:炸板率如何评分? A:炸板率由第4节打分函数中的 _sc(exp_rate, 40, 10) 公式映射到 0-100 分,阈值区间 [40%, 10%],炸板率越低得分越高。

  • 参考:情绪总分 ≥ 70 → 🟢做多;≥ 55 → 🟡偏多;≥ 40 → ⚪分歧;≥ 25 → 🟠偏空;< 25 → 🔴冰点

Q4:两融数据比当天少一天? A:正常现象。两融数据在当天收盘后约 1~2 小时后更新,晚报/收盘小结取到的是上一交易日数据。

Q5:主力净流入 > 500亿时显示什么? A:打印预警信息 ⚠️ 主力净流出-XXX亿,超大单+大单砸盘XXX亿,异常大额出逃,注意风险,但保留真实数值(不重置为0)。

Q6:定时任务重复推送? A:已内置文件锁机制的脚本会拒绝并发执行。当前各脚本锁机制如下:

  • 晚报:send_evening_report.py/tmp/a_stock_evening.lock(exists 检测 + sys.exit(0),finally 解锁)
  • 盘中预警:send_intraday_alert.py/tmp/a_stock_intraday.lock(同上)
  • 周末要闻:send_weekend_news.py/tmp/a_stock_weekend.lock(同上)
  • IPO周报:send_ipo_report.py/tmp/a_stock_ipo.lock(原子 os.O_EXCL 创建,更严格,finally 解锁)
  • 晨报:send_morning_report.py/root/.hermes/skills/A-stock-report/scripts/.morning_report_lock.json(JSON 文件,内容含 datestatus,检查当日是否已成功推送后才允许重复执行)

Q7:报告内容日期和文件名不对应? A:收盘小结文件名=报告日期;晚报文件名=生成当天日期,内容日期=上一交易日;周末要闻以内容里两融余额标注的日期为 key,与收盘小结文件名日期对齐合并。

Q8:如何使用 --date 指定历史日期? A:收盘小结和晚报均支持 --date YYYY-MM-DD,如 python3 send_close_summary.py --date 2026-04-13。晨报不支持指定历史日期。

Questions people ask

Which report types are supported?
Morning reports, close summaries, evening reports, intraday alerts, IPO weekly reports, and weekend finance editions are supported.
What credentials are required?
The system uses only WECOM_WEBHOOK_KEY and IWENCAI_API_KEY, loaded through environment variables. Each script loads only the keys needed for its task.
How are reports generated and delivered?
The close summary runs as a standalone Python pipeline for collection, scoring, report generation, and delivery. Morning, evening, and weekend reports use a dispatcher to inject runtime dates into prompts before an LLM writes content and a script pushes it to WeCom.

Related skills

Turn A-share data and filings into a structured fundamental, valuation, governance, and risk assessment.

78 installs1 stars

Retrieve structured Chinese market data and research material through a searchable CLI.

86 installs2 stars

Produces 24-hour capital-market delta reports focused on anomalies, catalysts, and affected securities.

73 installs1 stars

Convert Chinese finance questions into checked Tushare research workflows, summaries, and data files.

559 installs33 stars