# 实盘下单 · 盘口深度预览 — 开发方案

> 状态:**方案待实现**(按本文落地;改需求先改本文).  
> 范围:**三所实例**实盘下单监控(Binance / OKX / Gate);中控嵌入同一表单时一并带上.  
> 相关:[manual-order-rr-preview.md](./manual-order-rr-preview.md) · [position-sizing-mode.md](./position-sizing-mode.md) · 期权侧已有「卖一开 / 买一平」深度硬约束(本方案**不照搬硬挡**,首版以预览为主).

---

## 1. 背景与问题

实盘下单表单目前只展示 **标的现价/标记价**,再按止损与计仓模式算出预估风险 / 预估 RR.

- **资金小**:名义仓位通常远小于盘口前几档,市价成交贴近买卖一,现价参考够用.  
- **资金大**(尤其 `POSITION_SIZING_MODE=full_margin`):名义 = 可用保证金 × 缓冲 × 杠杆,容易到数十万 U. 市价单会沿对手盘穿档,入场均价偏离「现价」后,止损距离与有效盈亏比都会偏.

典型例子:

| 条件 | 含义 |
|------|------|
| 可用约 1 万 U,20 倍杠杆,全仓 | 计划名义约 **20 万 U** |
| **市价做空** | 立刻卖出 ≈ 20 万 U 名义 → 吃 **买单(bid)** |
| **市价做多** | 立刻买入 ≈ 20 万 U 名义 → 吃 **卖单(ask)** |

用户需要的不是整本订单簿娱乐墙,而是回答:

> 当前计划名义下,对手盘前几档**能不能接住**,接住后的**预估均价 / 滑点**大概多少?

---

## 2. 目标(首版)

在「实盘下单监控」开仓区增加 **计划名义 vs 对手盘深度** 的只读预览:

1. 按当前表单算出的 **计划名义(USDT)** 与 **方向**,取对应一侧盘口.  
2. 从最优档往外累加,直到累计名义 ≥ 计划名义(或盘口耗尽).  
3. 展示:吃到第几档、累计可吸收名义、预估成交均价(VWAP)、相对参考价的滑点(bps 或 %).  
4. **不拦截下单**(首版);可选标黄提示,见 §6.

与现有「预估风险 / 预估盈利 / 预估盈亏比」并列,作为下单前参考,不替代服务端风控与交易所真实成交.

---

## 3. 不做(首版外)

- 完整 20/50 档盘口图、深度图动画、WebSocket 持续推送盘口(首版 REST 轮询即可)  
- 按深度 **自动缩仓** 或 **禁止开仓**(期权硬约束那套;列为二期,见 §10)  
- 限价挂单的「挂单价到盘口距离」专项(可后加;首版聚焦市价吃单路径)  
- 平仓/止损单穿档预估(开仓侧先做;平仓可二期)  
- 改开仓逻辑、改计仓公式、改交易所下单路径  
- 中控独立深度页或跨所聚合盘口

---

## 4. 产品规则

### 4.1 对手盘方向

| 用户方向 | 市价开仓动作 | 累加侧 |
|----------|--------------|--------|
| 做多(long) | 买入 | **卖盘 asks**(卖一 → 卖 N) |
| 做空(short) | 卖出 | **买盘 bids**(买一 → 买 N) |

### 4.2 计划名义从哪来

与现有开仓计仓一致,优先复用服务端已有 sizing 口径(避免前后端各算一套):

| 计仓模式 | 计划名义 |
|----------|----------|
| `full_margin` | `notional_value` ≈ 可用 × 缓冲 × 杠杆(与 `compute_full_margin_sizing` 一致) |
| `risk`(以损定仓) | 由风险金额与止损距离反推的仓位名义(与现开仓 `add_order` 路径一致) |

表单未填齐止损/方向/币种、或无法取可用保证金时:深度预览显示「—」,不报错打断填写.

### 4.3 参考价与滑点

- **参考价**:优先与表单现价条同一口径(标记价/最新价,跟现有 `symbol_live_price` / `order_defaults` 一致).  
- **预估均价(VWAP)**:按所吃各档 `价格 × 该档名义` 加权.  
- **滑点**:
  - 做多: `(vwap - ref) / ref`(越正越差)
  - 做空: `(ref - vwap) / ref`(越正越差)
- 展示可用 **bps**(1 bps = 0.01%)或 `%`,UI 统一一种即可(建议 bps,大单更直观).

### 4.4 盘口档数

- 请求深度建议 **5～20 档**(实现时三所取各自 API 稳妥上限,默认 20).  
- 累加只展示「覆盖计划名义所需」的档位摘要,不必把未吃到的远档全部渲染.  
- 若累加后仍 `< 计划名义`:明确写 **深度不足 / 缺口约 X U**,不要伪装成已完全覆盖.

### 4.5 文案示例(空单 20 万 U)

```
对手盘(买):买一～买4 累计约 23.1 万 U · 预估均价 63480(相对现价约 5 bps)
```

深度不足时:

```
对手盘(买):前 20 档累计约 12.4 万 U · 缺口约 7.6 万 U · 预估均价按已有档估算(仅供参考)
```

---

## 5. 界面位置

放在实盘下单开仓区、现有预览条附近,避免抢主按钮视觉:

