程序员量化交易实战 26:先抽象提醒通道
原创 · 约 7 分钟阅读 · 阅读 --
Last updated on

程序员量化交易实战 26:先抽象提醒通道

作者: Alex Xiang


程序员量化交易实战 26:先抽象提醒通道

古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。

第 25 篇已经给每日流程加了生产检查。接下来要把日报送出去。

第 26 篇先不接飞书、不接邮件,只做提醒通道抽象。消息怎么生成是一回事,发到哪里、是否被接收,是另一回事。

ZiCode 工程师整理模拟盘提醒通道

先稳定发送接口

提醒通道最容易一开始就写死。

今天发到文件,明天想发到飞书,后天又想发邮件。如果日报生成逻辑直接依赖某个具体通道,后面改起来会很别扭。

回执对象

第 26 章新增 app/notification_channels.py

@dataclass(frozen=True)
class NotificationReceipt:
    channel: str
    accepted: bool
    destination: str
    message_title: str
    sent_at: datetime
    error: str = ""

发送动作必须有回执。没有回执,就无法在后续健康报告里判断提醒是否真的被通道接收。

这里的“接收成功”只表示通道层愿意接收这条消息,不等于读者已经看到消息。真实系统里通常还会继续拆成发送成功、平台回执成功、用户已读等更细的状态。第 26 篇先保留最小语义:消息是否被通道接受。

通道协议

class NotificationChannel(Protocol):
    name: str

    def send(self, message: PaperAlertMessage, *, destination: str, sent_at: datetime) -> NotificationReceipt:
        ...

这个协议很小,只约束输入消息、目的地和发送时间。具体通道可以是文件、飞书、邮件,也可以是测试用的内存实现。

当前联动运行结果

第 26-30 篇现在可以通过同一条命令运行:

uv run python -m scripts.chapter_examples paper-notify

这条命令会先生成目标权重、取价格、跑每日流程,然后把日报发到内存通道和文件通道。第 26 篇关注的是通道协议和回执:

paper-notify 命令生成的提醒通道回执

这次运行里,内存通道返回 accepted=True,目的地是 paper-daily。这个结果后面会进入运行健康报告,成为判断“日报是否真的送出”的依据。

本章更新与代码仓库

本章更新内容:

  • 新增 app/notification_channels.py
  • 定义通知回执和通道协议。
  • 实现 MemoryNotificationChannel,用于离线测试。
  • 增加 paper-notify 联动示例,展示每日流程生成日报后的通道回执。
  • 补充通道接收成功与用户已读之间的语义边界。
  • 新增 tests/test_notification_channels.py,覆盖有效消息、缺目的地和空正文。

代码仓库:

https://github.com/ax2/zi-quant-platform

本章代码:

git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-26
uv sync --extra dev
uv run pytest tests/test_notification_channels.py

第 26 章提交为 6bf1a6f,tag 为 chapter-26

本篇小结

提醒通道要先有边界,再接具体平台。

第 26 篇把发送接口和回执结构稳定下来。下一篇会实现一个文件型通道,让日报发送在本地也能被验证和回放。

微信公众号

欢迎关注「字与码」

如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。

微信公众号字与码二维码