Files
2025-11-14 22:56:44 +00:00

103 lines
2.4 KiB
Python

"""Execution adapter interfaces and data models for Phase 3."""
from __future__ import annotations
import abc
from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, Optional
@dataclass
class OrderParams:
symbol: str
side: str # "buy" or "sell"
quantity: float
price: Optional[float] = None
tif: str = "GTC"
client_order_id: Optional[str] = None
metadata: Optional[Dict[str, str]] = None
@dataclass
class OrderAck:
order_id: str
status: str # accepted/rejected
timestamp: datetime
reason: Optional[str] = None
@dataclass
class CancelAck:
order_id: str
status: str
timestamp: datetime
reason: Optional[str] = None
@dataclass
class FillEvent:
order_id: str
fill_id: str
symbol: str
side: str
quantity: float
price: float
timestamp: datetime
@dataclass
class PositionState:
symbol: str
quantity: float
avg_price: float
unrealized_pnl: float = 0.0
class ExecutionAdapter(abc.ABC):
"""Abstract interface for broker/order routing adapters."""
@abc.abstractmethod
def submit(self, order: OrderParams) -> OrderAck:
"""Submit a new order to the venue."""
@abc.abstractmethod
def cancel(self, order_id: str) -> CancelAck:
"""Cancel an existing order."""
@abc.abstractmethod
def sync_positions(self) -> Dict[str, PositionState]:
"""Return latest position snapshot."""
@abc.abstractmethod
def heartbeat(self) -> bool:
"""Quick connectivity check."""
class MockAdapter(ExecutionAdapter):
"""MVP mock adapter used in simulation/testing pipelines."""
def __init__(self):
self._order_counter = 0
self._orders: Dict[str, OrderParams] = {}
def _next_id(self) -> str:
self._order_counter += 1
return f"SIM-{self._order_counter}"
def submit(self, order: OrderParams) -> OrderAck:
order_id = self._next_id()
self._orders[order_id] = order
return OrderAck(order_id=order_id, status="accepted", timestamp=datetime.utcnow())
def cancel(self, order_id: str) -> CancelAck:
status = "cancelled" if order_id in self._orders else "not_found"
self._orders.pop(order_id, None)
return CancelAck(order_id=order_id, status=status, timestamp=datetime.utcnow())
def sync_positions(self) -> Dict[str, PositionState]:
return {}
def heartbeat(self) -> bool:
return True