2.3 消息流与数据流


2.3 消息流与数据流

本节摘要:本节用三条路径把前两节的静态边界与设计哲学串成动态图景。路径一:一次下单——从 trading-worker 里策略产出 intent,经风控闸门,订单落库为待处理状态,经交易所适配器发往交易所,成交回报回流更新状态,全程经数据库与队列、进程之间零直连。路径二:行情入库——交易所接口经 data_sources 模块拉取或订阅,规范化后落库,供指标与策略消费。路径三:对账回流——定时任务比对本地订单状态与交易所真实状态,修正漂移。每条路径都标注「谁、读写什么、失败时怎样」,末尾附排查收敛树与一节常见问题,读完你会获得在日志与数据库里定位任意一笔订单的能力。

学习目标

  • 按步复述一次下单从 intent 到成交回报的完整路径。
  • 说清行情数据从交易所到策略眼前的入库链路与节奏。
  • 解释对账任务解决什么问题、为什么必须定时做。
  • 用「查库定位法」追一笔虚拟订单的每一步。

一、路径一:一次下单的旅行

trading-worker PostgreSQL 交易所 ┌─────────────────┐ intent ┌──────────────┐ 适配器下单 ┌──────────┐ │ 策略 on_bar 计算 │ ─────────▶ │ 风控闸门检查 │ ──────────▶ │ Binance │ │ (读库:行情/仓位) │ │ 订单落库 │ │ OKX … │ └─────────────────┘ │ 状态=待处理 │ └────┬─────┘ ▲ └──────┬───────┘ │ │ │ 轮询/推送回报 ▼ │ ┌───▼────────┐ 成交/拒绝/部分成交 └──────────────────────────│ 状态更新 │ ◀──────────────┘ 策略读到新状态,继续计算 │ 状态=已成交 │ └────────────┘ 注:backend 不在此图主链上——它创建/修改的是「意图与配置」, 不是订单本身(第 2.2 节哲学的直接体现) ​
步 谁 读写 失败时
1 策略(trading-worker 内) 读:行情、账户状态 数据缺失则本周期不出 intent
2 风控闸门 读:限额规则;写:检查结果 拦截,订单停留在意图态,留痕可查
3 订单落库 写:订单记录(待处理) 落库失败则重试,宁可慢不可丢
4 交易所适配器 读:待处理订单;外呼交易所 网络失败按重试策略处理,状态可见
5 回报处理 写:订单状态(成交/拒绝/部分) 回报丢失由对账兜底(路径三)

两个读图要点:每一步都留库痕——这是可观测的来源;失败不消失——要么重试、要么留痕等待对账,任何一步都不会静默丢弃。

二、路径二:行情入库

交易所 REST / WebSocket data_sources 模块 PostgreSQL ┌──────────────────┐ 拉取/订阅 ┌───────────────────┐ 规范化写 ┌──────────┐ │ K 线 / 深度 / 成交 │ ─────────▶ │ 连接管理·限速·重连 │ ────────▶ │ 行情表 │ └──────────────────┘ │ 字段映射·单位统一 │ └────┬─────┘ └───────────────────┘ │ 读 ┌─────────────┴──────────┐ ▼ ▼ 指标计算(第4章) 策略 on_bar(第5章) ​

入库节奏的两类口径(具体策略以官方文档为准):K 线类通常以「闭合」为准落库——只有一根 K 线走完,它才是事实;未闭合的当前根属于「现在进行时」,供展示可以,进回测不行。深度与成交类是流式快照,按节流策略更新。这条纪律直接决定第 6 章回测会不会偷看未来数据。

失败处理:接口断流时先重连、再补数(REST 拉历史区间补洞),补不上的缺口进入第 3.3 节的质检流程。行情入库的责任人按任务类型分布在 scheduler-worker 与 celery-worker(第 2.1 节职责表),但「事实」只认库里的数据。

三、路径三:对账回流

对账回答一个尖锐的问题:**你认为的状态,和交易所认为的状态,一致吗?**漂移的来源很多——回报丢失、进程在写状态的半路被杀、交易所侧的维护性撤销。对账任务定期做三方比对:

比对项 本地(库) 对端(交易所) 不一致时
订单状态 待处理/已成交/已撤销 交易所订单状态 以对端为准修正本地,留修正记录
持仓数量 账户表 交易所账户 差异超阈值则告警并暂停相关策略
可用余额 账户表 交易所账户 告警;人工确认后修正

用最小代码把「以对端为准」的比对逻辑写出来(教学示意):

