feat(execution): reconcile timed-out orders safely
This commit is contained in:
@@ -25,6 +25,7 @@ class FakeBroker:
|
||||
def __init__(self, balance, fill=None):
|
||||
self.balance = balance
|
||||
self.fill = fill or FillStatus(state="accepted")
|
||||
self.poll_metadata = None
|
||||
|
||||
def name(self):
|
||||
return "fake"
|
||||
@@ -32,7 +33,16 @@ class FakeBroker:
|
||||
def submit_order(self, req):
|
||||
return OrderAck(accepted=True, broker_order_id="1")
|
||||
|
||||
def poll_fill(self, broker_order_id, *, side, symbol):
|
||||
def poll_fill(
|
||||
self,
|
||||
broker_order_id,
|
||||
*,
|
||||
side,
|
||||
symbol,
|
||||
order_date=None,
|
||||
submitted_at=None,
|
||||
):
|
||||
self.poll_metadata = (order_date, submitted_at)
|
||||
return self.fill
|
||||
|
||||
def cancel_order(self, broker_order_id, *, side, symbol, qty, venue="KRX"):
|
||||
@@ -77,6 +87,23 @@ def test_confirmed_fill_is_persisted_once_and_manual_remainder_stays_hidden(tmp_
|
||||
assert StrategyOwnershipStore(store.path).snapshot()[0] == {"005930": 2}
|
||||
|
||||
|
||||
def test_poll_preserves_original_order_metadata_through_ownership_decorator(tmp_path):
|
||||
store = StrategyOwnershipStore(tmp_path / "ownership.json")
|
||||
delegate = FakeBroker([])
|
||||
broker = OwnershipAwareBroker(delegate, store)
|
||||
submitted_at = datetime(2026, 8, 14, 6, 20, tzinfo=timezone.utc)
|
||||
|
||||
broker.poll_fill(
|
||||
"1",
|
||||
side="buy",
|
||||
symbol="005930",
|
||||
order_date="20260814",
|
||||
submitted_at=submitted_at,
|
||||
)
|
||||
|
||||
assert delegate.poll_metadata == ("20260814", submitted_at)
|
||||
|
||||
|
||||
def test_strategy_quantity_above_raw_broker_total_fails_closed(tmp_path):
|
||||
store = StrategyOwnershipStore(tmp_path / "ownership.json")
|
||||
store.apply_fill(
|
||||
|
||||
@@ -36,7 +36,7 @@ _SLOT_COLUMNS = (
|
||||
"sell_strategy_id, forced_close_at, stop_loss_price, take_profit_price, "
|
||||
"created_at, updated_at, instance_key, retired_at, "
|
||||
"timeout_sec, slippage_pct, occupancy_seq, venue, "
|
||||
"cancel_state, cancel_requested_at"
|
||||
"cancel_state, cancel_requested_at, order_submitted_at, order_date, cancel_attempts"
|
||||
)
|
||||
_MANAGED_SLOT_SQL = (
|
||||
f"SELECT {_SLOT_COLUMNS} FROM daily_slot "
|
||||
@@ -149,6 +149,9 @@ def _row(slot: Slot) -> tuple:
|
||||
slot.venue,
|
||||
slot.cancel_state,
|
||||
slot.cancel_requested_at,
|
||||
slot.order_submitted_at,
|
||||
slot.order_date,
|
||||
slot.cancel_attempts,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user