auto_trade_sys/docs/订单入库演变说明.md
薇薇安 7139b5de76 feat(trades, database): 增强订单同步与记录完善逻辑
在 `trades.py` 中更新 `sync_trades_from_binance` 方法,确保使用当前账号的 API 密钥进行订单同步,并优化了日志记录以反映同步状态。新增自动全量同步逻辑,处理无记录情况下的补全需求。更新 `database/models.py` 中的 `update_pending_by_entry_order_id` 方法,提供兜底机制以完善 pending 记录,确保在缺失 clientOrderId 时仍能更新交易状态。此改动提升了交易记录的完整性与系统的稳定性。
2026-02-18 22:11:06 +08:00

72 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 订单记录入库方式演变说明(为何 12 号下午之前能对上、后来对不上)
## 时间线(按 Git 提交)
- **2月12日及之前**:订单能对上一些。
- **2月12日下午**:提交 `0df841c` 只改了止盈比例和配置/前端,**未改入库逻辑**。
- **2月14日**`3d9f58f`(使用自定义订单号)、`11cd55f`client_order_id 支持)—— 下单带 `newClientOrderId`,补建逻辑收紧。
- **2月16日**`5154b49` 引入 **pending 预落库** + UDS 按 `client_order_id` 完善。
- **2月17日**`415589e` 等增强 UDS/同步UDS 开仓 FILLED 时**无 clientOrderId 直接 return**,不完善。
## 12 号下午之前的入库方式(能对上的原因)
1. **没有 pending 预落库**
开仓流程是REST 下单 → 轮询等待成交 → 成交后**直接** `Trade.create(entry_order_id=order.get("orderId"), client_order_id=order.get("clientOrderId"), ...)`
2. **完全依赖 REST 返回**
- `entry_order_id` 来自 REST 的 `orderId`,一定能拿到。
- `client_order_id` 来自 REST 的 `clientOrderId`,当时未传 `newClientOrderId`,可能是币安自动生成或空。
3. **User Data Stream 不参与开仓落库**
当时 UDS 主要做平仓回写;开仓是否落库只取决于 **position_manager 里 REST 成交后那一次 `Trade.create`**,链路简单,所以容易和币安对上。
## 后来的改动(导致对不上的可能原因)
1. **2月14日 3d9f58f**
- 下单时带 `newClientOrderId``SYSTEM_ORDER_ID_PREFIX` + 时间戳)。
- 补建缺失持仓逻辑收紧只补建「clientOrderId 带系统前缀」或「有止损/止盈单」的仓位;手动单、无前缀单不再自动建记录。
2. **2月16日 5154b49**
- **先落 pending**:开仓前 `Trade.create(status="pending", client_order_id=..., entry_order_id=None)`
- 下单时把 `client_order_id` 传给币安(`new_client_order_id`)。
- 成交后:优先用 **UDS 推送的 clientOrderId** 找到 pending`update_pending_to_filled``entry_order_id`/价格/数量;若 UDS 未收到或推送里**没有 clientOrderId**则跳过完善pending 会一直缺 `entry_order_id`
- REST 端成交后也有「有 pending 则完善、否则新建」的兜底,但若 REST 超时/异常,就只剩「未完善的 pending」或没记录。
3. **2月17日 415589e**
- UDS 开仓 FILLED**若没有 clientOrderId直接 return**,不尝试用 orderId 做任何回填。
综合效果:
- 一旦 **UDS 断连、丢包或推送里缺少 clientOrderId**pending 无法被 UDS 完善。
-**REST 端也失败**(超时、异常、进程重启等),就会出现「币安有成交、系统只有 pending 或无记录」的情况,对不上。
## 已做的改进(本次)
1. **同步接口按当前账号 API 拉取**
使用 `Account.get_credentials(account_id)`,不再用全局 config多账号/多配置时订单能对到正确账号。
2. **DB 无记录时自动全量**
若该账号在 DB 中没有任何交易记录,同步时会自动按「全量交易对」从币安拉订单并创建/补全记录。
3. **UDS 无 clientOrderId 时用 orderId 兜底**
- 新增 `Trade.update_pending_by_entry_order_id(symbol, account_id, order_id, entry_price, quantity)`
- 若 DB 中已有该 `entry_order_id` 则跳过;
- 否则在该 symbol+account 下找「status=pending 且 entry_order_id 为空」的记录,**若恰好 1 条**则用本订单号/价格/数量更新。
-`user_data_stream` 中:开仓 FILLED 时若**没有 client_order_id**,不再直接 return而是先尝试上述兜底只有兜底也匹配不到唯一 pending 时才仅打 debug 日志。
这样即使 UDS 未带 clientOrderId或 listenKey 断连导致漏推),只要该 symbol 下只有一条待完善的 pending仍能用 orderId 补上,减少「币安有、系统没有」的情况。
## 建议自检
1. **配置**
- 当前账号是否已配置 BINANCE_API_KEY / BINANCE_API_SECRET同步用的是当前选中账号的 API
- 若使用「系统单」前缀:`SYSTEM_ORDER_ID_PREFIX` 是否与下单时一致(影响补建和区分系统单)。
2. **对账**
- 在前端选好账号后,用「同步订单」勾选「全量同步」、选 7 天或 30 天,先补全历史。
- 再用「校验与币安一致性」接口查看是否还有缺失/不一致。
3. **日志**
- 若仍有漏记,可查:
- UDS开仓 FILLED 是否带 `c`clientOrderId、是否有「已用 orderId 兜底完善」。
- 同步/补建:是否有「创建新交易记录」或「补全 entry_order_id」的日志。