fix复盘真盈亏改为期权币盈亏×平仓价,不再绑卖回与初始权利金差。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-13 12:39:15 +08:00
parent 839baea375
commit fc0d76d174
11 changed files with 98 additions and 211 deletions
+13 -23
View File
@@ -1,4 +1,4 @@
"""复盘真盈亏=(权利金+币盈亏)×卖回价 − 初始权利金U."""
"""复盘真盈亏=期权历史币盈亏×平仓价."""
from __future__ import annotations
import sqlite3
@@ -7,7 +7,7 @@ import unittest
class ReviewLocalSyncFreezeTests(unittest.TestCase):
def test_refresh_recomputes_u_keeps_frozen_qty_px(self):
"""刷新按公式重算U;权利金币/币盈亏不变."""
"""刷新按币盈亏×平仓价重算U;币盈亏/平仓价不变."""
from lib.options.options_db import init_options_tables
from lib.options.options_review_lib import sync_options_from_local_trades
from lib.sim.mode_lib import MODE_SIM, TRADING_MODE_KEY
@@ -41,22 +41,21 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
trade = conn.execute(
"SELECT realized_pnl_usdt, open_index_px, close_index_px, pnl_settled, realized_pnl, premium_paid FROM options_trades WHERE id=1"
).fetchone()
# 0.01*80000 - 0.01*(90000-80000)=700;旧错账 -51 被刷新纠正
self.assertAlmostEqual(float(trade["realized_pnl_usdt"]), 700.0, places=2)
# 0.01*80000=800;旧错账 -51 被刷新纠正
self.assertAlmostEqual(float(trade["realized_pnl_usdt"]), 800.0, places=2)
self.assertAlmostEqual(float(trade["open_index_px"]), 90000.0, places=2)
self.assertAlmostEqual(float(trade["close_index_px"]), 80000.0, places=2)
self.assertEqual(int(trade["pnl_settled"]), 1)
self.assertAlmostEqual(float(trade["realized_pnl"]), 0.01, places=8)
self.assertAlmostEqual(float(trade["premium_paid"]), 0.01, places=8)
row = conn.execute(
"SELECT realized_pnl_total FROM options_review_trades WHERE history_key=?",
("local_opt:1",),
).fetchone()
self.assertAlmostEqual(float(row["realized_pnl_total"]), 700.0, places=2)
self.assertAlmostEqual(float(row["realized_pnl_total"]), 800.0, places=2)
conn.close()
def test_refresh_prefers_bridge_sell_vwap_over_wrong_index(self):
"""库内卖回价若是指数占位,刷新须用桥上卖回 VWAP;初始权利金U冻结不改."""
"""有卖回 VWAP 时优先用它折U."""
from lib.options.options_db import init_options_tables
from lib.options.options_review_lib import sync_options_from_local_trades
from lib.options.options_spot_bridge_lib import (
@@ -86,13 +85,13 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
inst_id, underlying, opt_type, sheets, eth_amount,
premium_paid, premium_received, realized_pnl, premium_ccy,
open_fee, close_fee, status, realized_pnl_usdt,
open_index_px, close_index_px, initial_premium_usdt, pnl_settled, bridge_id,
open_index_px, close_index_px, pnl_settled, bridge_id,
created_at, closed_at
) VALUES (
'BTC-USD-261015-84000-P', 'BTC', 'P', 1, 0.01,
0.01, 0.02, 0.01, 'BTC',
0, 0, 'closed', 1544.0,
88086.0, 85400.0, 840.10, 1, ?,
88086.0, 85400.0, 1, ?,
'2026-10-12 01:46:50', '2026-10-13 08:07:35'
)
""",
@@ -101,14 +100,11 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
conn.commit()
sync_options_from_local_trades(conn, None)
trade = conn.execute(
"SELECT realized_pnl_usdt, open_index_px, close_index_px, initial_premium_usdt FROM options_trades WHERE id=1"
"SELECT realized_pnl_usdt, close_index_px FROM options_trades WHERE id=1"
).fetchone()
# 已冻开仓价/初始权利金不覆盖;卖回价用桥 VWAP
self.assertAlmostEqual(float(trade["open_index_px"]), 88086.0, places=2)
self.assertAlmostEqual(float(trade["initial_premium_usdt"]), 840.10, places=2)
self.assertAlmostEqual(float(trade["close_index_px"]), 81418.0, places=2)
# (0.01+0.01)*81418 - 840.10 = 788.26
self.assertAlmostEqual(float(trade["realized_pnl_usdt"]), 788.26, places=2)
# 0.01*81418
self.assertAlmostEqual(float(trade["realized_pnl_usdt"]), 814.18, places=2)
conn.close()
def test_premium_usdt_move_formula(self):
@@ -122,9 +118,6 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
init_options_tables(conn)
ensure_runtime_settings_table(conn)
runtime_set(conn, TRADING_MODE_KEY, MODE_SIM)
# paid=0.01, recv=0.02, coin_pnl=0.01; open=90000, close=80000
# A = 0.01*80000 - (0.01*90000 - 0.01*80000) = 800 - 100 = 700
# 亦= recv*close - paid*open = 1600 - 900 = 700
conn.execute(
"""
INSERT INTO options_trades(
@@ -151,12 +144,11 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
"SELECT realized_pnl_total FROM options_review_trades WHERE history_key=?",
("local_opt:1",),
).fetchone()
self.assertAlmostEqual(float(row["realized_pnl_total"]), 700.0, places=2)
# 纠偏写回,不用账户差分 1506
self.assertAlmostEqual(float(row["realized_pnl_total"]), 800.0, places=2)
healed = conn.execute(
"SELECT realized_pnl_usdt FROM options_trades WHERE id=1"
).fetchone()
self.assertAlmostEqual(float(healed["realized_pnl_usdt"]), 700.0, places=2)
self.assertAlmostEqual(float(healed["realized_pnl_usdt"]), 800.0, places=2)
conn.close()
def test_uncomputable_old_trade_marked(self):
@@ -170,7 +162,6 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
init_options_tables(conn)
ensure_runtime_settings_table(conn)
runtime_set(conn, TRADING_MODE_KEY, MODE_SIM)
# 未冻结且无开仓/卖回价 → 缺价未核(不瞎写)
conn.execute(
"""
INSERT INTO options_trades(
@@ -233,7 +224,6 @@ class ReviewLocalSyncFreezeTests(unittest.TestCase):
"SELECT realized_pnl_total FROM options_review_trades WHERE history_key=?",
("local_opt:1",),
).fetchone()
# 开平价相同:波动项为0 → 等于币×卖回价=850
self.assertAlmostEqual(float(row["realized_pnl_total"]), 850.0, places=2)
conn.close()