09989d2709
Co-authored-by: Cursor <cursoragent@cursor.com>
10 KiB
10 KiB
规格:期权盈亏双口径结算(一次一仓)
状态:已定稿(2026-10-13 修订)
适用范围:币本位期权(模拟盘优先;实盘同规则)
目标:复盘可对账、数据统计跟期权历史一致;初始权利金 / 盈利率可展示;错账可脚本修复
1. 目标与原则
1.1 要解决什么
此前单笔盈亏混用多套口径,且卖回按开仓权利金封顶,导致:
- 盈利单(如约 1.5 倍)在复盘被冻成亏损(账户差分在盈利币未卖回时结算)
- 复盘与数据统计共用账户冻结,与「历史币盈亏 × 卖回价」不一致
- 缺少初始权利金(U)、盈利率展示
1.2 原则
| 原则 | 说明 |
|---|---|
| 双口径 | A 复盘 = 交易账户 USDT 快照差分;B 数据统计 = 期权历史币盈亏 × 平仓卖回价 |
| 一次一仓 | 同一账户同一时间只允许一笔期权持仓 |
| 卖光再结算 | A 口径:未卖光可卖标的币前,本单不冻结 |
| 冻结 | A 结算完成后永不修改;B 按平仓卖回价冻结后不跟盘 |
| 禁划转 | 持仓 / 待卖回期间禁止资金划转 |
| 权利金不含多买 | 初始权利金 = 开仓指数 × 权利金币量(不含现货缓冲多买) |
2. 双口径定义
2.1 口径 A — 真盈亏(交易账户 / 复盘交易记录)
本单真盈亏(U) = trading_usdt_after − trading_usdt_before
等价理解:平仓后卖光标的币收回的 USDT,相对开仓前(买币前)交易账户的变化。
- 消费者:期权复盘「期权交易记录」盈亏列、复盘 KPI、账户冻结(
pnl_settled) - 含:多买缓冲、现货滑点、期权/现货摩擦(整笔钱进出)
- 门禁:全部期权仓位已平 且 标的币无可卖量后才拍
after并冻结 - 未结算:列表显示「待结算」,不写币×价假 U
2.2 口径 B — 期权历史 / 数据统计(仅期权腿)
期权腿盈亏(币) = 收回权利金 − 已付权利金 − 期权开/平手续费
统计用 U ≈ 期权腿盈亏(币) × 平仓卖回价
- 消费者:期权面板「期权历史」(币)、数据统计 / 顶栏窗口统计(折 U)
- 不含现货买币/卖回;不用现货贵贱改写权利金腿
- 与复盘真盈亏 A 独立,禁止混用
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 开仓前
- 有可卖标的币(ETH/BTC)→ 拒开仓(粉尘低于现货最小可卖可忽略)。
- 拍交易账户 USDT →
trading_usdt_before。 - 开仓前若有多次划转:以开仓前最后一次划转完成后的余额为准(即开仓瞬间余额)。
- 开仓失败:回滚卖币,并拍最新资金快照(不留下脏 before / 半成品桥阻挡后续)。
- 写入
initial_premium_usdt = open_index_px × premium_paid(开仓成功后)。
3.2 持仓中
- 划转按钮灰 + API 拒绝。
- 面板合计盈亏(动态)=
Σ口径B已冻结+当前持仓浮盈。 - 本单未完成 A 结算前:复盘显示「待结算」,不写假 U。
3.3 平仓与卖回
- 系统可多次部分平仓;以最后一次全部平仓完成为准进入卖回。
- 期权空仓后:卖光交易账户该标的可卖币(禁止用开仓权利金
coin_bought封顶)。 coin_bought仅用于开仓阶段清理过量买币,不作平仓卖回上限。- 卖回未完成(仍有可卖币):桥保持待卖回,不进入 A 结算。
- 真粉尘(低于现货最小):可关桥并进入 A 结算(差额含粉尘损失)。
3.4 结算与冻结(A)
realized_pnl_usdt = after − before,pnl_settled=1。- 此后不得因划转、指数、复盘同步、监控公式而修改。
- 仅复盘读此冻结值。
3.5 划转
| 时机 | 行为 |
|---|---|
| 无持仓、无待卖回 | 允许划转 |
| 持仓中或待卖回 | 禁止划转 |
| 划转后 | 只影响下一笔开仓前的 usdt_before;不重算已冻结 A/B |
4. 状态机
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
- 一次一仓 / 未完成桥检查;可卖币拒开。
trading_usdt_before;买币、下单、写库(pnl_settled=0,initial_premium_usdt)。- 桥
coin_bought可记为权利金币量(供开仓清过量),平仓卖回不得用其封顶。
6.2 划转 POST /api/options/transfer
持仓或桥 ∈ {bought, holding, pending_sell} → 拒绝。
6.3 卖回与 A 结算
sell_residual_after_option_flat(及 retry / sweep):
- 空仓后卖光可用标的币(
coin_amount=None)。 - 仍有可卖 → 桥
pending_sell,返回未完成,不结算。 - 仅粉尘/已空 → 关桥 →
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):
- 回填
initial_premium_usdt = open_index_px × premium_paid。 - 口径 B:按币盈亏 × 卖回价重算统计侧(含
options_exchange_pnl_freeze)。 - 口径 A:卖回完整可重建则重算;否则
pnl_settled=0标needs_resettle/ 异常,勿盲信错账。 - 重刷
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,不含现货 |