"""End-to-end: UnifiedExecutor → DriveLoop → KernelExecPort → (fake) DITAv2 kernel. Proves the pure engine drives a kernel-shaped backend correctly — translation (side/action/ TIF/order_type), exit-size capping, maker-rest→fill, exit-escalation, taker-cross. The fake kernel mimics ExecutionKernel's surface (slot()/process_intent_async/on_venue_event/venue). The injected translator is identity, so the fake reads IntentSpec directly and we can assert exactly what the port produced. Run: /home/dolphin/siloqy_env/bin/python3 -m pytest prod/exec_unified/test_kernel_port.py -q """ from __future__ import annotations import asyncio from decimal import Decimal from types import SimpleNamespace from prod.exec_unified.contract import ExecutionRequest, Side, UrgencyClass from prod.exec_unified.drive_loop import Action, DriveLoop from prod.exec_unified.executor import ExecuteStatus, UnifiedExecutor from prod.exec_unified.kernel_port import IntentSpec, KernelExecPort from prod.exec_unified.placer import MarketSnapshot from prod.exec_unified.router import ExecutionMethod from prod.exec_unified.working import WorkingRegistry NARROW = MarketSnapshot(best_bid=Decimal("100"), best_ask=Decimal("100.05"), spread_bps=Decimal("5"), tick=Decimal("0.01"), step=Decimal("0.001")) def _slot(trade_id, stage, size): return SimpleNamespace(trade_id=trade_id, fsm_state=SimpleNamespace(value=stage), size=size, asset="BTCUSDT") class FakeVenue: def __init__(self): self.events = [] self.positions = [] def reconcile(self): ev, self.events = self.events, [] return ev def open_positions(self): return self.positions class FakeKernel: """Minimal ExecutionKernel surface. process_intent_async mutates slot 0 like the real single-slot FSM: MARKET fills now; LIMIT rests (slot unchanged); CANCEL is a no-op.""" def __init__(self, slot): self._slot = slot self.venue = FakeVenue() self.max_slots = 1 self.processed: list[IntentSpec] = [] def slot(self, i): return self._slot async def process_intent_async(self, spec: IntentSpec): self.processed.append(spec) if spec.action_kind == "ENTER" and spec.order_type == "MARKET": self._slot = _slot(spec.request_id, "POSITION_OPEN", spec.size) elif spec.action_kind == "EXIT" and spec.order_type == "MARKET": self._slot = _slot("", "IDLE", Decimal(0)) return SimpleNamespace(accepted=True) def on_venue_event(self, e): fn = getattr(e, "apply", None) if fn: fn(self) # test helpers def force_open(self, tid, size="1"): self._slot = _slot(tid, "POSITION_OPEN", Decimal(size)) def _ident(spec): # local translator: kernel reads the normalized spec directly return spec class Clock: def __init__(self, t=1000.0): self.t = t def __call__(self): return self.t def _stack(slot): clock = Clock() kernel = FakeKernel(slot) port = KernelExecPort(kernel, _ident, clock=clock) reg = WorkingRegistry(port.clock) dl = DriveLoop(port, reg) return UnifiedExecutor(dl), dl, kernel, reg def _req(urgency, side=Side.BUY, size="0.001", **kw): return ExecutionRequest(request_id="req", asset="BTCUSDT", side=side, size=Decimal(size), urgency=urgency, **kw) def _run(c): return asyncio.run(c) # ── translation correctness ────────────────────────────────────────────────── def test_maker_entry_translated_to_limit_postonly(): ex, dl, kernel, reg = _stack(_slot("", "IDLE", Decimal(0))) r = _run(ex.execute(_req(UrgencyClass.ACQUIRE), NARROW)) assert r.status is ExecuteStatus.RESTING_MAKER spec = kernel.processed[-1] assert spec.action_kind == "ENTER" assert spec.order_type == "LIMIT" and spec.tif == "PostOnly" # maker assert spec.side is Side.BUY assert spec.limit_price == Decimal("100") and spec.size == Decimal("0.001") assert reg.working("req-0") is not None def test_catastrophic_translated_to_market_gtc(): ex, dl, kernel, reg = _stack(_slot("pos", "POSITION_OPEN", Decimal("1"))) r = _run(ex.execute(_req(UrgencyClass.CATASTROPHIC, side=Side.SELL, size="1"), NARROW)) assert r.status is ExecuteStatus.CROSSED_TAKER spec = kernel.processed[-1] assert spec.action_kind == "EXIT" and spec.order_type == "MARKET" and spec.tif == "GTC" assert spec.reduce_only is True # MARKET exit closed the slot in the fake kernel assert kernel.slot(0).size == Decimal(0) # ── exit size capping (pink _exit_intent_from_slot) ────────────────────────── def test_exit_size_capped_to_slot(): # Caller asks to close 10 but the slot holds 0.5 — the port caps to 0.5 (never overshoot). ex, dl, kernel, reg = _stack(_slot("pos", "POSITION_OPEN", Decimal("0.5"))) _run(ex.execute(_req(UrgencyClass.PROTECT, side=Side.SELL, size="10"), NARROW)) spec = kernel.processed[-1] assert spec.action_kind == "EXIT" assert spec.size == Decimal("0.5") # capped to the authoritative remaining size # ── full lifecycle: maker entry rests, then fills after TTL ────────────────── def test_entry_rests_then_fills_after_ttl(): ex, dl, kernel, reg = _stack(_slot("", "IDLE", Decimal(0))) r = _run(ex.execute(_req(UrgencyClass.ACQUIRE), NARROW)) assert r.status is ExecuteStatus.RESTING_MAKER wo = reg.working("req-0") assert wo is not None # the maker quote fills — kernel slot now shows our position (trade_id == our rid0) kernel.force_open("req-0") res = _run(dl.handle_expired(wo)) from prod.exec_unified.drive_loop import Resolved assert res is Resolved.FILLED_AFTER_TTL assert reg.working("req-0") is None # cleared, not retried # ── full lifecycle: maker exit never strands → escalates to MARKET ─────────── def test_maker_exit_escalates_to_market_and_closes(): ex, dl, kernel, reg = _stack(_slot("pos", "POSITION_OPEN", Decimal("1"))) r = _run(ex.execute(_req(UrgencyClass.PROTECT, side=Side.SELL, size="1"), NARROW)) assert r.status is ExecuteStatus.RESTING_MAKER # maker exit resting wo = reg.working("req-0") # TTL fires, position still open → escalate to MARKET (never strand) from prod.exec_unified.drive_loop import Resolved res = _run(dl.handle_expired(wo)) assert res is Resolved.ESCALATED_MARKET assert kernel.processed[-1].order_type == "MARKET" # crossed assert kernel.slot(0).size == Decimal(0) # position closed # ── requote gate reads real venue positions ────────────────────────────────── def test_requote_gate_blocks_when_venue_holds_position(): ex, dl, kernel, reg = _stack(_slot("", "IDLE", Decimal(0))) # entry with a chase budget, so a miss would try to requote _run(ex.execute(_req(UrgencyClass.ACQUIRE), NARROW)) wo = reg.working("req-0") wo.meta["max_reprices"] = 1 # allow a retry attempt kernel.venue.positions = [{"positionAmt": "0.3"}] # venue is NOT flat from prod.exec_unified.drive_loop import Resolved res = _run(dl.handle_expired(wo)) assert res is Resolved.REQUOTE_BLOCKED # port.open_positions() saw the position # no new order submitted after the blocked requote assert all(s.action_kind != "ENTER" or s.request_id == "req-0" for s in kernel.processed)