Files
siloqy/prod/clean_arch/dita_v2/contracts.py
Codex 9bef1f6b01 dita_v2: VenueTelemetrySnapshot + Zinc venue plane (4th shm partition) + local Rust target dir
Upstream-canonical commit of the ~366 lines that sat uncommitted in the working
tree (surveyed in DITAV2_SOA_SURVEY_20260702). Venue telemetry published at every
venue boundary (submit/cancel/reconcile) over the zinc venue_region; SOA per
UV DITAv2 adjudication 2026-07-03.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 00:42:20 +02:00

411 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Canonical v2 contracts for the DITAv2 execution kernel."""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, Mapping, Optional, Sequence, Tuple
class TradeSide(str, Enum):
"""Trade side."""
LONG = "LONG"
SHORT = "SHORT"
FLAT = "FLAT"
class TradeStage(str, Enum):
"""Execution stage for a trade slot."""
IDLE = "IDLE"
DECISION_CREATED = "DECISION_CREATED"
INTENT_CREATED = "INTENT_CREATED"
ORDER_REQUESTED = "ORDER_REQUESTED"
ORDER_SENT = "ORDER_SENT"
ORDER_ACKED = "ORDER_ACKED"
ORDER_REJECTED = "ORDER_REJECTED"
ENTRY_WORKING = "ENTRY_WORKING"
PARTIAL_FILL = "PARTIAL_FILL"
POSITION_OPENED = "POSITION_OPENED"
POSITION_OPEN = "POSITION_OPEN"
EXIT_REQUESTED = "EXIT_REQUESTED"
EXIT_SENT = "EXIT_SENT"
EXIT_ACKED = "EXIT_ACKED"
EXIT_REJECTED = "EXIT_REJECTED"
EXIT_WORKING = "EXIT_WORKING"
POSITION_PARTIALLY_CLOSED = "POSITION_PARTIALLY_CLOSED"
POSITION_CLOSED = "POSITION_CLOSED"
CLOSED = "CLOSED"
TRADE_TERMINAL_WRITTEN = "TRADE_TERMINAL_WRITTEN"
STALE_STATE_RECONCILING = "STALE_STATE_RECONCILING"
class KernelCommandType(str, Enum):
"""Kernel command types."""
ENTER = "ENTER"
EXIT = "EXIT"
MARK_PRICE = "MARK_PRICE"
RECONCILE = "RECONCILE"
CONTROL = "CONTROL"
CANCEL = "CANCEL"
class KernelEventKind(str, Enum):
"""Normalized venue event kinds."""
ORDER_ACK = "ORDER_ACK"
ORDER_REJECT = "ORDER_REJECT"
RATE_LIMITED = "RATE_LIMITED"
PARTIAL_FILL = "PARTIAL_FILL"
FULL_FILL = "FULL_FILL"
CANCEL_ACK = "CANCEL_ACK"
CANCEL_REJECT = "CANCEL_REJECT"
MARK_PRICE = "MARK_PRICE"
RECONCILE = "RECONCILE"
CONTROL = "CONTROL"
class KernelDiagnosticCode(str, Enum):
"""Structured diagnostic codes emitted by the kernel."""
OK = "OK"
RATE_LIMITED = "RATE_LIMITED"
INVALID_SLOT_ID = "INVALID_SLOT_ID"
INVALID_INTENT = "INVALID_INTENT"
UNSUPPORTED_INTENT = "UNSUPPORTED_INTENT"
SLOT_BUSY = "SLOT_BUSY"
NO_OPEN_POSITION = "NO_OPEN_POSITION"
NO_ACTIVE_EXIT_ORDER = "NO_ACTIVE_EXIT_ORDER"
UNKNOWN_EVENT_KIND = "UNKNOWN_EVENT_KIND"
ORDER_REJECTED = "ORDER_REJECTED"
ENTRY_ORDER_REJECTED = "ENTRY_ORDER_REJECTED"
EXIT_ORDER_REJECTED = "EXIT_ORDER_REJECTED"
CANCEL_REJECTED = "CANCEL_REJECTED"
STALE_STATE_RECONCILE = "STALE_STATE_RECONCILE"
RECONCILED = "RECONCILED"
DUPLICATE_EVENT = "DUPLICATE_EVENT"
UNRESOLVED_SLOT = "UNRESOLVED_SLOT"
INVALID_TRANSITION = "INVALID_TRANSITION"
TERMINAL_STATE = "TERMINAL_STATE"
CAPITAL_FROZEN = "CAPITAL_FROZEN"
class KernelSeverity(str, Enum):
"""Severity classification for kernel outcomes."""
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
CRITICAL = "CRITICAL"
class VenueOrderStatus(str, Enum):
"""Order status surface mirrored from venue truth."""
NEW = "NEW"
ACKED = "ACKED"
PARTIALLY_FILLED = "PARTIALLY_FILLED"
FILLED = "FILLED"
CANCELED = "CANCELED"
REJECTED = "REJECTED"
class VenueEventStatus(str, Enum):
"""Status alias for normalized venue events."""
ACKED = "ACKED"
REJECTED = "REJECTED"
RATE_LIMITED = "RATE_LIMITED"
PARTIALLY_FILLED = "PARTIALLY_FILLED"
FILLED = "FILLED"
CANCELED = "CANCELED"
CANCELED_REJECTED = "CANCEL_REJECTED"
@dataclass(frozen=True)
class VenueOrder:
"""Venue-specific order identity and fill state."""
internal_trade_id: str
venue_order_id: str
venue_client_id: str
side: TradeSide
intended_size: float
filled_size: float = 0.0
average_fill_price: float = 0.0
status: VenueOrderStatus = VenueOrderStatus.NEW
metadata: Dict[str, Any] = field(default_factory=dict)
@property
def remaining_size(self) -> float:
return max(0.0, float(self.intended_size) - float(self.filled_size))
@dataclass(frozen=True)
class VenueTelemetrySnapshot:
"""Shared-memory surface for venue-side call boundaries and state."""
phase: str = "idle"
status: str = "IDLE"
venue: str = "bingx"
endpoint: str = ""
method: str = ""
intent_id: str = ""
trade_id: str = ""
slot_id: int = 0
asset: str = ""
side: TradeSide = TradeSide.FLAT
action: str = ""
order_id: str = ""
client_order_id: str = ""
venue_order_status: str = ""
venue_event_kind: str = ""
message: str = ""
retry_after_ms: int = 0
timestamp: Optional[datetime] = None
details: Dict[str, Any] = field(default_factory=dict)
def as_dict(self) -> Dict[str, Any]:
return {
"phase": self.phase,
"status": self.status,
"venue": self.venue,
"endpoint": self.endpoint,
"method": self.method,
"intent_id": self.intent_id,
"trade_id": self.trade_id,
"slot_id": int(self.slot_id or 0),
"asset": self.asset,
"side": self.side.value if hasattr(self.side, "value") else str(self.side),
"action": self.action,
"order_id": self.order_id,
"client_order_id": self.client_order_id,
"venue_order_status": self.venue_order_status,
"venue_event_kind": self.venue_event_kind,
"message": self.message,
"retry_after_ms": int(self.retry_after_ms or 0),
"timestamp": self.timestamp.isoformat() if hasattr(self.timestamp, "isoformat") else None,
"details": dict(self.details),
}
@dataclass
class TradeSlot:
"""A single execution slot managed by the v2 kernel."""
slot_id: int
trade_id: str = ""
asset: str = ""
side: TradeSide = TradeSide.FLAT
entry_price: float = 0.0
size: float = 0.0
initial_size: float = 0.0
leverage: float = 0.0
entry_time: Optional[datetime] = None
unrealized_pnl: float = 0.0
realized_pnl: float = 0.0
closed: bool = False
exit_leg_ratios: Tuple[float, ...] = (1.0,)
active_leg_index: int = 0
active_exit_order: Optional[VenueOrder] = None
active_entry_order: Optional[VenueOrder] = None
fsm_state: TradeStage = TradeStage.IDLE
close_reason: str = ""
last_event_time: Optional[datetime] = None
seen_event_ids: Tuple[str, ...] = ()
metadata: Dict[str, Any] = field(default_factory=dict)
def is_free(self) -> bool:
return self.fsm_state in {TradeStage.IDLE, TradeStage.CLOSED} and float(self.size or 0.0) <= 0.0 and not self.active_entry_order and not self.active_exit_order
def is_open(self) -> bool:
return self.fsm_state in {
TradeStage.ENTRY_WORKING,
TradeStage.POSITION_OPENED,
TradeStage.POSITION_OPEN,
TradeStage.EXIT_WORKING,
} and not self.closed
def mark_price(self, price: float) -> None:
if price is None or price != price or price <= 0:
return
self.entry_price = self.entry_price or price
if self.entry_price <= 0 or self.size <= 0:
self.unrealized_pnl = 0.0
return
delta = (price - self.entry_price) / self.entry_price
if self.side == TradeSide.SHORT:
delta = -delta
self.unrealized_pnl = delta * self.size * self.entry_price * self.leverage
def next_exit_ratio(self) -> float:
if self.active_leg_index < len(self.exit_leg_ratios):
ratio = float(self.exit_leg_ratios[self.active_leg_index])
return max(0.0, min(1.0, ratio))
return 1.0
def consume_exit_leg(self) -> float:
ratio = self.next_exit_ratio()
self.active_leg_index = min(self.active_leg_index + 1, max(len(self.exit_leg_ratios), 1))
return ratio
def remaining_size(self) -> float:
return max(0.0, float(self.size))
def attach_entry_order(self, order: VenueOrder) -> None:
self.active_entry_order = order
def attach_exit_order(self, order: VenueOrder) -> None:
self.active_exit_order = order
def to_dict(self) -> Dict[str, Any]:
def _order_dict(order: Optional[VenueOrder]) -> Optional[Dict[str, Any]]:
if order is None:
return None
return {
"internal_trade_id": order.internal_trade_id,
"venue_order_id": order.venue_order_id,
"venue_client_id": order.venue_client_id,
"side": order.side.value,
"intended_size": float(order.intended_size or 0.0),
"filled_size": float(order.filled_size or 0.0),
"average_fill_price": float(order.average_fill_price or 0.0),
"status": order.status.value,
"metadata": dict(order.metadata),
}
return {
"slot_id": self.slot_id,
"trade_id": self.trade_id,
"asset": self.asset,
"side": self.side.value,
"entry_price": float(self.entry_price or 0.0),
"size": float(self.size or 0.0),
"initial_size": float(self.initial_size or 0.0),
"leverage": float(self.leverage or 0.0),
"entry_time": self.entry_time.isoformat() if hasattr(self.entry_time, "isoformat") else None,
"unrealized_pnl": float(self.unrealized_pnl or 0.0),
"realized_pnl": float(self.realized_pnl or 0.0),
"closed": bool(self.closed),
"exit_leg_ratios": [float(r) for r in self.exit_leg_ratios],
"active_leg_index": int(self.active_leg_index or 0),
"active_exit_order": _order_dict(self.active_exit_order),
"active_entry_order": _order_dict(self.active_entry_order),
"fsm_state": self.fsm_state.value,
"close_reason": self.close_reason,
"last_event_time": self.last_event_time.isoformat() if hasattr(self.last_event_time, "isoformat") else None,
"seen_event_ids": list(self.seen_event_ids),
"metadata": dict(self.metadata),
}
@dataclass(frozen=True)
class KernelIntent:
"""Command emitted by the algo and written to the hot-path intent region."""
timestamp: datetime
intent_id: str
trade_id: str
slot_id: int
asset: str
side: TradeSide
action: KernelCommandType
reference_price: float
target_size: float
leverage: float
exit_leg_ratios: Tuple[float, ...] = (1.0,)
reason: str = ""
metadata: Dict[str, Any] = field(default_factory=dict)
stage: TradeStage = TradeStage.INTENT_CREATED
order_type: str = "MARKET"
limit_price: float = 0.0
@dataclass(frozen=True)
class VenueEvent:
"""Normalized venue truth mapped into DITAv2 semantics."""
timestamp: datetime
event_id: str
trade_id: str
slot_id: int
kind: KernelEventKind
status: VenueEventStatus
venue_order_id: str = ""
venue_client_id: str = ""
side: TradeSide = TradeSide.FLAT
asset: str = ""
price: float = 0.0 # avg fill price
size: float = 0.0
filled_size: float = 0.0
remaining_size: float = 0.0
reason: str = ""
raw_payload: Dict[str, Any] = field(default_factory=dict)
metadata: Dict[str, Any] = field(default_factory=dict)
# ── Fee / friction fields ──────────────────────────────────────────────
# fee: exchange commission for this fill event.
# Positive = cost; negative = rebate (maker on some venues).
# Starts as ESTIMATED_TAKER from the REST ACK path (BingX ACK does not
# include commission — we estimate from fill_size × fill_price × rate).
# Updated to WS_SETTLED when the FILL_SETTLED event arrives from the
# account stream with the actual commission field "n".
fee: float = 0.0
fee_asset: str = "" # e.g. "USDT"
# fee_source provenance codes:
# "" — fee unknown (e.g. CANCEL_ACK, ORDER_ACK events)
# "ESTIMATED_TAKER" — REST path, MARKET order; estimated at taker rate
# "ESTIMATED_MAKER" — REST path, LIMIT order that may rest; estimated at maker rate
# "WS_SETTLED" — actual fee from WS ORDER_TRADE_UPDATE field "n"
# "REST_SETTLED" — actual fee from REST fill history (allFillOrders)
fee_source: str = ""
is_maker: bool = False # True when LIMIT order rested and filled as maker
# exchange_ts: exchange-assigned fill timestamp (ms epoch).
# 0 when not available (REST ACK path — use VenueEvent.timestamp as fallback).
# Non-zero from WS ORDER_TRADE_UPDATE (field "T" or "t").
exchange_ts: int = 0
# slippage_bps: signed fill-quality metric.
# For taker fills: (fill_price - mark_at_submit) / mark_at_submit × 10_000
# positive = worse than mark (usual for taker on moving markets)
# negative = better than mark (rare — mark moved in our favour between submit and fill)
# For maker fills: fill_price is better than mid by design; slippage is typically
# negative (price improvement vs what a taker would have paid).
# 0.0 when mark_at_submit is unavailable.
slippage_bps: float = 0.0
mark_at_submit: float = 0.0 # mark/mid price captured just before submit_intent POST
@dataclass(frozen=True)
class KernelTransition:
"""Durable kernel transition used for debug journaling."""
timestamp: datetime
trade_id: str
slot_id: int
prev_state: TradeStage
next_state: TradeStage
trigger: str
intent_id: str = ""
event_id: str = ""
control_mode: str = ""
control_verbosity: str = ""
details: Dict[str, Any] = field(default_factory=dict)
@dataclass(frozen=True)
class KernelOutcome:
"""Result of applying a command or venue event."""
accepted: bool
slot_id: int
trade_id: str
state: TradeStage
diagnostic_code: KernelDiagnosticCode = KernelDiagnosticCode.OK
severity: KernelSeverity = KernelSeverity.INFO
transitions: Tuple[KernelTransition, ...] = ()
emitted_events: Tuple[VenueEvent, ...] = ()
details: Dict[str, Any] = field(default_factory=dict)