| 区域 | 建议 |
|------|------|
| 现价条旁或下方 | 一行摘要即可(§4.5) |
| `#order-plan-preview` | 可增一项「盘口深度」或独立 `#order-depth-preview` |
| 详细档位 | 首版可不展开;若展开,仅列出已累加到的那几档(价/量/累计名义) |

小资金且滑点低于阈值时,可用灰色弱提示「前 N 档已覆盖,滑点可忽略」,避免噪音.

---

## 6. 提示阈值(软提示,不挡单)

建议可配置(`.env`,有默认值),仅影响颜色/文案:

| 变量(草案) | 含义 | 默认建议 |
|------------|------|----------|
| `MANUAL_DEPTH_WARN_BPS` | 预估滑点 ≥ 此值标黄 | `5` |
| `MANUAL_DEPTH_ALERT_BPS` | 预估滑点 ≥ 此值标红/强调 | `15` |
| `MANUAL_DEPTH_SHORTFALL_WARN` | 累计名义 < 计划名义时强调 | 开 |

首版:**不**因此 `disabled` 开仓按钮;与期权「无卖一禁止开仓」区分开.

---

## 7. 技术设计

### 7.1 API(三所各暴露,或抽到 `lib/` 共用 handler)

建议新增(名称可微调):

`GET /api/order_depth_preview`

| 参数 | 说明 |
|------|------|
| `symbol` | 与开仓表单一致 |
| `direction` | `long` / `short` |
| `sl` / `sl_pct` / `fixed_rr` / `sltp_mode` 等 | 以损定仓算名义时需要;全仓模式可只传 symbol+direction |
| 或直接传 `notional_usdt` | 若前端已从其它 preview API 拿到名义,可减少重复计算(**二选一,实现时定一种主路径**) |

响应草案:

```json
{
  "ok": true,
  "side": "bid",
  "ref_px": 63512.3,
  "plan_notional_usdt": 200000,
  "covered_notional_usdt": 231000,
  "shortfall_usdt": 0,
  "levels_used": 4,
  "vwap": 63480.0,
  "slippage_bps": 5.1,
  "levels": [
    {"px": 63510, "sz": "...", "notional_usdt": 50000, "cum_notional_usdt": 50000}
  ],
  "msg": ""
}
```

失败(拉盘口失败、币种无效):`ok=false` + 简短 `msg`;前端显示「深度暂不可用」,不影响开仓。

### 7.2 交易所盘口

| 所 | 合约盘口 | 注意 |
|----|----------|------|
| Binance | USD-M 深度 | 数量单位换算成 USDT 名义 |
| OKX | swap books | 同左;与期权 `fetch_option_book_depth` **分开**,勿混用期权接口 |
| Gate | futures order book | 同左 |

公共逻辑建议落在 `lib/trade/`(例如 `manual_order_depth_preview_lib.py`):输入档位列表 + 计划名义 + 方向 → 输出 VWAP / 缺口 / levels_used.  
各所只负责 **拉 book + 单位换算成 USDT 名义**.

### 7.3 前端

- 共享脚本(建议):`lib/common/static/manual_order_depth_preview.js`  
- 与 `manual_order_rr_preview.js` 同样在币种/方向/止损/模式变更时 debounce 刷新  
- 轮询间隔建议 3～5s(仅表单可见且字段有效时);切页或无焦点可停  
- 三所 `index` / 嵌入 fragment 引入同一脚本

### 7.4 测试

- 纯函数:给定假盘口 + 名义,断言 `levels_used` / `vwap` / `shortfall`  
- 方向: long 只吃 ask, short 只吃 bid  
- 深度不足与刚好覆盖边界  
- 不要求联调真盘口也能合入(真盘口可手工验一次 BTC/山寨对比)

---

## 8. 验收标准

1. 全仓 + 已知杠杆下,预览「计划名义」与开仓实际计仓名义同量级(允许四舍五入误差).  
2. 市价空只反映买盘累加;市价多只反映卖盘累加.  
3. BTC 厚盘:小名义常显示「前 1～2 档已覆盖、滑点很低」.  
4. 人为放大名义或选薄流动性标的:能看到多档累加或「深度不足」.  
5. 拉盘口失败时不阻断开仓按钮.  
6. 中控嵌入实盘下单同样可见(与实例页同源表单).

---

## 9. 实现顺序建议

1. `lib/trade` 累加/VWAP 纯函数 + 单测  
2. 一所(建议 OKX 或当前主力所)拉 book + API + 前端一行预览  
3. 抽换算差异,补 Binance / Gate  
4. 接入软提示阈值与文案打磨  
5. 文档验收记录补进本文或 `docs/更新文档.md`

---

## 10. 二期(明确不做进首版)

| 项 | 说明 |
|----|------|
| 深度不够自动缩名义 | 类似期权 `cap_by_ask_depth` |
| 滑点超阈值二次确认 / 禁止市价 | 产品确认后再做硬门禁 |
| 平仓与止损穿档预估 | 持仓卡或平仓按钮旁 |
| WS 盘口 | 降低 REST 压力、更即时 |
| 限价开仓:挂单价相对盘口位置 | 另一套提示 |

---

## 11. 决策摘要(已拍板)

- **要做**:按计划名义展示「覆盖该名义所需」的对手盘摘要 + 预估均价/滑点.  
- **做空看买单,做多看卖单**.  
- **首版只展示 + 软提示,不挡单**.  
- **不为小资金做整屏盘口墙**;大名义时深度预览才有关键决策价值.
