fix: persist uncertain cancel outcomes
This commit is contained in:
@@ -219,6 +219,29 @@ class InMemorySlotRepository:
|
||||
)
|
||||
return True
|
||||
|
||||
def mark_cancel_outcome(
|
||||
self,
|
||||
slot_id: UUID,
|
||||
broker_order_id: str,
|
||||
state: str,
|
||||
) -> bool:
|
||||
"""Persist one cancel attempt iff the same order is still pending."""
|
||||
s = self._slots.get(slot_id)
|
||||
if (
|
||||
s is None
|
||||
or s.broker_order_id != broker_order_id
|
||||
or s.status not in self._PENDING
|
||||
):
|
||||
return False
|
||||
now = datetime.now(tz=timezone.utc)
|
||||
self._slots[slot_id] = replace(
|
||||
s,
|
||||
cancel_state=state,
|
||||
cancel_requested_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
return True
|
||||
|
||||
def list_dispatched_pending(self, instance_key: str = "default") -> list[Slot]:
|
||||
"""Pending slots already dispatched (broker_order_id NOT NULL) — poll targets."""
|
||||
return [
|
||||
@@ -236,7 +259,11 @@ class InMemorySlotRepository:
|
||||
s = self._slots.get(slot_id)
|
||||
if s is not None:
|
||||
self._slots[slot_id] = replace(
|
||||
s, broker_order_id=None, updated_at=datetime.now(tz=timezone.utc)
|
||||
s,
|
||||
broker_order_id=None,
|
||||
cancel_state=None,
|
||||
cancel_requested_at=None,
|
||||
updated_at=datetime.now(tz=timezone.utc),
|
||||
)
|
||||
|
||||
# --- bulk counts ---
|
||||
|
||||
@@ -59,6 +59,11 @@ class Slot:
|
||||
# Order venue carried from the admitted intent through dispatch/cancel.
|
||||
# It is reset to KRX when the permanent asset slot returns to INACTIVE.
|
||||
venue: str = "KRX"
|
||||
# Immediate cancel-request result. The slot remains pending until fill
|
||||
# polling confirms cancelled/filled. Persisted to prevent blind retries
|
||||
# across ticks and restarts.
|
||||
cancel_state: Optional[str] = None
|
||||
cancel_requested_at: Optional[datetime] = None
|
||||
|
||||
|
||||
# Canonical column contract for `Slot` (dcy-001 OQ-2 / FR-5).
|
||||
@@ -88,6 +93,8 @@ EXPECTED_SLOT_FIELDS: frozenset[str] = frozenset({
|
||||
"slippage_pct", # dcy-022 / REQ-068 (BAT-032)
|
||||
"occupancy_seq", # dcy-028 / REQ-081 (BAT-042)
|
||||
"venue",
|
||||
"cancel_state",
|
||||
"cancel_requested_at",
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -205,6 +205,8 @@ class SlotService:
|
||||
timeout_sec=None,
|
||||
slippage_pct=None,
|
||||
venue="KRX",
|
||||
cancel_state=None,
|
||||
cancel_requested_at=None,
|
||||
updated_at=datetime.now(tz=timezone.utc),
|
||||
)
|
||||
|
||||
@@ -277,6 +279,8 @@ class SlotService:
|
||||
slippage_pct=new_slippage_pct,
|
||||
occupancy_seq=new_occupancy_seq,
|
||||
venue=new_venue,
|
||||
cancel_state=None,
|
||||
cancel_requested_at=None,
|
||||
updated_at=datetime.now(tz=timezone.utc),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user