Files
crypto_monitor/tests/test_options_sync.py
T

134 lines
4.4 KiB
Python

"""期权平仓/到期状态同步单测."""
import sqlite3
from lib.exchange.okx_options_lib import resolve_option_close_from_history
from lib.options.options_db import init_options_tables
from lib.options.options_monitor_lib import sync_open_options_trades
def test_resolve_option_close_from_history_picks_latest():
rows = [
{"instId": "ETH-USD_UM-260709-1700-P", "uTime": "1000", "realizedPnl": "-1.0", "closeAvgPx": "0"},
{"instId": "ETH-USD_UM-260709-1700-P", "uTime": "2000", "realizedPnl": "-1.24", "closeAvgPx": "0", "posId": "9"},
]
got = resolve_option_close_from_history(rows, open_ms=500)
assert got is not None
assert got["realized_pnl"] == -1.24
assert got["pos_id"] == "9"
def test_sync_open_options_trades_marks_expired_closed():
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
init_options_tables(conn)
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
open_quote, premium_paid, status)
VALUES (?, 'ETH', 'P', 1700, '', 20, 0.2, 6.2, 1.24, 'open')
""",
("ETH-USD_UM-260709-1700-P",),
)
conn.commit()
n = sync_open_options_trades(
conn,
live_inst_ids=set(),
fetch_history_fn=lambda _inst: [],
)
assert n == 1
row = conn.execute("SELECT status, premium_received, realized_pnl, signal_note FROM options_trades").fetchone()
assert row["status"] == "closed"
assert row["premium_received"] == 0.0
assert row["realized_pnl"] == -1.24
assert "到期结算" in (row["signal_note"] or "")
def test_sync_open_options_trades_skips_without_close_evidence():
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
init_options_tables(conn)
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
open_quote, premium_paid, status, created_at)
VALUES (?, 'BTC', 'P', 62000, '', 1, 0.01, 380.0, 3.8, 'open', '2026-07-09 08:00:00')
""",
("BTC-USD_UM-260710-62000-P",),
)
conn.commit()
n = sync_open_options_trades(
conn,
live_inst_ids=set(),
fetch_history_fn=lambda _inst: [],
)
assert n == 0
row = conn.execute("SELECT status FROM options_trades").fetchone()
assert row["status"] == "open"
def test_reconcile_live_open_trades_reopens_sync_artifact():
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
init_options_tables(conn)
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
open_quote, premium_paid, status, closed_at)
VALUES (?, 'BTC', 'P', 62000, '', 1, 0.01, 380.0, 3.8, 'closed', '2026-07-09 09:10:34')
""",
("BTC-USD_UM-260710-62000-P",),
)
conn.commit()
from lib.options.options_monitor_lib import reconcile_live_open_trades
n = reconcile_live_open_trades(conn, live_inst_ids={"BTC-USD_UM-260710-62000-P"})
assert n == 1
row = conn.execute("SELECT status, closed_at FROM options_trades").fetchone()
assert row["status"] == "open"
assert row["closed_at"] is None
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
init_options_tables(conn)
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
open_quote, premium_paid, status, created_at)
VALUES (?, 'ETH', 'P', 1700, '', 20, 0.2, 6.2, 1.24, 'open', '2026-07-08 02:32:44')
""",
("ETH-USD_UM-260709-1700-P",),
)
conn.commit()
def _hist(_inst):
return [
{
"instId": "ETH-USD_UM-260709-1700-P",
"uTime": "1784000000000",
"realizedPnl": "-0.5",
"closeAvgPx": "0.1",
"posId": "pos-1",
}
]
n = sync_open_options_trades(
conn,
live_inst_ids=set(),
fetch_history_fn=_hist,
)
assert n == 1
row = conn.execute(
"SELECT status, premium_received, realized_pnl, close_ord_id FROM options_trades"
).fetchone()
assert row["status"] == "closed"
assert row["realized_pnl"] == -0.5
assert row["premium_received"] == 0.74
assert row["close_ord_id"] == "pos-1"