dd979d9dd0
Co-authored-by: Cursor <cursoragent@cursor.com>
290 lines
12 KiB
Markdown
290 lines
12 KiB
Markdown
# 规格:期权盈亏双口径结算(一次一仓)
|
||
|
||
> 状态:已定稿(2026-10-13 修订)
|
||
> 适用范围:币本位期权(模拟盘优先;实盘同规则)
|
||
> 目标:复盘可对账、数据统计跟期权历史一致;初始权利金 / 盈利率可展示;错账可脚本修复
|
||
|
||
---
|
||
|
||
## 1. 目标与原则
|
||
|
||
### 1.1 要解决什么
|
||
|
||
此前单笔盈亏混用多套口径,且卖回按开仓权利金封顶,导致:
|
||
|
||
- 盈利单(如约 1.5 倍)在复盘被冻成亏损(账户差分在盈利币未卖回时结算)
|
||
- 复盘与数据统计共用账户冻结,与「历史币盈亏 × 卖回价」不一致
|
||
- 缺少初始权利金(U)、盈利率展示
|
||
|
||
### 1.2 原则
|
||
|
||
| 原则 | 说明 |
|
||
|------|------|
|
||
| 双口径 | **A 复盘** = 交易账户 USDT 快照差分;**B 数据统计** = 期权历史币盈亏 × 平仓卖回价 |
|
||
| 一次一仓 | 同一账户同一时间只允许一笔期权持仓 |
|
||
| 卖光再结算 | A 口径:未卖光可卖标的币前,本单不冻结 |
|
||
| 冻结 | A 结算完成后永不修改;B 按平仓卖回价冻结后不跟盘 |
|
||
| 禁划转 | 持仓 / 待卖回期间禁止资金划转 |
|
||
| 权利金不含多买 | 初始权利金 = 开仓指数 × 权利金币量(不含现货缓冲多买) |
|
||
|
||
---
|
||
|
||
## 2. 双口径定义
|
||
|
||
### 2.1 口径 A — 真盈亏(复盘交易记录)
|
||
|
||
```
|
||
真盈亏(U) = 期权历史盈亏(币) × 平仓卖回价
|
||
− (权利金 × 开仓价 − 权利金 × 平仓卖回价)
|
||
```
|
||
|
||
- **币量**只用期权腿:`realized_pnl`(历史币盈亏,**已含**开/平手续费)、`premium_paid`(权利金);**不含**现货多买/多卖数量
|
||
- **价格**只用开仓买币 VWAP、平仓卖回 VWAP;现货多余仓位只参与均价,**数量不进公式**
|
||
- 真盈亏**不再另扣**手续费(费已在历史币盈亏里);复盘「期权手续费」列仅展示
|
||
- 无手续费时:`期权收回权利金×卖回价 − 权利金×开仓价`(收回=`premium_received`,不是账户全部现货)
|
||
|
||
**固定量 vs 一次冻结价:**
|
||
|
||
| 字段 | 性质 |
|
||
|------|------|
|
||
| `premium_paid`(权利金币) | 开仓后**固定**,不再改 |
|
||
| `realized_pnl`(期权腿币盈亏) | 平仓后**固定**,不再改 |
|
||
| 开仓价 | 买币完成时算一次 VWAP 写入 `open_index_px`,**冻住** |
|
||
| 卖回价 | 平仓卖回全部完成时算一次 VWAP 写入 `close_index_px`,**冻住** |
|
||
| `realized_pnl_usdt` | 按上式计算;**刷新时用固定量+价重算**(可纠正旧错账) |
|
||
|
||
- 卖回未完成 → 「待卖回」,不算真盈亏
|
||
- 缺价 → 「缺价未核」
|
||
- 复盘刷新:**不得**改权利金币量/币盈亏/已冻开仓价/卖回价;**要**按公式重算真盈亏 U
|
||
|
||
- **消费者**:期权复盘「期权交易记录」盈亏列、复盘 KPI、`realized_pnl_usdt` 冻结
|
||
- **不含**:现货多买差分当盈亏 / 账户 after−before
|
||
- 账户 `trading_usdt_before/after` 仅审计用,**不**作复盘真盈亏
|
||
|
||
### 2.2 口径 B — 期权历史 / 数据统计(仅期权腿)
|
||
|
||
```
|
||
期权腿盈亏(币) = 收回权利金 − 已付权利金 − 期权开/平手续费
|
||
统计用 U ≈ 期权腿盈亏(币) × 平仓卖回价
|
||
```
|
||
|
||
- **消费者**:期权面板「期权历史」(币)、数据统计 / 顶栏窗口统计(折 U)
|
||
- **不含**现货;**不**做「开仓价 vs 卖回价」权利金 USDT 波动修正(那是口径 A)
|
||
- 与复盘真盈亏 A **独立**:`A = B − 权利金×(开仓价−卖回价)`
|
||
|
||
### 2.3 初始权利金、盈利率、期权手续费
|
||
|
||
| 字段 | 定义 |
|
||
|------|------|
|
||
| 初始权利金(U) | `open_index_px × premium_paid`(不含 `budget_usdt` 多买) |
|
||
| 盈利率(复盘) | `真盈亏A / initial_premium_usdt` |
|
||
| 期权手续费(U) | 仅期权开/平:`open_fee×开仓指数 + close_fee×卖回价`(不含现货) |
|
||
|
||
复盘「期权交易记录」须展示:初始权利金(U)、真盈亏(A)、盈利率、期权手续费(U)。
|
||
|
||
---
|
||
|
||
## 3. 产品规则
|
||
|
||
### 3.1 开仓前
|
||
|
||
1. 有可卖标的币(ETH/BTC)→ 拒开仓(粉尘低于现货最小可卖可忽略)。
|
||
2. 拍交易账户 USDT → `trading_usdt_before`。
|
||
3. 开仓前若有多次划转:以**开仓前最后一次划转完成后**的余额为准(即开仓瞬间余额)。
|
||
4. 开仓失败:回滚卖币,并拍**最新**资金快照(不留下脏 before / 半成品桥阻挡后续)。
|
||
5. 写入 `initial_premium_usdt = open_index_px × premium_paid`(开仓成功后)。
|
||
|
||
### 3.2 持仓中
|
||
|
||
1. 划转按钮灰 + API 拒绝。
|
||
2. 面板合计盈亏(动态)= `Σ口径B已冻结` + `当前持仓浮盈`。
|
||
3. 本单未完成 A 结算前:复盘显示「待结算」,不写假 U。
|
||
|
||
### 3.3 平仓与卖回
|
||
|
||
1. 系统可多次部分平仓;**以最后一次全部平仓完成**为准进入卖回。
|
||
2. 期权空仓后:**卖光**交易账户该标的可卖币(**禁止**用开仓权利金 `coin_bought` 封顶)。
|
||
3. `coin_bought` 仅用于开仓阶段清理过量买币,不作平仓卖回上限。
|
||
4. 卖回未完成(仍有可卖币):桥保持待卖回,**不**进入 A 结算。
|
||
5. 真粉尘(低于现货最小):可关桥并进入 A 结算(差额含粉尘损失)。
|
||
|
||
### 3.4 结算与冻结(A)
|
||
|
||
1. `realized_pnl_usdt = after − before`,`pnl_settled=1`。
|
||
2. 此后不得因划转、指数、复盘同步、监控公式而修改。
|
||
3. 仅复盘读此冻结值。
|
||
|
||
### 3.5 划转
|
||
|
||
| 时机 | 行为 |
|
||
|------|------|
|
||
| 无持仓、无待卖回 | 允许划转 |
|
||
| 持仓中或待卖回 | 禁止划转 |
|
||
| 划转后 | 只影响下一笔开仓前的 `usdt_before`;不重算已冻结 A/B |
|
||
|
||
---
|
||
|
||
## 4. 状态机
|
||
|
||
```text
|
||
IDLE
|
||
│ 有可卖币? ──是──> 拒开仓
|
||
│ 快照 trading_usdt_before(划转取最后一次后余额)
|
||
▼
|
||
OPENING ──失败──> 回滚卖币 → 最新资金快照 → IDLE
|
||
│ 成功(一次一仓);写 initial_premium_usdt
|
||
▼
|
||
OPEN(禁划转)
|
||
│ 可多次部分平仓
|
||
▼
|
||
CLOSING(交易所仓位未清零则停留)
|
||
│ 仓位 = 0
|
||
▼
|
||
SELLING_SPOT(卖光可卖标的币;禁止权利金封顶)
|
||
│ 可卖币 < minSz(真粉尘)或已空
|
||
▼
|
||
SETTLE_A(after − before → 冻结;仅此态可写 pnl_settled=1)
|
||
▼
|
||
IDLE
|
||
```
|
||
|
||
**硬门禁**
|
||
|
||
| 条件 | 行为 |
|
||
|------|------|
|
||
| OPEN / CLOSING / SELLING_SPOT | 禁止划转 |
|
||
| 未进 SETTLE_A | 复盘 U 为待结算 |
|
||
| pnl_settled=1 | 禁止覆盖 A |
|
||
| SETTLE_A | 要求 open_positions=0 且无可卖标的币 |
|
||
|
||
实现上可为显式状态字段,或由 `options_trades.status` + 桥状态 + `pnl_settled` 等价表达,但**结算入口必须统一校验门禁**。
|
||
|
||
---
|
||
|
||
## 5. 数据字段
|
||
|
||
### 5.1 `options_trades`
|
||
|
||
| 字段 | 含义 |
|
||
|------|------|
|
||
| `trading_usdt_before` | 开仓前交易账户 USDT |
|
||
| `trading_usdt_after` | 卖光后交易账户 USDT |
|
||
| `realized_pnl_usdt` | **口径 A** 冻结值 |
|
||
| `pnl_settled` | 0/1,A 是否已冻结 |
|
||
| `realized_pnl` | 币数量净盈亏(期权历史展示) |
|
||
| `close_index_px` | 平仓/卖回价(口径 B 用) |
|
||
| `open_index_px` | 开仓指数 |
|
||
| `premium_paid` | 开仓权利金币量 |
|
||
| `initial_premium_usdt` | 初始权利金 U = open_index × premium_paid |
|
||
| `budget_usdt` | 买币花费(含缓冲),**不得**当权利金或 before |
|
||
|
||
### 5.2 `options_review_trades`
|
||
|
||
| 字段 | 含义 |
|
||
|------|------|
|
||
| `realized_pnl_total` | **仅口径 A**(或待结算空) |
|
||
| `initial_premium_usdt` | 初始权利金 U |
|
||
| `profit_rate` | A / 初始权利金(小数,如 1.5 = 1.5 倍) |
|
||
|
||
### 5.3 `options_exchange_pnl_freeze`
|
||
|
||
实盘统计辅助:历史 key → 口径 B 的 U 冻结。
|
||
|
||
---
|
||
|
||
## 6. 模块行为
|
||
|
||
### 6.1 开仓 `open_coin_option_buy_full`
|
||
|
||
1. 一次一仓 / 未完成桥检查;可卖币拒开。
|
||
2. `trading_usdt_before`;买币、下单、写库(`pnl_settled=0`,`initial_premium_usdt`)。
|
||
3. 桥 `coin_bought` 可记为权利金币量(供开仓清过量),**平仓卖回不得用其封顶**。
|
||
|
||
### 6.2 划转 `POST /api/options/transfer`
|
||
|
||
持仓或桥 ∈ {bought, holding, pending_sell} → 拒绝。
|
||
|
||
### 6.3 卖回与 A 结算
|
||
|
||
`sell_residual_after_option_flat`(及 retry / sweep):
|
||
|
||
1. 空仓后卖光可用标的币(`coin_amount=None`)。
|
||
2. 仍有可卖 → 桥 `pending_sell`,返回未完成,**不结算**。
|
||
3. 仅粉尘/已空 → 关桥 → `try_settle_after_sellback`(内再校验无可卖币)→ A 冻结。
|
||
|
||
### 6.4 数据统计(口径 B)
|
||
|
||
- `net_realized_pnl` / 胜率 / 盈亏比:历史币盈亏 × 卖回价。
|
||
- **不读** `pnl_settled` 账户差分。
|
||
- 数据统计页不得再打复盘 stats API 作为盈亏真源。
|
||
|
||
### 6.5 期权复盘(口径 A)
|
||
|
||
- 同步本地已平:优先 `pnl_settled=1` 的 `realized_pnl_usdt`。
|
||
- 未结算:显示待结算,不导入假 U。
|
||
- 同步 `initial_premium_usdt`、`profit_rate`。
|
||
|
||
### 6.6 期权历史列表
|
||
|
||
仍按**币**展示权利金/币盈亏;U 只用于复盘(A)与数据统计(B)。
|
||
|
||
---
|
||
|
||
## 7. 对账关系
|
||
|
||
```
|
||
口径 A: Σ 已冻结单笔 A + 期间净划转 ≈ 交易账户相对首笔 before 的累计变化
|
||
口径 B: Σ (历史币盈亏 × 卖回价) ≈ 面板数据统计已实现
|
||
```
|
||
|
||
差异应可归因:粉尘、滑点、手续费(A 内已含);B 不含多买缓冲。
|
||
|
||
---
|
||
|
||
## 8. 非目标 / 不做
|
||
|
||
- 不用 `budget_usdt` 当单笔盈利或初始权利金。
|
||
- 不用口径 A 覆盖数据统计,也不用口径 B 覆盖复盘。
|
||
- 持仓中不因行情重算已冻结 A/B。
|
||
- 不把期权历史列表强制改为 U。
|
||
|
||
---
|
||
|
||
## 9. 历史数据修复
|
||
|
||
对已错误冻结的账户差分(典型:币盈亏>0 且 A 为负,且 `coin_sold≈premium_paid≪premium_received`):
|
||
|
||
1. 回填 `initial_premium_usdt = open_index_px × premium_paid`。
|
||
2. 口径 B:按币盈亏 × 卖回价重算统计侧(含 `options_exchange_pnl_freeze`)。
|
||
3. 口径 A:卖回完整可重建则重算;否则 `pnl_settled=0` 标 `needs_resettle` / 异常,勿盲信错账。
|
||
4. 重刷 `options_review_trades.realized_pnl_total` / `profit_rate`。
|
||
|
||
脚本:`scripts/repair_options_dual_pnl.py`(dry-run → CSV → apply)。
|
||
|
||
---
|
||
|
||
## 10. 验收清单
|
||
|
||
- [ ] 盈利约 1.5 倍单:卖回含盈利币;复盘 A 为正,约等于账户差分
|
||
- [ ] 卖回不得按开仓权利金封顶
|
||
- [ ] 仍有可卖币时不 `pnl_settled=1`
|
||
- [ ] 复盘展示初始权利金、盈利率
|
||
- [ ] 数据统计 = 历史币盈亏 × 卖回价,与复盘 A 可不同
|
||
- [ ] 开仓写入 before + initial_premium;失败有最新快照/回滚
|
||
- [ ] 持仓禁划转;空仓划转不影响已冻结
|
||
- [ ] 历史错账可用脚本修复
|
||
|
||
---
|
||
|
||
## 11. 修订记录
|
||
|
||
| 日期 | 说明 |
|
||
|------|------|
|
||
| 2026-10-09 | 初版:交易账户快照差分 + 一次一仓 + 持仓禁划转 + 卖回后冻结 |
|
||
| 2026-10-13 | 修订:双口径 A/B;卖光再结算;初始权利金/盈利率;状态机;历史修复脚本 |
|
||
| 2026-10-13 | 复盘「期权交易记录」盈亏与数据统计同口径 B;增加仅期权手续费展示 |
|
||
| 2026-10-13 | 交易记录改回真盈亏 A;期权历史/统计仅期权腿 B,不含现货 |
|
||
| 2026-10-13 | 真盈亏明确为卖光收回−买币;复盘禁止指数折 U 冒充;桥可回退 |
|
||
| 2026-10-13 | 真盈亏改回权利金 USDT 波动式:币盈亏×卖回价−权利金×(开−平);忽略多买 |
|
||
| 2026-10-13 | 多笔买/卖回用 VWAP;卖完再结算;待卖回/缺价未核标记 |
|