COBY : specs + task 1
This commit is contained in:
189
COBY/interfaces/exchange_connector.py
Normal file
189
COBY/interfaces/exchange_connector.py
Normal file
@ -0,0 +1,189 @@
|
||||
"""
|
||||
Base interface for exchange WebSocket connectors.
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Callable, List, Optional
|
||||
from ..models.core import ConnectionStatus, OrderBookSnapshot, TradeEvent
|
||||
|
||||
|
||||
class ExchangeConnector(ABC):
|
||||
"""Base interface for exchange WebSocket connectors"""
|
||||
|
||||
def __init__(self, exchange_name: str):
|
||||
self.exchange_name = exchange_name
|
||||
self._data_callbacks: List[Callable] = []
|
||||
self._status_callbacks: List[Callable] = []
|
||||
self._connection_status = ConnectionStatus.DISCONNECTED
|
||||
|
||||
@abstractmethod
|
||||
async def connect(self) -> bool:
|
||||
"""
|
||||
Establish connection to the exchange WebSocket.
|
||||
|
||||
Returns:
|
||||
bool: True if connection successful, False otherwise
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def disconnect(self) -> None:
|
||||
"""Disconnect from the exchange WebSocket."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def subscribe_orderbook(self, symbol: str) -> None:
|
||||
"""
|
||||
Subscribe to order book updates for a symbol.
|
||||
|
||||
Args:
|
||||
symbol: Trading symbol (e.g., 'BTCUSDT')
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def subscribe_trades(self, symbol: str) -> None:
|
||||
"""
|
||||
Subscribe to trade updates for a symbol.
|
||||
|
||||
Args:
|
||||
symbol: Trading symbol (e.g., 'BTCUSDT')
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def unsubscribe_orderbook(self, symbol: str) -> None:
|
||||
"""
|
||||
Unsubscribe from order book updates for a symbol.
|
||||
|
||||
Args:
|
||||
symbol: Trading symbol (e.g., 'BTCUSDT')
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def unsubscribe_trades(self, symbol: str) -> None:
|
||||
"""
|
||||
Unsubscribe from trade updates for a symbol.
|
||||
|
||||
Args:
|
||||
symbol: Trading symbol (e.g., 'BTCUSDT')
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_connection_status(self) -> ConnectionStatus:
|
||||
"""
|
||||
Get current connection status.
|
||||
|
||||
Returns:
|
||||
ConnectionStatus: Current connection status
|
||||
"""
|
||||
return self._connection_status
|
||||
|
||||
def add_data_callback(self, callback: Callable) -> None:
|
||||
"""
|
||||
Add callback for data updates.
|
||||
|
||||
Args:
|
||||
callback: Function to call when data is received
|
||||
Signature: callback(data: Union[OrderBookSnapshot, TradeEvent])
|
||||
"""
|
||||
if callback not in self._data_callbacks:
|
||||
self._data_callbacks.append(callback)
|
||||
|
||||
def remove_data_callback(self, callback: Callable) -> None:
|
||||
"""
|
||||
Remove data callback.
|
||||
|
||||
Args:
|
||||
callback: Callback function to remove
|
||||
"""
|
||||
if callback in self._data_callbacks:
|
||||
self._data_callbacks.remove(callback)
|
||||
|
||||
def add_status_callback(self, callback: Callable) -> None:
|
||||
"""
|
||||
Add callback for status updates.
|
||||
|
||||
Args:
|
||||
callback: Function to call when status changes
|
||||
Signature: callback(exchange: str, status: ConnectionStatus)
|
||||
"""
|
||||
if callback not in self._status_callbacks:
|
||||
self._status_callbacks.append(callback)
|
||||
|
||||
def remove_status_callback(self, callback: Callable) -> None:
|
||||
"""
|
||||
Remove status callback.
|
||||
|
||||
Args:
|
||||
callback: Callback function to remove
|
||||
"""
|
||||
if callback in self._status_callbacks:
|
||||
self._status_callbacks.remove(callback)
|
||||
|
||||
def _notify_data_callbacks(self, data):
|
||||
"""Notify all data callbacks of new data."""
|
||||
for callback in self._data_callbacks:
|
||||
try:
|
||||
callback(data)
|
||||
except Exception as e:
|
||||
# Log error but don't stop other callbacks
|
||||
print(f"Error in data callback: {e}")
|
||||
|
||||
def _notify_status_callbacks(self, status: ConnectionStatus):
|
||||
"""Notify all status callbacks of status change."""
|
||||
self._connection_status = status
|
||||
for callback in self._status_callbacks:
|
||||
try:
|
||||
callback(self.exchange_name, status)
|
||||
except Exception as e:
|
||||
# Log error but don't stop other callbacks
|
||||
print(f"Error in status callback: {e}")
|
||||
|
||||
@abstractmethod
|
||||
async def get_symbols(self) -> List[str]:
|
||||
"""
|
||||
Get list of available trading symbols.
|
||||
|
||||
Returns:
|
||||
List[str]: List of available symbols
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def normalize_symbol(self, symbol: str) -> str:
|
||||
"""
|
||||
Normalize symbol to exchange format.
|
||||
|
||||
Args:
|
||||
symbol: Standard symbol format (e.g., 'BTCUSDT')
|
||||
|
||||
Returns:
|
||||
str: Exchange-specific symbol format
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_orderbook_snapshot(self, symbol: str, depth: int = 20) -> Optional[OrderBookSnapshot]:
|
||||
"""
|
||||
Get current order book snapshot.
|
||||
|
||||
Args:
|
||||
symbol: Trading symbol
|
||||
depth: Number of price levels to retrieve
|
||||
|
||||
Returns:
|
||||
OrderBookSnapshot: Current order book or None if unavailable
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Get exchange name."""
|
||||
return self.exchange_name
|
||||
|
||||
@property
|
||||
def is_connected(self) -> bool:
|
||||
"""Check if connector is connected."""
|
||||
return self._connection_status == ConnectionStatus.CONNECTED
|
Reference in New Issue
Block a user