auto_trade_sys/docs/订单与统计一致性说明.md

3.7 KiB
Raw Blame History

持仓、订单记录、统计与币安一致性说明

在引入「订单号前后一致」处理(entry_order_id / exit_order_id / SYSTEM_ORDER_ID_PREFIX)后,以下内容的状态如下。


一、已能保证的部分

1. 持仓与币安一致

  • 仪表板「当前持仓」:数据来自 币安实时持仓get_open_positions()),与币安页面一致(仅受 POSITION_MIN_NOTIONAL_USDT 过滤影响)。
  • 补建逻辑:只有「开仓订单 clientOrderId 以配置前缀开头」的持仓会补建 DB 记录,避免把手动单算进系统。

2. 订单记录与币安可对账

  • 开仓:系统下单时写入 newClientOrderId = 前缀_时间戳_随机,并保存 entry_order_id 到 DB。
  • 平仓:平仓时保存 exit_order_idTrade.update_exit 会做 get_by_exit_order_id 防重复。
  • 同步
    • POST /api/account/positions/sync:只对「开仓订单 clientOrderId 前缀匹配」的持仓补建,且从成交里取 orderId 作为 entry_order_id
    • POST /api/trades/sync-binance:用 get_by_exit_order_id(order_id) 判断是否已同步,避免重复;开仓侧用 get_by_entry_order_id(order_id) 判断是否已存在。
  • 因此:每条 DB 记录都可与币安订单一一对应(通过 entry_order_id / exit_order_id),订单记录与币安在「谁开的、谁平的」上一致。

3. 统计口径与去重

  • 统计:来自 Trade.get_all(..., account_id),只统计该账号的 DB 记录。
  • 净盈亏get_net_pnl(t) 逻辑为:
    • 若有 realized_pnl:用 realized_pnl,再若 commission_asset == 'USDT' 则减去 commission
    • 否则用 pnl(按价格差算)。
  • 胜率、总盈亏、盈亏比等均基于上述净盈亏汇总,不会因为重复同步同一条平仓而重复计入(由 exit_order_id 唯一性保证)。

二、仍依赖「谁在写」的部分

1. 手续费commission

场景 是否写入 commission 说明
交易系统内平仓 get_recent_tradesexit_order_id 汇总 commission写入 update_exit
仪表板「平仓」按钮 同上,取成交里的 commission/realizedPnl 写入。
持仓同步positions/sync 是(已补全) 更新 closed 前按 exit_order_id 拉取 get_recent_trades,汇总 commission/realizedPnl 并写入。
订单同步trades/sync-binance 是(已补全) 更新平仓记录前按订单号拉取成交,写入 commission/realized_pnl。

因此:所有标记为已平仓的记录都会尽量带上手续费与实际盈亏,统计与币安一致。

2. 实际盈亏realized_pnl

  • 交易系统平仓、仪表板平仓:从币安成交取 realizedPnl 并写入。
  • 持仓同步、订单同步:已补全逻辑,同样按 exit_order_id 拉取成交并写入 realized_pnl
  • 统计中若存在 realized_pnl 会优先使用并再扣 USDT 手续费,否则用价格差 pnl

三、小结:能否「直接保证」?

  • 持仓与币安一致:可以,当前实现已保证(实时持仓 + 按前缀补建)。
  • 订单记录与币安可对账:可以,entry_order_id / exit_order_id 与防重复逻辑已保证一一对应、不重复。
  • 统计准确性:在「同一笔平仓只被记录一次」和「按净盈亏汇总」上已保证;手续费与实际盈亏已在所有关仓路径补全:
    • 系统/仪表板平仓、持仓同步、订单同步 均会按 exit_order_id 拉取成交并写入 commission/realized_pnl统计与币安对齐。