# -*- coding: utf-8 -*- """repair_options_spot_vwap_from_sim_ledger:同秒多笔卖回不得重复配对 USDT.""" from __future__ import annotations import importlib.util import sqlite3 import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "scripts" / "repair_options_spot_vwap_from_sim_ledger.py" def _load_repair(): spec = importlib.util.spec_from_file_location("repair_opt_vwap", SCRIPT) assert spec and spec.loader mod = importlib.util.module_from_spec(spec) sys.modules[spec.name] = mod spec.loader.exec_module(mod) return mod def _mk_conn() -> sqlite3.Connection: c = sqlite3.connect(":memory:") c.row_factory = sqlite3.Row c.executescript( """ CREATE TABLE sim_ledger_entries ( id INTEGER PRIMARY KEY, ts TEXT, kind TEXT, ccy TEXT, account TEXT, amount REAL, note TEXT ); """ ) return c def test_same_ts_multi_sell_pairs_distinct_usdt(): mod = _load_repair() c = _mk_conn() # 模拟 trade2:最后一笔 option_close 后同秒/连秒多笔 BTC→USDT rows = [ (21, "2026-10-13 00:06:58", "option_close", "BTC", "trading", 0.01, "sell BTC-USD-261015-84000-P"), (23, "2026-10-13 00:07:35", "option_close", "BTC", "trading", 0.008, "sell BTC-USD-261015-84000-P"), (24, "2026-10-13 00:07:35", "convert", "BTC", "trading", -0.01123875, "BTC/USDT mkt 81411.8737"), (25, "2026-10-13 00:07:35", "convert", "USDT", "trading", 914.967695545875, "from btc"), (26, "2026-10-13 00:07:36", "convert", "BTC", "trading", -0.018413659934387205, "BTC/USDT mkt 81424.9671"), (27, "2026-10-13 00:07:36", "convert", "USDT", "trading", 1499.3316552687493, "from btc"), (28, "2026-10-13 00:07:36", "convert", "BTC", "trading", -1.8413659934386636e-05, "BTC/USDT mkt 81418.9702"), (29, "2026-10-13 00:07:36", "convert", "USDT", "trading", 1.4992212285500766, "from btc"), ] c.executemany( "INSERT INTO sim_ledger_entries(id,ts,kind,ccy,account,amount,note) VALUES (?,?,?,?,?,?,?)", rows, ) buy_u, buy_c, sell_u, sell_c = mod._ledger_buy_sell( c, underly="BTC", inst_id="BTC-USD-261015-84000-P", open_ts="", close_ts="", ) assert buy_u is None and buy_c is None assert sell_c is not None and abs(sell_c - 0.02967082359432159) < 1e-12 assert sell_u is not None and abs(sell_u - 2415.798572043174) < 1e-6 vwap = sell_u / sell_c assert 81400 < vwap < 81450 def test_old_bug_would_double_count_large_fill(): """对照:若按同 ts 永远取第一笔 USDT,会得到 ~3913 而非 ~2415.""" mod = _load_repair() c = _mk_conn() rows = [ (23, "t0", "option_close", "BTC", "trading", 0.01, "sell BTC-USD-X"), (24, "t1", "convert", "BTC", "trading", -0.01, "BTC/USDT mkt 1"), (25, "t1", "convert", "USDT", "trading", 900.0, "from btc"), (26, "t2", "convert", "BTC", "trading", -0.02, "BTC/USDT mkt 1"), (27, "t2", "convert", "USDT", "trading", 1500.0, "from btc"), (28, "t2", "convert", "BTC", "trading", -0.0001, "BTC/USDT mkt 1"), (29, "t2", "convert", "USDT", "trading", 1.5, "from btc"), ] c.executemany( "INSERT INTO sim_ledger_entries(id,ts,kind,ccy,account,amount,note) VALUES (?,?,?,?,?,?,?)", rows, ) _, _, sell_u, sell_c = mod._ledger_buy_sell( c, underly="BTC", inst_id="BTC-USD-X", open_ts="", close_ts="" ) assert sell_u == 2401.5 assert abs(float(sell_c) - 0.0301) < 1e-12