auto_trade_sys/docs/bian/订单记录简化流程(支付式闭环).md
薇薇安 13a0e7d580 delete: 移除过时的文档与代码文件
删除了多个不再使用的文档和代码文件,包括交易更新推送、条件订单推送、REST API 文档、WebSocket API 文档及相关的策略分析文档。这些文件的移除有助于清理代码库,确保项目的整洁性与可维护性。
2026-02-20 17:49:00 +08:00

7.9 KiB
Raw Permalink Blame History

订单记录简化流程(支付式闭环)

参考 订单交易更新推送.txt条件订单交易更新推送.txt,把订单记录做成「先本地单号 → 写 DB + 下单 → 仅靠 WS 推送更新状态」的闭环,和支付系统类似。


一、目标流程(你期望的)

  1. 先本地生成订单号(如 client_order_id = SYS_时间戳_随机)。
  2. 写 DB 与下单尽量一体:先插入一条「待成交」记录(带 client_order_id),再立刻用该 id 去交易所下单REST 或 WS选更稳的方式逻辑上视为「同一事务」——下单失败则把该条记录标为失败/取消。
  3. 状态只跟 WS 走:用币安 ORDER_TRADE_UPDATE(和必要时 ALGO_UPDATE驱动所有「成交、平仓、取消」等状态与字段更新DB 只根据推送更新,不依赖 REST 轮询结果做主数据。

这样:一条 DB 记录 = 一次「开仓意图」或「平仓意图」,用本地 id 和交易所 id 串联WS 是唯一事实来源,逻辑简单、易对账。


二、币安推送里用到的字段docs/bian

ORDER_TRADE_UPDATE订单交易更新推送

字段 含义 用途
e 事件类型 ORDER_TRADE_UPDATE
o.c 客户端自定义订单 ID clientOrderId,我们下单时传的,用来唯一匹配「本地这条记录」
o.i 订单 ID orderId,交易所订单号,写 entry_order_id / exit_order_id
o.x 本次事件类型 NEW / TRADE / CANCELED / EXPIRED 等
o.X 订单当前状态 NEW / PARTIALLY_FILLED / FILLED / CANCELED 等
o.ap 订单平均成交价 成交后更新 entry_price 或 exit_price
o.z 订单累计成交量 成交数量
o.R 是否只减仓 true = 平仓单
o.rp 该笔实现盈亏 平仓时写 pnl/realized_pnl

开仓o.R != trueo.X == FILLED → 用 o.c 找到 pending 记录,更新为 open写入 entry_order_id=o.ientry_price=o.apquantity=o.z
平仓o.R == trueo.X == FILLED → 用 o.s(symbol) + 当前 open 记录匹配,写入 exit_order_id=o.iexit_price=o.appnl 等(可用 o.rp)。

ALGO_UPDATE条件订单交易更新推送

字段 含义 用途
o.X 条件单状态 TRIGGERED / FINISHED 表示已触发
o.ai 触发后普通订单 id 平仓单触发后,用 ai 作为 exit_order_id并等 ORDER_TRADE_UPDATE(ai) 拿成交价、rp

止损/止盈是「条件单」:先下 Algo 单,触发后生成一笔普通订单,推送里给 ai。我们应:
1在 ALGO_UPDATE 里用 ai 回写 exit_order_id
2在随后收到的 ORDER_TRADE_UPDATEo.i == ai)里用 ap/z/rp 回写 exit_price、pnl 等,这样平仓数据也闭环。


三、闭环流程(按事件串起来)

开仓

1. 生成 client_order_id = SYS_<ts>_<rand>
2. 写 DBINSERT 一条 status=pending, client_order_id=client_order_id, symbol/side/quantity/...
3. 下单REST 或 WS order.place带 newClientOrderId=client_order_id
   - 若下单失败UPDATE 该条为 status=canceled 或 failed保证「有记录」且状态明确
4. 之后只依赖 WS
   - 收到 ORDER_TRADE_UPDATEo.c=client_order_ido.X=FILLED非 R
   - → UPDATE 该条status=open, entry_order_id=o.i, entry_price=o.ap, quantity=o.z

这样:开仓是否成交、成交价/量、交易所 orderId 全部由 WS 一次更新完成,不依赖 REST 轮询。

平仓(市价/限价主动平)

