"""多笔买/卖回 VWAP 与真盈亏.""" from __future__ import annotations import sqlite3 import unittest class SpotVwapBridgeTests(unittest.TestCase): def test_buy_and_close_sell_vwap_multi_fill(self): from lib.options.options_spot_bridge_lib import ( BRIDGE_CLOSED, add_bridge_buy_fill, add_bridge_close_sell_fill, bridge_buy_vwap, bridge_sell_vwap, ensure_bridge_table, insert_bridge, update_bridge, ) conn = sqlite3.connect(":memory:") conn.row_factory = sqlite3.Row ensure_bridge_table(conn) 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) conn.close() def test_true_pnl_uses_bridge_vwap_not_index(self): from lib.options.options_db import init_options_tables from lib.options.options_pnl_settle_lib import resolve_true_pnl_usdt_from_trade from lib.options.options_spot_bridge_lib import ( BRIDGE_CLOSED, add_bridge_buy_fill, add_bridge_close_sell_fill, ensure_bridge_table, insert_bridge, update_bridge, ) conn = sqlite3.connect(":memory:") conn.row_factory = sqlite3.Row init_options_tables(conn) 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) 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; coin_pnl=0.01 # A = 0.01*2000 - (0.01*2000 - 0.01*2000) = 20 # 若误用指数 90000/80000 会得到 700 pnl, src = resolve_true_pnl_usdt_from_trade( premium_paid=0.01, premium_received=0.02, realized_pnl=0.01, open_index_px=90000.0, close_index_px=80000.0, premium_ccy="BTC", conn=conn, bridge_id=bid, ) self.assertEqual(src, "premium_move") self.assertAlmostEqual(float(pnl), 20.0, places=2) conn.close() def test_pending_sell_blocks_true_pnl(self): from lib.options.options_pnl_settle_lib import resolve_true_pnl_usdt_from_trade from lib.options.options_spot_bridge_lib import ( BRIDGE_PENDING_SELL, add_bridge_buy_fill, add_bridge_close_sell_fill, ensure_bridge_table, insert_bridge, update_bridge, ) conn = sqlite3.connect(":memory:") conn.row_factory = sqlite3.Row 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, 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(src, "pending_sell") self.assertIsNone(pnl) conn.close() if __name__ == "__main__": unittest.main()