VIOLET V2b: ScriptedVenue + ExecDeadlineDriver (event-driven TTL @sub-second)

exec_driver.py lifts PINK's TTL-resolution logic (_exec_after_submit /
_handle_expired_working, live-proven) into a standalone driver with
injected ports (router/submit/pump/slot_view/venue_flat/ref-price) and
replaces the 1s polling sweep with one DeadlineScheduler deadline per
working order. The driver is the TIMING authority (router clamps TTLs
>=0.5s — its internal deadline is vestigial here); the router stays the
POLICY authority. R1 preserved verbatim: exit TTL -> MARKET escalation on
the SAME trade_id; post-only reject -> schedule_in(0) through the one
shared resolution path; venue-truth requote gate fails safe.

scripted_venue.py subclasses MockVenueAdapter (zero shared edits) with
per-trade directives: IMMEDIATE_FILL / REST_THEN_FILL / REST_THEN_EXPIRE /
POST_ONLY_REJECT / CANCEL_REJECT / FILL_RACES_CANCEL; deferred fills
release through reconcile() (the production pump seam), never the 50ms
subscribe() poll.

17 new tests incl. full-kernel CANCEL->venue mapping, fill-races-cancel,
bounded retry chains, on_fill deadline cancellation, fail-safe probe.
Router 77 green untouched; shared files clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-06-13 00:18:54 +02:00
parent ba01b914ce
commit dfe7136404
4 changed files with 906 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
"""V2b: ScriptedVenue — directive semantics + kernel CANCEL mapping."""
from __future__ import annotations
import sys
import time
from datetime import datetime, timezone
sys.path.insert(0, "/mnt/dolphinng5_predict")
sys.path.insert(0, "/mnt/dolphinng5_predict/nautilus_dolphin")
import pytest
from prod.clean_arch.dita_v2.contracts import (
KernelCommandType,
KernelEventKind,
KernelIntent,
TradeSide,
TradeStage,
)
from prod.clean_arch.violet.scripted_venue import Directive, ScriptedVenue
def _intent(tid: str, action=KernelCommandType.ENTER, *, order_type="LIMIT",
limit_price=99.5, ref=100.0) -> KernelIntent:
return KernelIntent(
timestamp=datetime.now(timezone.utc),
intent_id=tid, trade_id=tid, slot_id=0,
asset="BTCUSDT", side=TradeSide.SHORT, action=action,
reference_price=ref, target_size=1.0, leverage=1.0,
exit_leg_ratios=(1.0,), reason="test", metadata={},
stage=TradeStage.INTENT_CREATED,
order_type=order_type, limit_price=limit_price,
)
def test_rest_then_expire_acks_only_and_cancel_pops():
v = ScriptedVenue()
v.set_directive("T1", Directive.REST_THEN_EXPIRE)
events = v.submit(_intent("T1"))
assert [e.kind for e in events] == [KernelEventKind.ORDER_ACK]
assert len(v.open_orders()) == 1
order = v.open_orders()[0]
assert order.internal_trade_id == "T1"
out = v.cancel(order)
assert [e.kind for e in out] == [KernelEventKind.CANCEL_ACK]
assert v.open_orders() == []
assert v.reconcile() == [] # nothing ever falls due
def test_rest_then_fill_releases_via_reconcile_at_limit_price():
v = ScriptedVenue()
v.set_directive("T2", Directive.REST_THEN_FILL, fill_delay_ms=10.0)
v.submit(_intent("T2", limit_price=99.25))
assert v.reconcile() == [] # not due yet
time.sleep(0.02)
fills = v.reconcile()
assert [e.kind for e in fills] == [KernelEventKind.FULL_FILL]
assert fills[0].price == 99.25 # maker fills at the limit
assert fills[0].filled_size == 1.0
assert v.reconcile() == [] # released exactly once
def test_post_only_reject():
v = ScriptedVenue()
v.set_directive("T3", Directive.POST_ONLY_REJECT)
events = v.submit(_intent("T3"))
assert [e.kind for e in events] == [KernelEventKind.ORDER_REJECT]
assert v.open_orders() == []
def test_fill_races_cancel():
"""Cancel is rejected and the fill surfaces on the next reconcile —
the late-WS-fill-beats-cancel race."""
v = ScriptedVenue()
v.set_directive("T4", Directive.FILL_RACES_CANCEL)
v.submit(_intent("T4"))
order = v.open_orders()[0]
out = v.cancel(order)
assert [e.kind for e in out] == [KernelEventKind.CANCEL_REJECT]
fills = v.reconcile()
assert [e.kind for e in fills] == [KernelEventKind.FULL_FILL]
assert fills[0].trade_id == "T4"
def test_cancel_reject_directive():
v = ScriptedVenue()
v.set_directive("T5", Directive.CANCEL_REJECT)
v.submit(_intent("T5"))
out = v.cancel(v.open_orders()[0])
assert [e.kind for e in out] == [KernelEventKind.CANCEL_REJECT]
assert v.reconcile() == [] # no phantom fill
def test_prefix_lookup_covers_retries():
v = ScriptedVenue()
v.set_directive("T6", Directive.REST_THEN_EXPIRE)
v.set_directive("T6-r1", Directive.IMMEDIATE_FILL)
assert [e.kind for e in v.submit(_intent("T6"))] == [KernelEventKind.ORDER_ACK]
kinds = [e.kind for e in v.submit(_intent("T6-r1"))]
assert KernelEventKind.FULL_FILL in kinds # own directive wins
kinds_m = [e.kind for e in v.submit(_intent("T6-m"))]
assert kinds_m == [KernelEventKind.ORDER_ACK] # falls back to T6 prefix
def test_no_directive_is_parent_default():
v = ScriptedVenue()
kinds = [e.kind for e in v.submit(_intent("T7"))]
assert KernelEventKind.FULL_FILL in kinds
def test_kernel_cancel_reaches_venue_with_right_order():
"""Full kernel drive: ENTER (resting LIMIT) then CANCEL via
process_intent — the CANCEL must reach ScriptedVenue.cancel with the
venue_order_id of the resting quote and pop it."""
from prod.clean_arch.dita_v2.launcher import build_launcher_bundle
venue = ScriptedVenue()
venue.set_directive("T-CXL", Directive.REST_THEN_EXPIRE)
bundle = build_launcher_bundle(venue_mode="MOCK", max_slots=1, venue=venue)
kernel = bundle.kernel
kernel.process_intent(_intent("T-CXL"))
assert venue.submits == ["T-CXL"]
assert len(venue.open_orders()) == 1
resting_oid = venue.open_orders()[0].venue_order_id
cancel = _intent("T-CXL", action=KernelCommandType.CANCEL,
order_type="MARKET", limit_price=0.0)
kernel.process_intent(cancel)
assert venue.cancels == ["T-CXL"]
assert venue.open_orders() == [] # CANCEL_ACK popped it
assert resting_oid # mapping existed end-to-end
if __name__ == "__main__":
raise SystemExit(pytest.main([__file__, "-v"]))