"""Venue adapter contracts for DITAv2.""" from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime from typing import Any, AsyncIterator, Dict, List, Optional, Protocol from .contracts import ( KernelCommandType, KernelIntent, KernelEventKind, TradeSide, VenueEvent, VenueEventStatus, VenueOrder, VenueOrderStatus, ) from .exchange_event import ExchangeEvent class VenueAdapter(Protocol): """Abstract venue adapter used by the kernel.""" def submit(self, intent: KernelIntent) -> List[VenueEvent]: ... def cancel(self, order: VenueOrder, *, reason: str = "") -> List[VenueEvent]: ... def open_orders(self) -> List[VenueOrder]: ... def open_positions(self) -> List[Dict[str, Any]]: ... def reconcile(self) -> List[VenueEvent]: ... # ------------------------------------------------------------------ # Phase 2 — stream seam (spec G3) # ------------------------------------------------------------------ async def subscribe(self) -> AsyncIterator[ExchangeEvent]: """ Yield ExchangeEvent instances in arrival order. Implementations must handle reconnection, keepalive, and 24h rotation internally. The iterator never terminates normally — callers cancel it on shutdown. Both the WS and poll-failover paths implement this interface so the kernel layer is source-agnostic. """ ... # pragma: no cover async def account_snapshot(self) -> ExchangeEvent: """ Return a single ACCOUNT_UPDATE + POSITION_UPDATE merged event by calling the exchange REST API. Used for gap-backfill on reconnect and as the poll-failover path. """ ... # pragma: no cover