"""hold_timing unit tests.""" from backend.app.api.hold_timing import hold_timing def test_hold_target_perp_only_uses_perp_close(): g = { "open_at_ms": 1_000, "close_at_ms": 9_000, # later residual settle would have overwritten "status": "closed", "close_reason": "target_perp_only", } fills = [ {"leg": "option", "action": "open", "ts_ms": 1_000}, {"leg": "perp", "action": "open", "ts_ms": 1_100}, {"leg": "perp", "action": "close", "ts_ms": 5_000}, {"leg": "option", "action": "close", "ts_ms": 9_000}, ] h = hold_timing(g, fills) assert h["hold_open_at_ms"] == 1_000 assert h["hold_close_at_ms"] == 5_000 assert h["hold_ms"] == 4_000 assert h["hold_basis"] == "perp" def test_hold_option_residual_uses_perp(): g = { "open_at_ms": 100, "close_at_ms": 500, "status": "option_residual", "close_reason": "target_perp_only", } fills = [ {"leg": "perp", "action": "close", "ts_ms": 500}, ] h = hold_timing(g, fills) assert h["hold_close_at_ms"] == 500 assert h["hold_ms"] == 400 def test_hold_dual_leg_uses_group_close(): g = { "open_at_ms": 100, "close_at_ms": 800, "status": "closed", "close_reason": "fixed_usdt", } fills = [ {"leg": "option", "action": "close", "ts_ms": 790}, {"leg": "perp", "action": "close", "ts_ms": 800}, ] h = hold_timing(g, fills) assert h["hold_close_at_ms"] == 800 assert h["hold_ms"] == 700 assert h["hold_basis"] == "group" def test_hold_open_no_close(): g = {"open_at_ms": 100, "close_at_ms": None, "status": "open", "close_reason": None} h = hold_timing(g, []) assert h["hold_close_at_ms"] is None assert h["hold_ms"] is None assert h["hold_basis"] == "open" def test_hold_sqlite_row_like_without_get(): """sqlite3.Row 无 .get,需能转 dict。""" class Row: def __init__(self, d): self._d = d def keys(self): return self._d.keys() def __getitem__(self, k): return self._d[k] def __iter__(self): return iter(self._d) g = Row( { "open_at_ms": 100, "close_at_ms": None, "status": "option_residual", "close_reason": "target_perp_only", } ) fills = [Row({"leg": "perp", "action": "close", "ts_ms": 400})] h = hold_timing(g, fills) assert h["hold_close_at_ms"] == 400 assert h["hold_ms"] == 300