177 lines
4.1 KiB
Markdown
177 lines
4.1 KiB
Markdown
|
|
# Exchange Integration Architecture
|
||
|
|
|
||
|
|
This document describes how exchange adapters integrate with the trading system.
|
||
|
|
|
||
|
|
## Adapter Pattern
|
||
|
|
|
||
|
|
All exchanges use the adapter pattern to provide a unified interface:
|
||
|
|
|
||
|
|
```
|
||
|
|
Trading Engine
|
||
|
|
│
|
||
|
|
▼
|
||
|
|
BaseExchange (Interface)
|
||
|
|
│
|
||
|
|
├──► CoinbaseExchange
|
||
|
|
├──► BinanceExchange (future)
|
||
|
|
└──► KrakenExchange (future)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Base Exchange Interface
|
||
|
|
|
||
|
|
All exchanges implement `BaseExchange`:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class BaseExchange(ABC):
|
||
|
|
async def connect()
|
||
|
|
async def disconnect()
|
||
|
|
async def fetch_balance()
|
||
|
|
async def place_order()
|
||
|
|
async def cancel_order()
|
||
|
|
async def fetch_order_status()
|
||
|
|
async def fetch_ohlcv()
|
||
|
|
async def subscribe_ohlcv()
|
||
|
|
async def subscribe_trades()
|
||
|
|
async def subscribe_order_book()
|
||
|
|
async def fetch_open_orders()
|
||
|
|
async def fetch_positions()
|
||
|
|
async def fetch_markets()
|
||
|
|
```
|
||
|
|
|
||
|
|
## Exchange Factory
|
||
|
|
|
||
|
|
The factory pattern creates exchange instances:
|
||
|
|
|
||
|
|
```
|
||
|
|
ExchangeFactory
|
||
|
|
│
|
||
|
|
├──► get_exchange(name)
|
||
|
|
│ │
|
||
|
|
│ ├──► Lookup registered adapter
|
||
|
|
│ ├──► Get API keys from KeyManager
|
||
|
|
│ └──► Instantiate adapter
|
||
|
|
│
|
||
|
|
└──► register_exchange(name, adapter_class)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Exchange Registration
|
||
|
|
|
||
|
|
Exchanges are registered at module import:
|
||
|
|
|
||
|
|
```python
|
||
|
|
# In exchange module
|
||
|
|
from src.exchanges.factory import ExchangeFactory
|
||
|
|
|
||
|
|
ExchangeFactory.register_exchange("coinbase", CoinbaseExchange)
|
||
|
|
```
|
||
|
|
|
||
|
|
## CCXT Integration
|
||
|
|
|
||
|
|
Most exchanges use the CCXT library:
|
||
|
|
|
||
|
|
```python
|
||
|
|
import ccxt.pro as ccxt
|
||
|
|
|
||
|
|
class CoinbaseExchange(BaseExchange):
|
||
|
|
def __init__(self, ...):
|
||
|
|
self.exchange = ccxt.coinbaseadvanced({
|
||
|
|
'apiKey': api_key,
|
||
|
|
'secret': secret_key,
|
||
|
|
'enableRateLimit': True,
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
## WebSocket Support
|
||
|
|
|
||
|
|
Real-time data via WebSockets:
|
||
|
|
|
||
|
|
```python
|
||
|
|
async def subscribe_ohlcv(self, symbol, timeframe, callback):
|
||
|
|
"""Subscribe to OHLCV updates."""
|
||
|
|
await self.exchange.watch_ohlcv(symbol, timeframe, callback)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Rate Limiting
|
||
|
|
|
||
|
|
All exchanges respect rate limits:
|
||
|
|
|
||
|
|
- CCXT handles rate limiting automatically
|
||
|
|
- `enableRateLimit: True` in exchange config
|
||
|
|
- Custom rate limiting for non-CCXT exchanges
|
||
|
|
|
||
|
|
## Error Handling
|
||
|
|
|
||
|
|
Exchange-specific error handling:
|
||
|
|
|
||
|
|
```python
|
||
|
|
try:
|
||
|
|
order = await self.exchange.create_order(...)
|
||
|
|
except ccxt.NetworkError as e:
|
||
|
|
# Handle network errors
|
||
|
|
logger.error(f"Network error: {e}")
|
||
|
|
raise
|
||
|
|
except ccxt.ExchangeError as e:
|
||
|
|
# Handle exchange errors
|
||
|
|
logger.error(f"Exchange error: {e}")
|
||
|
|
raise
|
||
|
|
```
|
||
|
|
|
||
|
|
## Connection Management
|
||
|
|
|
||
|
|
- **Connection Pooling**: Reuse connections when possible
|
||
|
|
- **Auto-Reconnect**: Automatic reconnection on disconnect
|
||
|
|
- **Health Monitoring**: Monitor connection health
|
||
|
|
- **Graceful Shutdown**: Properly close connections
|
||
|
|
|
||
|
|
## Adding New Exchanges
|
||
|
|
|
||
|
|
See [Adding Exchanges](../developer/adding_exchanges.md) for detailed guide.
|
||
|
|
|
||
|
|
## Exchange-Specific Features
|
||
|
|
|
||
|
|
Some exchanges have unique features:
|
||
|
|
|
||
|
|
- **Coinbase**: Requires passphrase for some operations
|
||
|
|
- **Binance**: Futures and margin trading
|
||
|
|
- **Kraken**: Different order types
|
||
|
|
|
||
|
|
These are handled in exchange-specific adapters.
|
||
|
|
|
||
|
|
## WebSocket Implementation
|
||
|
|
|
||
|
|
### Coinbase WebSocket Support
|
||
|
|
|
||
|
|
The Coinbase adapter includes WebSocket subscription methods:
|
||
|
|
|
||
|
|
- **subscribe_ticker()**: Subscribe to real-time price updates
|
||
|
|
- **subscribe_orderbook()**: Subscribe to order book changes
|
||
|
|
- **subscribe_trades()**: Subscribe to trade executions
|
||
|
|
|
||
|
|
### WebSocket Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
Exchange WebSocket API
|
||
|
|
↓
|
||
|
|
CoinbaseAdapter.subscribe_*()
|
||
|
|
↓
|
||
|
|
Callback Functions
|
||
|
|
↓
|
||
|
|
DataCollector (with signals)
|
||
|
|
↓
|
||
|
|
UI Widgets (via signals)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Reconnection Strategy
|
||
|
|
|
||
|
|
- Automatic reconnection on disconnect
|
||
|
|
- Message queuing during disconnection
|
||
|
|
- Heartbeat/ping-pong for connection health
|
||
|
|
- Fallback to polling if WebSocket unavailable
|
||
|
|
|
||
|
|
### Implementation Notes
|
||
|
|
|
||
|
|
- Uses `websockets` library for async WebSocket connections
|
||
|
|
- Callbacks are wrapped to emit Qt signals for UI updates
|
||
|
|
- Basic implementation provided; can be extended for full Coinbase Advanced Trade WebSocket API
|
||
|
|
|