# 审计说明 — 开/平仓逻辑与实盘安全（2026-07-29）

## 范围

- 开仓 / 平仓 / 到期双腿 / 弃期权 / stuck `opening` 恢复
- LIVE OKX / 币安执行器与本地账本一致性
- 交易所对账（永续 + 期权）

## 结论摘要（三轮）

| 严重度 | 问题 | 处置 |
|--------|------|------|
| Critical | 到期双平期权二次入账 | **已修** |
| Critical | abandon 账本拒记 / 假 residual 双计 | **已修** |
| Critical | 币安 `orderId=` 保留 opening 实际不匹配 → 可能重复开 | **已修**：错误文案带 `orderId=` |
| Critical | `opening` 无元数据，崩溃后无法恢复 | **已修**：`stamp_opening_intent` + `recover_opening` |
| High | 对账只查永续 | **已修**：期权仓位 + flat 时任意期权残留 |
| High | pending 时永续已空仍用 DB 数量下单 | **已修**：`allow_db_fallback=False` → 直接 finalize |
| High | 期权已空仍再卖 / 未 mark | **已修**：查仓跳过再卖；有 close fill 不二次入账 |
| High | 永续开仓异常时可能已成交仍回滚期权 | **已修**：先查永续仓再决定 |
| High | `_wait_fill` 部分成交当全成 | **已修** |
| High | residual LIVE 无 `allow_negative` | **已修** |
| Med | 币安缺保证金模式 | **已修**：落库 + `set_margin_type` |

## 开仓状态机（自检）

1. `claim_open_slot` → `opening`
2. `stamp_opening_intent`（写入 group_id / option_inst_id / 数量）
3. 下期权 → 再 stamp 成交均价
4. 下永续；失败则查永续仓：有仓保留 opening；无仓则回滚期权，回滚失败 → `half_open`
5. 成功 → `open`；启动/tick/`close_group` 遇 `opening` → `recover_opening`

## 平仓状态机（自检）

1. 卖期权（或到期本地结算）→ `_mark_option_closed_perp_pending`（只一次）
2. 平永续；交易所已空则不下单，直接 finalize
3. abandon：若已 pending，只续平永续，不记 residual
4. finalize 在 pending 时 `skip_option_cash`

## 仍需人工场景（极少）

- `opening` 无 `option_inst_id` 且交易所有不明期权仓：禁止自动清槽，企微告警
- 提升为 `open` 时永续入场价用指数近似（本地镜像；实盘盈亏仍可走交易所对账）

## 涉及文件

- `backend/app/live/reconcile.py`（核心恢复/对账）
- `executor.py` / `binance_executor.py` / `okx_trade.py` / `binance_trade.py`
- `strategy/engine.py` / `sim/matcher.py`
