Files
siloqy/prod/clean_arch/ports/execution.py

75 lines
2.2 KiB
Python
Raw Normal View History

"""Execution port for DITA-driven live trading.
This port is intentionally free of Nautilus Trader node concepts.
It provides a direct exchange boundary for PINK/BLUE-compatible DITA runtimes.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Dict, Optional
@dataclass(frozen=True)
class ExchangeStateSnapshot:
"""Exchange-led account/position/order snapshot."""
timestamp: datetime
capital: float
equity: float
open_positions: Dict[str, Dict[str, Any]] = field(default_factory=dict)
open_orders: list[Dict[str, Any]] = field(default_factory=list)
all_orders: list[Dict[str, Any]] = field(default_factory=list)
all_fills: list[Dict[str, Any]] = field(default_factory=list)
account: Dict[str, Any] = field(default_factory=dict)
open_notional: float = 0.0
source: str = "exchange"
recovered: bool = False
@dataclass(frozen=True)
class ExecutionReceipt:
"""Canonical receipt returned by a direct execution adapter."""
timestamp: datetime
status: str
symbol: str
side: str
action: str
quantity: float
price: float
client_order_id: str
order_id: str = ""
realized_pnl: float = 0.0
fees: float = 0.0
raw_ack: Dict[str, Any] = field(default_factory=dict)
raw_state: Dict[str, Any] = field(default_factory=dict)
class ExecutionPort(ABC):
"""Direct exchange execution boundary."""
@abstractmethod
async def connect(self) -> bool:
raise NotImplementedError
@abstractmethod
async def disconnect(self) -> None:
raise NotImplementedError
@abstractmethod
async def refresh_state(self, symbol: str | None = None, *, include_history: bool = False) -> ExchangeStateSnapshot:
raise NotImplementedError
@abstractmethod
async def submit_intent(self, intent: Any) -> ExecutionReceipt:
raise NotImplementedError
@abstractmethod
async def reconcile(self, symbol: str | None = None) -> ExchangeStateSnapshot:
"""Recovery-only path for catastrophic restart/hibernate scenarios."""
raise NotImplementedError