exec(unified): L2 foundation — contract §2 + whether-maker Router §6, pure, 26 tests
First code of the Unified Execution Layer (SPEC_UNIFIED_EXEC_LAYER_20260714.md). Pure
policy, stdlib+Decimal only, zero I/O, zero venue knowledge, zero importers elsewhere —
adopting it breaks nothing (freeze-safe; operator unparked the build 2026-07-14).
- contract.py: ExecutionRequest input surface (§2.1) + V-TYPES (Side, UrgencyClass,
ProtectiveSpec, ExecutionAdvice), frozen, validated-at-construction, illegal states
unrepresentable. 'an asset, a size, and a prayer'.
- router.py: decide(request) -> RoutingDecision — total pure map of the §6 urgency
ladder. Encodes A1 adjudication verdict in the architecture: Router=whether-maker,
SmartPlacer=where-in-book via the wants_placement/pre_submit seam. Complementary.
- _constants.py: policy magnitudes with provenance; PROVISIONAL ones flagged for
L8/L10 calibration (never vibes, never a hardcoded cadence).
- test_exec_unified.py: 26 behaviour + mutation-litmus tests. Verified RED under
CATASTROPHIC->MAKER and ACQUIRE cross_on_expiry->True mutations.
Not yet wired: PINK drive-loop port (§7), venue dialect (§11), telemetry (§12).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 23:00:42 +02:00
|
|
|
|
"""Policy constants — from data, never vibes (spec §6 closing note).
|
|
|
|
|
|
|
|
|
|
|
|
Every constant cites its provenance. Where a number is not yet backed by an L8/L10
|
|
|
|
|
|
characterization row it is marked PROVISIONAL and must be calibrated before the smart
|
|
|
|
|
|
path arms with real capital — a provisional constant is a known-unknown, not a vibe.
|
|
|
|
|
|
|
|
|
|
|
|
Cadence is NEVER hardcoded here (no literal 1 s): the drive loop takes its clock
|
|
|
|
|
|
injected (spec §7, C1). These are policy magnitudes, not periods.
|
|
|
|
|
|
"""
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
|
|
|
|
# PROTECT: "maker at touch, one reprice, ≤2 s total, then cross" (spec §6).
|
|
|
|
|
|
PROTECT_REPRICE_LIMIT: int = 1
|
|
|
|
|
|
PROTECT_MAX_MS: int = 2_000
|
|
|
|
|
|
|
|
|
|
|
|
# HARVEST: "maker at target ± offset, chase ≤ N; give up when regression eats X%
|
|
|
|
|
|
# of unrealized → cross" (spec §6). N and X are PROVISIONAL — no characterization
|
|
|
|
|
|
# row fixes them yet (§17 open question: chase bounds from bookDepth replay).
|
|
|
|
|
|
HARVEST_MAX_CHASES: int = 3 # PROVISIONAL — calibrate vs L8 fill_sim
|
|
|
|
|
|
HARVEST_GIVEUP_REGRESSION_FRAC: Decimal = Decimal("0.25") # PROVISIONAL — 25% of unrealized
|
|
|
|
|
|
|
|
|
|
|
|
# ACQUIRE: "patient maker inside spread; abandon, never chase" (spec §6, §4-1:
|
|
|
|
|
|
# a missed entry is free, a chased entry is not). No chase budget by construction.
|
|
|
|
|
|
ACQUIRE_MAX_CHASES: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
# Dead-man's stop default multiple of software SL distance (spec §10, §17 open
|
|
|
|
|
|
# question: 2× vs ATR-scaled). PROVISIONAL default.
|
|
|
|
|
|
PROTECTIVE_STOP_MULT_DEFAULT: Decimal = Decimal("2.0")
|
2026-07-14 23:51:04 +02:00
|
|
|
|
|
2026-07-15 02:30:30 +02:00
|
|
|
|
# Maker-quote lifetime for UNBOUNDED-TTL urgencies (HARVEST/ACQUIRE): how long a resting
|
|
|
|
|
|
# quote lives before the drive loop sweeps + re-evaluates it. Bounded quote lifetime +
|
|
|
|
|
|
# cancel/replace is the certified GTX discipline (spec §4-16). PROVISIONAL — calibrate vs
|
|
|
|
|
|
# L8 GTX fill latencies; measured in injected-clock seconds, never a hardcoded loop literal.
|
|
|
|
|
|
MAKER_QUOTE_TTL_S: float = 6.0
|
|
|
|
|
|
|
2026-07-14 23:51:04 +02:00
|
|
|
|
# Requote hot-window: after an OWN fill, refuse to re-quote for this long because the
|
|
|
|
|
|
# REST venue reconcile lags the WS fill by seconds — re-quoting inside it double-enters.
|
|
|
|
|
|
# Provenance: live double-entry, pink_direct.py:1055 / :1323 (2026-06-10). Measured in
|
|
|
|
|
|
# injected-clock seconds; the loop reads it, never a hardcoded literal in the branch.
|
|
|
|
|
|
REQUOTE_HOT_WINDOW_S: float = 5.0
|