feat: propagate intent venue through execution
This commit is contained in:
@@ -75,6 +75,7 @@ class BuyIntent:
|
||||
# slippage_pct: effective limit = entry_price*(1+pct/100) buy / *(1-pct/100) sell.
|
||||
timeout_sec: Optional[int] = None
|
||||
slippage_pct: Optional[float] = None
|
||||
venue: str = "KRX"
|
||||
extra: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
@@ -93,6 +94,7 @@ class SellIntent:
|
||||
# dcy-022 / REQ-068: execution policy (optional, backward-compat).
|
||||
timeout_sec: Optional[int] = None
|
||||
slippage_pct: Optional[float] = None
|
||||
venue: str = "KRX"
|
||||
extra: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
@@ -152,6 +154,7 @@ class IntentService:
|
||||
"entry_price": intent.entry_price,
|
||||
"strategy_id": intent.strategy_id,
|
||||
"sell_strategy_id": intent.sell_strategy_id,
|
||||
"venue": intent.venue,
|
||||
}
|
||||
prior = self._dedup(intent.intent_id, "buy", payload)
|
||||
if prior is not None:
|
||||
@@ -169,6 +172,7 @@ class IntentService:
|
||||
"reason": intent.reason,
|
||||
"sell_strategy_id": intent.sell_strategy_id,
|
||||
"qty": intent.qty,
|
||||
"venue": intent.venue,
|
||||
}
|
||||
prior = self._dedup(intent.intent_id, "sell", payload)
|
||||
if prior is not None:
|
||||
@@ -207,6 +211,9 @@ class IntentService:
|
||||
dcy-036 / REQ-114: entry gate — if entry_allowed_fn returns False,
|
||||
BuyIntent is rejected before any slot lookup."""
|
||||
|
||||
if intent.venue not in {"KRX", "NXT", "SOR"}:
|
||||
return IntentDecision(intent.intent_id, "rejected", None, "invalid_venue")
|
||||
|
||||
# dcy-036 / REQ-114: day-start entry gate (fail-closed).
|
||||
# None or True → pass; False → reject new entry.
|
||||
# SellIntent is NOT checked (청산 경로는 차단하지 않음 AC-5).
|
||||
@@ -292,6 +299,7 @@ class IntentService:
|
||||
take_profit_price=intent.take_profit_price,
|
||||
timeout_sec=effective_timeout,
|
||||
slippage_pct=intent.slippage_pct,
|
||||
venue=intent.venue,
|
||||
extra={"intent_id": intent.intent_id, "symbol": symbol},
|
||||
)
|
||||
except SlotStateMismatchError:
|
||||
@@ -300,6 +308,9 @@ class IntentService:
|
||||
return IntentDecision(intent.intent_id, "rejected", None, "already_active")
|
||||
|
||||
def _admit_sell(self, intent: SellIntent) -> IntentDecision:
|
||||
if intent.venue not in {"KRX", "NXT", "SOR"}:
|
||||
return IntentDecision(intent.intent_id, "rejected", None, "invalid_venue")
|
||||
|
||||
slot = self._repo.fetch_slot(intent.slot_id)
|
||||
if slot is None:
|
||||
return IntentDecision(intent.intent_id, "rejected", None, "slot_not_found")
|
||||
@@ -342,6 +353,7 @@ class IntentService:
|
||||
qty=intent.qty,
|
||||
timeout_sec=effective_timeout,
|
||||
slippage_pct=intent.slippage_pct,
|
||||
venue=intent.venue,
|
||||
extra={"intent_id": intent.intent_id},
|
||||
)
|
||||
except SlotStateMismatchError:
|
||||
|
||||
Reference in New Issue
Block a user