# 订单记录入库方式演变说明（为何 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」的日志。
