Sequoia-X 项目研究站 · 飞书播报

Sequoia-X 飞书播报:按策略分群推送的 webhook 路由

推送模块把选股结果组装成飞书交互卡片,再按策略的 webhook_key 决定发到哪个群:环境变量里配了 STRATEGY_WEBHOOK_<KEY> 就推给对应机器人,没配就回落到默认 Webhook。这类设计的实际价值是——海龟突破和定增公告可以进不同的群,不用在代码里改收件人。

消息形态:交互卡片(interactive)路由:7 个策略 key + 默认回落依据 notify/feishu.py 与 core/config.py(2026-09 核验)
7 个策略类各自带一个 webhook_key
环境变量路由STRATEGY_WEBHOOK_<KEY>
未配置回落用默认 FEISHU_WEBHOOK_URL
成功判定响应体 code == 0
飞书推送路由示意(依据 notify/feishu.py 与 core/config.py 整理,非官方流程图)。
Card

Sequoia-X 的飞书播报卡片长什么样

源码构造的是飞书 interactive 卡片,字段固定。

卡片部分源码内容适用场景注意点
消息类型msg_type = "interactive"需要结构化排版的播报不是纯文本消息,网关或中转层需要支持卡片格式
标题📈 Sequoia-X 选股播报 | {策略名},模板蓝色一眼分辨是哪个策略的结果策略名取的是类名(如 MaVolumeStrategy),不是中文别名
摘要行日期 / 策略 / 选股数量三项快速确认当天是否跑过日期取的是执行当天(date.today()),不是数据源的最后一个交易日
分隔线hr 元素视觉分层纯展示,不影响数据
选股列表每个标的一段 lark_md 链接:[名称](https://xueqiu.com/S/<代码>)点进去直接看个股页名称要先查库外的股票基础信息,查不到就用代码兜底
链接前缀6 开头 → SH;4 / 8 开头 → BJ;其余 → SZ生成雪球代码与数据层入库时的 sh./sz. 规则不同,别混淆
空结果列表为空时不会走到推送(main.py 先判断命中数)避免空卡片刷屏推送器内部虽有「(无选股结果)」兜底文案,正常流程不会用到
Routing

Sequoia-X 七个策略的 webhook 标识

标识定义在各策略类里,环境变量名由配置模块扫描前缀得到。

策略类webhook_key环境变量名适用场景
MaVolumeStrategyma_volumeSTRATEGY_WEBHOOK_MA_VOLUME均线放量信号单独建群
TurtleTradeStrategyturtleSTRATEGY_WEBHOOK_TURTLE突破类信号单独建群
HighTightFlagStrategyflagSTRATEGY_WEBHOOK_FLAG旗形整理信号单独建群
LimitUpShakeoutStrategyshakeoutSTRATEGY_WEBHOOK_SHAKEOUT洗盘信号单独建群
UptrendLimitDownStrategylimit_downSTRATEGY_WEBHOOK_LIMIT_DOWN错杀信号单独建群
RpsBreakoutStrategyrpsSTRATEGY_WEBHOOK_RPS强势股信号单独建群
PrivatePlacementStrategyprivate_placementSTRATEGY_WEBHOOK_PRIVATE_PLACEMENT公告事件单独建群
基类默认值default回落到 FEISHU_WEBHOOK_URL必填项,缺失则配置校验直接失败
路由是怎么生效的:配置模块在初始化后遍历环境变量,把所有以 STRATEGY_WEBHOOK_ 开头的键收集进一个映射(键名去掉前缀并转小写);推送时用策略的 webhook_key 去查这个映射,查不到就用默认 Webhook。所以键名的大小写与拼写必须与策略类里的标识一致。
Setup

Sequoia-X 飞书配置:从建机器人到验证

按顺序做完这五步,推送链路才算打通。

  1. 在飞书群里添加自定义机器人

    在目标群设置里添加「自定义机器人」,拿到该机器人的 Webhook 地址。开源项目不包含机器人创建能力,这一步在飞书侧完成。

  2. 先配一个默认 Webhook

    把地址写进项目根目录 .envFEISHU_WEBHOOK_URL。它是必填项——不填的话程序在读取配置阶段就会失败退出,连数据同步都不会开始。

  3. 按策略补充专属 Webhook

    想让某个策略单独进群,就在 .env 里加对应的 STRATEGY_WEBHOOK_<KEY>,例如 STRATEGY_WEBHOOK_TURTLE。没配的键自动回落到默认地址。

  4. 跑一次日常模式观察日志

    执行 python main.py,每条命中的策略都会打印一行推送结果:成功是「飞书推送成功 [key],共 N 只股票」,失败会带上 HTTP 状态与飞书响应体。

  5. 到群里核对卡片内容

    确认标题里的策略名、日期、数量与标的一一对应。若同一只股票出现在多条卡片里,那是因为它同时满足多个策略——这是预期行为。

日志格式示例(行为来自源码,非真实运行记录):
飞书推送成功 [turtle],共 8 只股票 / 飞书推送失败 [turtle] HTTP状态=400 飞书响应=...。真实的运行记录本站没有采集,页面只描述源码会打印什么。
Failure

Sequoia-X 推送失败怎么判定与排查

最容易踩的坑:HTTP 200 不等于推送成功。

现象源码判定适用场景处理方向
HTTP 200 但没收到消息响应体 code != 0 仍记为失败地址失效、机器人被移除、内容被风控看日志里的飞书响应体,按返回码定位
日志出现请求异常捕获 requests.RequestException 后记 ERRORDNS / 网络 / 代理问题换网络环境或用能访问飞书的机器执行
单次推送耗时 10 秒请求超时设为 10 秒网络拥塞或服务端响应慢超时只影响这一条推送,不会中断后续策略
进了错误的群webhook_key 查映射,查不到回落默认环境变量名拼错、大小写不一致对照上表逐个核对键名
推送失败但数据已更新推送异常被吞掉,不抛出、不影响主流程数据入库与推送解耦推送失败不会让当天数据白拉,修复后可重跑(当天重写是安全的)
完全没有推送日志命中为空时 main.py 直接跳过推送阈值严或当天行情不匹配先看策略是否命中,再看推送
Names

Sequoia-X 卡片里的股票名称从哪里来

卡片上显示中文名而不是代码,这一步是推送前额外做的查询。

环节实现适用场景注意点
查询方式推送前逐只调用 baostock 基础信息接口取名称命中数量不多时成本可接受这是一次额外登录与逐只查询,命中多时推送阶段会变慢
失败兜底查不到名称时用雪球代码(如 SZ000001)当显示名数据源临时不可用不会因为取名称失败而放弃整条推送
名称缓存源码未做持久化缓存每日一次推送场景够用频繁手动重跑会重复查询,注意上游接口负担
链接格式lark_md 的 [名称](url) 语法点击直达个股页卡片需以 lark_md 渲染,纯文本模式看不到链接
与库内代码的关系库内存纯数字代码,推送时再转带前缀格式保持存储与展示解耦两条转换规则不一致(sh./sz.SH/SZ/BJ),改代码时别互相替换
去重同一策略内部返回的清单已是去重结果定增策略尤其需要(同一标的可能多次定增)跨策略之间不做合并去重
安全提示:Webhook 地址等同于向该群发消息的凭据,请写在 .env 等本地配置里,不要提交到版本库、不要贴进截图或公开文档。本站示例中出现的地址均为占位符。
FAQ

飞书播报常见问题

不配飞书 Webhook,Sequoia-X 能用吗?

不能。默认 Webhook 是配置模型的必填字段,缺失时初始化配置就会抛校验错误,程序在启动阶段退出。如果你只想要数据不想要推送,需要自行改造代码,这超出本站整理范围。

Sequoia-X 一个群能收到所有策略结果吗?

可以。只配 FEISHU_WEBHOOK_URL 不配任何 STRATEGY_WEBHOOK_* 时,所有策略都回落到这个默认地址,结果都会进同一个群。想分组就补对应的环境变量。

Sequoia-X 推送成功但群里看不到?

先确认消息类型:源码发的是 interactive 卡片,如果接收端或中转层只支持纯文本,可能被丢弃。其次确认机器人仍在群里且有发送权限,再核对日志里是否真的打印了「飞书推送成功 [key]」。

Sequoia-X 推送失败要重跑整个流程吗?

通常不必。推送与数据入库是解耦的:推送异常只记日志,不影响已经写入的数据。修好 Webhook 后手工重跑当天是安全的,因为日常模式写入前会先删除当日记录。

Sequoia-X 卡片日期为什么是执行日?

源码里卡片日期取的是程序执行当天的日期,而不是数据源中最后一个交易日的日期。节假日补跑时两者可能不一致,判断数据新鲜度应结合策略命中情况与日志里的同步条数。

能改成钉钉、企业微信或邮件吗?

仓库里的通知模块只实现了飞书,没有其他渠道的代码。要接别的渠道需要自己按 notify/ 目录的结构新增模块并在 main.py 中调用。以上以仓库当前源码为准。

推送不通时,按排查表往下走

报错页把配置、数据、交易日与推送四类失败分开处理,并给出安全重跑方式。