1. 不新建 DB 记录,只「选一条当前 open 记录」准备关仓
2. 下单reduceOnly 市价/限价单(可带 newClientOrderId 便于对账)
3. 只依赖 WS
   - 收到 ORDER_TRADE_UPDATEo.R=trueo.X=FILLEDo.s=symbol
   - → 按 symbol(+ 可选 orderId/clientOrderId) 匹配那条 open
   - → UPDATEstatus=closed, exit_order_id=o.i, exit_price=o.ap, pnl/realized_pnl 等(可用 o.rp

平仓(条件单触发:止损/止盈)

1. 不新建 DB 记录,只为当前 open 挂 Algo 单STOP_MARKET/TAKE_PROFIT_MARKET 等)
2. 触发后只依赖 WS
   - 先收到 ALGO_UPDATEo.X=TRIGGERED/FINISHEDo.ai=触发后订单 id
     → UPDATE 该 openexit_order_id=o.ai先占位
   - 再收到 ORDER_TRADE_UPDATEo.i=o.aio.X=FILLEDo.R=true
     → 同一条记录exit_price=o.appnl/realized_pnl 用 o.rp必要时补 duration/exit_time

这样:条件单触发的平仓也完全由 WS 闭环,不依赖 REST 或定时同步做主数据。


四、和当前实现的对应关系

目标步骤 当前实现 说明
本地先生成 client_order_id 已有 position_manager 里 SYS_ts_rand,并传 newClientOrderId
先写 DB 再下单 已有 Trade.create(..., status='pending', client_order_id=...),再下单
下单失败把记录标失败 ⚠️ 部分 有失败路径,但不一定统一 UPDATE 为 canceled/failed
开仓成交只靠 WS 更新 已有 User Data Stream 里 ORDER_TRADE_UPDATE FILLED + 非 R → update_pending_to_filled(client_order_id, ..., order_id, ap, z)
平仓成交只靠 WS 更新 exit_order_id 已有 ORDER_TRADE_UPDATE FILLED + R → set_exit_order_id_for_open_trade(symbol, account_id, order_id)
平仓成交用 WS 更新 exit_price / pnl 缺口 目前只写了 exit_order_id没有在 WS 里用 ap/rpupdate_exit(..., exit_price, pnl, ...),条件单触发的平仓尤其缺
条件单触发用 ai 写 exit_order_id 已有 ALGO_UPDATE 里 set_exit_order_id_for_open_trade(symbol, account_id, ai)
「DB + 下单」原子性 ⚠️ 语义上的 DB 与交易所是两套系统,无法真 2PC只能「先写 DB 再下单,失败则把该条标为失败」

所以:主流程已经接近「支付式」,真正缺的闭环是:WS 收到平仓成交(含条件单触发的 ai 那笔)时,不仅要写 exit_order_id还要用推送里的 ap/rp 等把 exit_price、pnl、exit_time 等一次更新掉


五、建议补的一步(闭环平仓数据)

User Data Stream 里,当 ORDER_TRADE_UPDATEo.R == trueo.X == FILLED 时,除现有 set_exit_order_id_for_open_trade(symbol, account_id, order_id) 外,建议:

  • 用同一推送里的 o.apo.zo.rp(及可选 o.N/o.n 手续费)和当前时间(或 o.T 成交时间),对同一条 open 记录再调一次 update_exit(或等价的「按 exit_order_id 补全 exit_price / pnl / commission」接口
    • exit_price
    • pnl / pnl_percent或 realized_pnl
    • commission若有
    • exit_time

都从 WS 一次写库。这样:

  • 市价/限价平仓ORDER_TRADE_UPDATE 一次即可完成「exit_order_id + 价格 + 盈亏」闭环。
  • 条件单平仓ALGO_UPDATE 写 exit_order_id → 等 ORDER_TRADE_UPDATE(ai) 再按上面补全价格和盈亏,也闭环。

六、小结

  • 你的理解:先本地单号 → 写 DB + 下单(尽量一体)→ 只靠 WS 通知更新订单状态与成交数据,是正确且更清晰的设计。
  • 当前实现:开仓侧已经是「先生成 client_order_id、先写 pending、再下单、WS 完善」;平仓侧 exit_order_id 已由 WS 回写,但 exit_price / pnl 等还未在 WS 路径里统一写库,算一个遗漏。
  • 补上这一块WS 平仓成交时顺带 update_exit 价格与盈亏),就能在「不依赖 REST 轮询、不依赖同步接口做主数据」的前提下,做到订单记录与币安完全以 WS 为源的闭环。
  • 事务DB 与交易所无法真事务,只能「先 DB 再下单,失败则把该条记录标为失败/取消」,当前逻辑已接近,可再统一失败态标记。

文档参考:docs/bian/订单交易更新推送.txtdocs/bian/条件订单交易更新推送.txt