把前 16 课的零件组装成一条流水线:每天盘后自动生成一份晚报
一个能跑的"每日盘后晚报"工作流:scripts/daily_brief.py 一条命令,串联行情快照、新闻情绪仪表、公告雷达、宏观水位四个组件,产出一份结构化的 Markdown 晚报(data/daily_brief.md),最后落在唯一重要的一栏——明日观察清单。
这节课几乎没有新知识,全是组装。但组装本身是本系列最重要的工程课:单个组件的价值是线性的,工作流的价值是结构的——它决定了哪个组件的失败可以被容忍,以及信息最终必须以什么形状到达你手里。
到第 16 课为止,你手里已经有一把零件:行情接口(第 2 课)、情绪打分(第 3 课)、回测(第 4 课)、工具调用 Agent(第 5 课)、盘中监控(第 6 课)、公告雷达(第 10 课)、宏观水位(第 12 课)。零件继续增加下去,你会得到一个典型的新手系统:十几个脚本,想起来了跑一下,忘了就断更,某个接口挂了整个流程就停摆。
工程上正确的方向是反过来的:先把已有零件编排成一条固定节奏的工作流,再考虑加新零件。编排要解决三个问题:
| 编排问题 | 本课的答案 |
|---|---|
| 零件按什么顺序跑? | 固定流水线:行情 → 情绪 → 公告 → 宏观 → 清单,每天同一顺序、同一时间 |
| 某个零件挂了怎么办? | 组件级容错:该栏目降级为占位说明,晚报照常产出——宁可缺一角,不可整份缺席 |
| 产出给谁看、看什么? | 产出形状固定为五栏晚报,最后一栏永远是"明日观察清单" |
看脚本里的 run_component():每个组件被同一层 try/except 包裹,任何一环抛异常,只换来晚报里一行"本栏目今日生成失败,明早请人工补查"。这就是第 2 课"免费接口一定会挂"在系统层面的回答——不是把每个接口修到不挂(做不到),而是让任何单点失败都不具备杀伤力。
| 环节 | 复用自 | 失败时的降级 |
|---|---|---|
| 1. 持仓自选股当日行情 | 第 2/6 课(东财 → 新浪双源) | 两级实时源都挂 → 内置样本,晚报照常 |
| 2. 新闻情绪仪表 | 第 3 课(打分 + 相关度过滤 + 加权聚合) | 演示模式用预计算结果,不依赖网络与 Key |
| 3. 公告雷达 | 第 10 课(关键词规则分级:高危/关注/提示) | 规则引擎不联网,本机跑,几乎不会失败 |
| 4. 宏观水位提示 | 第 12 课(固定结论,每月人工更新一次) | 纯本地常量,零依赖 |
| 5. 明日观察清单 | 本课新增:把前四栏汇总成"明天怎么办" | 行情缺失时用样本兜底,清单照常生成 |
注意这张表的刻意设计:越靠后的环节,依赖越少、越不可能失败。行情是最不可靠的(免费接口、风控封 IP),放在最前面、配最深的降级链;公告雷达和宏观水位是本地规则与常量,几乎不会挂。这样无论网络环境多糟,你每天 15:05 都能拿到一份晚报——区别只是某一栏是"真实数据"还是"占位说明"。
cd "$HOME/AI Project/Quant Learning"
source .venv/bin/activate
python scripts/daily_brief.py
你会看到(我已在你的环境实测通过,晚报正文略有节选):
运行模式:演示模式(内置样本 + 预计算摘要,不联网)
晚报日期:2026-07-22
[1/5] 拉取持仓自选股行情……
行情来源:内置样本(演示模式,不联网)
[2/5] 新闻情绪打分(第 3 课组件)……
[3/5] 公告雷达扫描(第 10 课规则)……
[4/5] 宏观水位读取(第 12 课结论)……
[5/5] 生成明日观察清单与晚报……
晚报已写入:data/daily_brief.md
============================================================
# 每日盘后晚报 · 2026-07-22
## 主编按语
今日组合一喜一忧:茅台业绩预告落地、情绪偏暖,可持仓观察;宁德遭股东减持且今日浮亏,
但 T+1 冻结、明日才解禁——今晚的任务是写好预案,不是焦虑。宏观水位中性偏高,新建仓位不追高。
## 一、行情摘要
| 股票 | 收盘价 | 涨跌幅 | 成交额(亿) |
|---|---|---|---|
| 贵州茅台(600519) | 1521.00 | -1.55% | 48.20 |
| 宁德时代(300750) | 231.50 | -2.73% | 83.60 |
| 平安银行(000001) | 11.25 | +0.45% | 19.70 |
## 二、情绪仪表
- **贵州茅台(600519)**:加权情绪分 **+0.40**(利好 1 条 / 利空 0 条,仅统计相关度≥0.5 的 2 条)
- **宁德时代(300750)**:加权情绪分 **-0.23**(利好 1 条 / 利空 1 条,仅统计相关度≥0.5 的 2 条)
- 最值得一看:宁德时代公告:股东拟减持不超过1%股份(利空 -0.6,重要股东减持直接压制股价情绪)
……
## 三、公告雷达
- 【高危】**宁德时代**:……减持股份计划的公告(命中关键词:减持)
- 【关注】**贵州茅台**:……半年度业绩预告(命中关键词:业绩预告)
- 【提示】**平安银行**:……转股价格调整的公告(命中关键词:转股)
## 五、明日观察清单
1. **贵州茅台(600519)**——持仓 100 股可正常卖出。今晚有业绩预告(关注级):若明早高开,注意利好兑现的回落……
2. **宁德时代(300750)**——今日新买入 200 股,T+1 冻结中,**明日才解禁可卖**。今日收跌 2.73%且叠加减持公告(高危):
明早集合竞价重点盯开盘价,若低开超 2%,解禁后是否止损由你决定——今晚先写好预案,明早不临时决策。
3. **平安银行(000001)**——无持仓,仅观察。转股价格调整属常规事项,不构成介入理由。
============================================================
花一分钟读清单第 2 条——它是整份晚报的缩影:行情(跌 2.73%)+ 公告(减持,高危)+ 持仓状态(T+1 冻结,明日解禁)三条信息在别的地方各自出现,只有在这一栏被组装成了一个可执行的明日预案。组件各自给出的是"信息",工作流给出的是"计划"。
演示模式全程离线;想看真实收盘数据,加 --real:
python scripts/daily_brief.py --real
我在你的机器上实测了一次,结果本身就是教材:
[1/5] 拉取持仓自选股行情……
东方财富接口失败(ProxyError),尝试下一数据源……
行情来源:新浪财经收盘快照
东财又被风控了(第 2 课封 IP 事件的续集),新浪兜底成功,晚报照常产出。akshare 没有暴露超时参数,脚本用线程包了 15 秒超时(_run_with_timeout()),降级前留 1 秒间隔、绝不无间隔猛刷——这些都是第 2、6 课定下的接口礼仪,现在是工作流的一部分。
脚本还有一个 --live 模式:把晚报素材交给 LLM(默认 DeepSeek,OpenAI 兼容协议)写"主编按语",替代演示模式的预计算文本。此模式已写好但尚未实测(你机器上还没有 Key)——拿到 Key 后 export LLM_API_KEY="sk-你的key" 再跑,有报错直接贴给我。注意:主编按语是晚报里唯一交给 LLM 自由发挥的部分,而它恰好是五栏里最不重要的——重要的四栏全是规则与数据。这不是巧合。
大多数复盘工具把力气花在"今日总结"上:今日涨跌、今日盈亏、今日新闻。这些信息让人感觉很努力,但对明天的决策几乎没有增量——它们描述的是已经收盘的世界。
本课晚报把五栏中的四栏都当作素材,只为服务最后一栏。明日观察清单的写法有三条纪律:
清单最后一行是写给你自己的:"明日盘中无论发生什么,先读这份清单,再决定要不要改主意。"盘后的你冷静、信息完整、没有持仓浮亏的实时刺激;盘中的你恰恰相反。把决策权从盘中的自己手里,移交给盘后的自己——这就是工作流替你做的事。
最后说一个容易被当作"软内容"的硬观点:这份晚报的最大价值不在于自动化省了多少时间,而在于它每天 15:05 固定出现。
情绪化交易的触发器是"不定期地、被行情牵着去看盘":盘中刷到暴跌 → 恐慌翻新闻 → 临时决定割肉。固定节奏把这个回路倒过来:你知道 15:05 会有一份晚报把所有信息整理好等你,盘中就没有理由反复打开行情软件。看盘次数降下来,决策质量就升上去——行为金融里这叫"减少反馈频率"(Benartzi & Thaler, 1995:反馈越频繁,风险偏好越扭曲),不需要 LLM 也能成立。
所以部署建议只有一条:把这条命令挂到每个交易日的固定时刻(crontab 或手动雷打不动地跑),让它成为像刷牙一样的日常,而不是"想起来才跑"的工具。
凭记忆作答——答错比答对更能加固记忆。
tradingagents/graph/ 下怎么把多个 Analyst/Researcher/Trader 节点编排成一张有向工作流图(基于 LangGraph)。对照本课:我们的线性流水线是最简单的图,它的多智能体辩论是更复杂的图,但"组件独立、编排先行、人做最终决策"的骨架是同一个。第 18 课 · 整合项目:盘中提醒闭环——晚报管盘后,下一课把第 6 课的盘中监控接进同一个系统:异动快报 → 对照晚报预案 → 人工确认,打通"计划-提醒-执行"的完整闭环。
有任何不清楚的地方(比如降级链的超时写法、Markdown 生成、crontab 定时),直接问我——我是你的老师。