# reconcile_demo.py —— 对账比对的最小示意(纯标准库) def reconcile(local_orders, remote_orders): """两侧均为 {订单号: 状态};状态示意:pending / filled / cancelled""" drift = [] for oid, local_state in local_orders.items(): remote_state = remote_orders.get(oid) if remote_state is None: drift.append((oid, local_state, "对端不见此单", "本地核查后处理")) elif local_state != remote_state: drift.append((oid, local_state, remote_state, "以对端为准修正并留痕")) return drift if __name__ == "__main__": local = {"A1": "pending", "A2": "filled", "A3": "filled"} remote = {"A1": "filled", "A2": "filled"} for row in reconcile(local, remote): print(row) # 示意:A1 被修正为已成交;A3 对端不见,转入本地核查 ​

注意代码里没有任何「自动重下单」之类的补救——对账的职责是修正认知,不是替策略决策。发现漂移之后的动作(重发、放弃、告警人工介入)属于上层流程,混进对账会让它变成第二个交易循环。

对账由定时任务驱动(celery-beat 节拍 + celery-worker / scheduler-worker 执行,具体分工以官方文档为准),这本身就是第 2.2 节哲学的应用:对账是长周期、必须与交易循环解耦的动作,它的裁判依据永远是交易所这个外部事实源,而不是本地内存。

在 paper 模式下,signal-only 虚拟账户(官方口径:只记录信号不发真实订单)没有真实对端,对账退化为「信号记录完整性检查」——这也是 paper 与实盘在工程上的本质差异之一,第 7、8 章会反复回到这一点。

四、综合演练:追一笔订单

设想你在界面(backend 写库的意图)配置了一个 paper 策略,某根 K 线闭合后它应该入场。排查顺序:

  1. 查行情表——那根 K 线闭合落库了吗?(路径二)
  2. 查意图与风控记录——intent 产出了被拦,还是没产出?(路径一步骤 1~2)
  3. 查订单表状态——待处理卡住还是已成交?(路径一步骤 3~5)
  4. 查对账记录——有没有自动修正过什么?(路径三)

四步各自「查哪里」再落具体一点(表名与字段示意,以官方文档为准):

排查步 查哪里 找什么
1 行情 行情表:该标的该周期的闭合根 那根 K 线存在吗、字段完整吗
2 意图 意图与风控记录 有没有产出、被哪条规则拦下
3 订单 订单表:状态与时间戳 停在待处理还是已成交、卡在哪一步
4 对账 对账修正记录 有没有自动修正、修正了什么
排查的收敛路径(示意) 症状:该成交没成交 └─▶ 行情在吗 ──否──▶ 数据层问题(第 3 章) │是 └─▶ 意图在吗 ──否──▶ 策略条件没触发(第 4、5 章) │是 └─▶ 被拦了吗 ──是──▶ 风控处置日志(5.3 节) │否 └─▶ 订单状态 ──卡住──▶ 适配器与回报链路 ​

四步之内必有答案,因为每条路径的每一步都有库痕。这就是架构章的最终回报:系统对你不再是黑箱,而是一张可以按图索骥的地图。

五、常见问题与排查

疑问 排查方向
订单一直停在待处理 先看适配器日志与重试策略,再看对账记录是否已在跟进
同一根 K 线,回测与实盘行为不同 查闭合纪律:实盘是否消费了进行时根(3.1 节)
对账频繁修正本地状态 病因多在回报链路稳定性,不在对账本身;查适配器连接质量
行情有缺口但策略照常在跑 缺口应进 3.3 节质检;策略侧靠幂等保证补数重放无害
paper 模式下需要对账吗 退化为信号记录完整性检查,同样不可省略

本节要点回顾

  • 下单五步:intent ──▶ 风控 ──▶ 落库 ──▶ 适配器 ──▶ 回报;backend 不在主链上。
  • 每一步留库痕、失败不静默消失:重试或等待对账。
  • 行情以「闭合为准」落库,未闭合数据不进回测;断流靠重连加补数。
  • 对账以交易所为外部事实源修正本地漂移,是解耦的长周期任务。
  • 四步排查法:行情 ──▶ 意图/风控 ──▶ 订单状态 ──▶ 对账记录。
  • 排查收敛树:行情、意图、拦截、订单四问依次否决,四问之内必有答案。

三条路径里反复出现同一个源头:数据。行情从哪里来、宏观数据如何聚合、多源口径怎么统一——第 3 章把这条源头展开成完整一章。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U