mirror of
https://github.com/xavierchuan/FX-ML-Trading-Engine.git
synced 2026-07-28 10:37:44 +00:00
103 lines
2.4 KiB
Python
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
|