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
+11 -33
View File
@@ -24,12 +24,10 @@ class SpotVwapBridgeTests(unittest.TestCase):
bid = insert_bridge(conn, underlying="BTC", status="holding", budget_usdt=2200)
add_bridge_buy_fill(conn, bid, usdt_spent=1000.0, coin_bought=0.5)
add_bridge_buy_fill(conn, bid, usdt_spent=1200.0, coin_bought=0.6)
# 2200 / 1.1 = 2000
self.assertAlmostEqual(float(bridge_buy_vwap(conn, bid)), 2000.0, places=4)
add_bridge_close_sell_fill(conn, bid, usdt_recovered=800.0, coin_sold=0.4)
add_bridge_close_sell_fill(conn, bid, usdt_recovered=1200.0, coin_sold=0.6)
# 2000 / 1.0 = 2000
self.assertAlmostEqual(float(bridge_sell_vwap(conn, bid)), 2000.0, places=4)
update_bridge(conn, bid, status=BRIDGE_CLOSED, close=True)
self.assertAlmostEqual(float(bridge_sell_vwap(conn, bid)), 2000.0, places=4)
@@ -56,15 +54,13 @@ class SpotVwapBridgeTests(unittest.TestCase):
add_bridge_close_sell_fill(conn, bid, usdt_recovered=1600.0, coin_sold=0.8)
add_bridge_close_sell_fill(conn, bid, usdt_recovered=400.0, coin_sold=0.2)
update_bridge(conn, bid, status=BRIDGE_CLOSED, close=True)
# buy_vwap=2000, sell_vwap=2000; 初始权利金按买 VWAP=20
# U=(0.01+0.01)*2000 - 20 = 20; 若误用指数 80000 会得到大数
# sell_vwap=2000; U=0.01*2000=20; 不用指数 80000
pnl, src = resolve_true_pnl_usdt_from_trade(
premium_paid=0.01,
premium_received=0.02,
realized_pnl=0.01,
open_index_px=2000.0,
open_index_px=90000.0,
close_index_px=80000.0,
initial_premium_usdt=20.0,
premium_ccy="BTC",
conn=conn,
bridge_id=bid,
@@ -73,13 +69,12 @@ class SpotVwapBridgeTests(unittest.TestCase):
self.assertAlmostEqual(float(pnl), 20.0, places=2)
conn.close()
def test_pending_sell_blocks_true_pnl(self):
def test_pending_sell_still_allows_option_pnl(self):
"""现货待卖回不阻断期权盈亏折U(用冻结平仓价)."""
from lib.options.options_pnl_settle_lib import resolve_true_pnl_usdt_from_trade
from lib.options.options_spot_bridge_lib import (
BRIDGE_HOLDING,
BRIDGE_PENDING_SELL,
add_bridge_buy_fill,
add_bridge_close_sell_fill,
ensure_bridge_table,
insert_bridge,
update_bridge,
@@ -90,7 +85,6 @@ class SpotVwapBridgeTests(unittest.TestCase):
ensure_bridge_table(conn)
bid = insert_bridge(conn, underlying="ETH", status="holding", budget_usdt=3000)
add_bridge_buy_fill(conn, bid, usdt_spent=3000.0, coin_bought=1.0)
add_bridge_close_sell_fill(conn, bid, usdt_recovered=1500.0, coin_sold=0.5)
update_bridge(conn, bid, status=BRIDGE_PENDING_SELL)
pnl, src = resolve_true_pnl_usdt_from_trade(
premium_paid=0.01,
@@ -102,26 +96,12 @@ class SpotVwapBridgeTests(unittest.TestCase):
conn=conn,
bridge_id=bid,
)
self.assertEqual(src, "pending_sell")
self.assertIsNone(pnl)
# holding 未关桥同样不得用指数提前结算
update_bridge(conn, bid, status=BRIDGE_HOLDING)
pnl2, src2 = resolve_true_pnl_usdt_from_trade(
premium_paid=0.01,
premium_received=0.02,
realized_pnl=0.01,
open_index_px=3000.0,
close_index_px=3000.0,
premium_ccy="ETH",
conn=conn,
bridge_id=bid,
)
self.assertEqual(src2, "pending_sell")
self.assertIsNone(pnl2)
self.assertEqual(src, "premium_move")
self.assertAlmostEqual(float(pnl), 30.0, places=2)
conn.close()
def test_closed_bridge_without_sell_vwap_is_missing(self):
"""已关桥但无 close_sell 时不得用指数冒充卖回价."""
def test_closed_bridge_without_sell_falls_back_close_index(self):
"""已关桥无卖回 VWAP 时回退冻结平仓价."""
from lib.options.options_pnl_settle_lib import resolve_true_pnl_usdt_from_trade
from lib.options.options_spot_bridge_lib import (
BRIDGE_CLOSED,
@@ -142,17 +122,15 @@ class SpotVwapBridgeTests(unittest.TestCase):
realized_pnl=0.01,
open_index_px=100000.0,
close_index_px=90000.0,
initial_premium_usdt=1000.0,
premium_ccy="BTC",
conn=conn,
bridge_id=bid,
)
self.assertEqual(src, "none")
self.assertIsNone(pnl)
self.assertEqual(src, "premium_move")
self.assertAlmostEqual(float(pnl), 900.0, places=2)
conn.close()
def test_buy_vwap_ignores_shrunk_coin_bought(self):
"""开仓后 coin_bought 被改成权利金量时,不得用 budget/缩水量当买价."""
from lib.options.options_spot_bridge_lib import (
add_bridge_buy_fill,
bridge_buy_vwap,
@@ -166,7 +144,7 @@ class SpotVwapBridgeTests(unittest.TestCase):
ensure_bridge_table(conn)
bid = insert_bridge(conn, underlying="BTC", status="holding", budget_usdt=2200)
add_bridge_buy_fill(conn, bid, usdt_spent=2200.0, coin_bought=1.1)
update_bridge(conn, bid, coin_bought=0.01) # 缩成权利金
update_bridge(conn, bid, coin_bought=0.01)
self.assertAlmostEqual(float(bridge_buy_vwap(conn, bid)), 2000.0, places=4)
conn.close()