COB WS fix
This commit is contained in:
@ -26,6 +26,7 @@ from collections import defaultdict
|
||||
|
||||
from .multi_exchange_cob_provider import MultiExchangeCOBProvider, COBSnapshot, ConsolidatedOrderBookLevel
|
||||
from .data_provider import DataProvider, MarketTick
|
||||
from .enhanced_cob_websocket import EnhancedCOBWebSocket
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -48,6 +49,9 @@ class COBIntegration:
|
||||
# Initialize COB provider to None, will be set in start()
|
||||
self.cob_provider = None
|
||||
|
||||
# Enhanced WebSocket integration
|
||||
self.enhanced_websocket: Optional[EnhancedCOBWebSocket] = None
|
||||
|
||||
# CNN/DQN integration
|
||||
self.cnn_callbacks: List[Callable] = []
|
||||
self.dqn_callbacks: List[Callable] = []
|
||||
@ -62,43 +66,187 @@ class COBIntegration:
|
||||
self.cob_feature_cache: Dict[str, np.ndarray] = {}
|
||||
self.last_cob_features_update: Dict[str, datetime] = {}
|
||||
|
||||
# WebSocket status for dashboard
|
||||
self.websocket_status: Dict[str, str] = {symbol: 'disconnected' for symbol in self.symbols}
|
||||
|
||||
# Initialize signal tracking
|
||||
for symbol in self.symbols:
|
||||
self.cob_signals[symbol] = []
|
||||
self.liquidity_alerts[symbol] = []
|
||||
self.arbitrage_opportunities[symbol] = []
|
||||
|
||||
logger.info("COB Integration initialized (provider will be started in async)")
|
||||
logger.info("COB Integration initialized with Enhanced WebSocket support")
|
||||
logger.info(f"Symbols: {self.symbols}")
|
||||
|
||||
async def start(self):
|
||||
"""Start COB integration"""
|
||||
logger.info("Starting COB Integration")
|
||||
"""Start COB integration with Enhanced WebSocket"""
|
||||
logger.info("🚀 Starting COB Integration with Enhanced WebSocket")
|
||||
|
||||
# Initialize COB provider here, within the async context
|
||||
self.cob_provider = MultiExchangeCOBProvider(
|
||||
symbols=self.symbols,
|
||||
bucket_size_bps=1.0 # 1 basis point granularity
|
||||
)
|
||||
|
||||
# Register callbacks
|
||||
self.cob_provider.subscribe_to_cob_updates(self._on_cob_update)
|
||||
self.cob_provider.subscribe_to_bucket_updates(self._on_bucket_update)
|
||||
|
||||
# Start COB provider streaming
|
||||
# Initialize Enhanced WebSocket first
|
||||
try:
|
||||
logger.info("Starting COB provider streaming...")
|
||||
await self.cob_provider.start_streaming()
|
||||
self.enhanced_websocket = EnhancedCOBWebSocket(
|
||||
symbols=self.symbols,
|
||||
dashboard_callback=self._on_websocket_status_update
|
||||
)
|
||||
|
||||
# Add COB data callback
|
||||
self.enhanced_websocket.add_cob_callback(self._on_enhanced_cob_update)
|
||||
|
||||
# Start enhanced WebSocket
|
||||
await self.enhanced_websocket.start()
|
||||
logger.info("✅ Enhanced WebSocket started successfully")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error starting COB provider streaming: {e}")
|
||||
# Start a background task instead
|
||||
logger.error(f"❌ Error starting Enhanced WebSocket: {e}")
|
||||
|
||||
# Initialize COB provider as fallback
|
||||
try:
|
||||
self.cob_provider = MultiExchangeCOBProvider(
|
||||
symbols=self.symbols,
|
||||
bucket_size_bps=1.0 # 1 basis point granularity
|
||||
)
|
||||
|
||||
# Register callbacks
|
||||
self.cob_provider.subscribe_to_cob_updates(self._on_cob_update)
|
||||
self.cob_provider.subscribe_to_bucket_updates(self._on_bucket_update)
|
||||
|
||||
# Start COB provider streaming as backup
|
||||
logger.info("Starting COB provider as backup...")
|
||||
asyncio.create_task(self._start_cob_provider_background())
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error initializing COB provider: {e}")
|
||||
|
||||
# Start analysis threads
|
||||
asyncio.create_task(self._continuous_cob_analysis())
|
||||
asyncio.create_task(self._continuous_signal_generation())
|
||||
|
||||
logger.info("COB Integration started successfully")
|
||||
logger.info("✅ COB Integration started successfully with Enhanced WebSocket")
|
||||
|
||||
async def _on_enhanced_cob_update(self, symbol: str, cob_data: Dict):
|
||||
"""Handle COB updates from Enhanced WebSocket"""
|
||||
try:
|
||||
logger.debug(f"📊 Enhanced WebSocket COB update for {symbol}")
|
||||
|
||||
# Convert enhanced WebSocket data to COB format for existing callbacks
|
||||
# Notify CNN callbacks
|
||||
for callback in self.cnn_callbacks:
|
||||
try:
|
||||
callback(symbol, {
|
||||
'features': cob_data,
|
||||
'timestamp': cob_data.get('timestamp', datetime.now()),
|
||||
'type': 'enhanced_cob_features'
|
||||
})
|
||||
except Exception as e:
|
||||
logger.warning(f"Error in CNN callback: {e}")
|
||||
|
||||
# Notify DQN callbacks
|
||||
for callback in self.dqn_callbacks:
|
||||
try:
|
||||
callback(symbol, {
|
||||
'state': cob_data,
|
||||
'timestamp': cob_data.get('timestamp', datetime.now()),
|
||||
'type': 'enhanced_cob_state'
|
||||
})
|
||||
except Exception as e:
|
||||
logger.warning(f"Error in DQN callback: {e}")
|
||||
|
||||
# Notify dashboard callbacks
|
||||
dashboard_data = self._format_enhanced_cob_for_dashboard(symbol, cob_data)
|
||||
for callback in self.dashboard_callbacks:
|
||||
try:
|
||||
if asyncio.iscoroutinefunction(callback):
|
||||
asyncio.create_task(callback(symbol, dashboard_data))
|
||||
else:
|
||||
callback(symbol, dashboard_data)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error in dashboard callback: {e}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing Enhanced WebSocket COB update for {symbol}: {e}")
|
||||
|
||||
async def _on_websocket_status_update(self, status_data: Dict):
|
||||
"""Handle WebSocket status updates for dashboard"""
|
||||
try:
|
||||
symbol = status_data.get('symbol')
|
||||
status = status_data.get('status')
|
||||
message = status_data.get('message', '')
|
||||
|
||||
if symbol:
|
||||
self.websocket_status[symbol] = status
|
||||
logger.info(f"🔌 WebSocket status for {symbol}: {status} - {message}")
|
||||
|
||||
# Notify dashboard callbacks about status change
|
||||
status_update = {
|
||||
'type': 'websocket_status',
|
||||
'data': {
|
||||
'symbol': symbol,
|
||||
'status': status,
|
||||
'message': message,
|
||||
'timestamp': status_data.get('timestamp', datetime.now().isoformat())
|
||||
}
|
||||
}
|
||||
|
||||
for callback in self.dashboard_callbacks:
|
||||
try:
|
||||
if asyncio.iscoroutinefunction(callback):
|
||||
asyncio.create_task(callback(symbol, status_update))
|
||||
else:
|
||||
callback(symbol, status_update)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error in dashboard status callback: {e}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing WebSocket status update: {e}")
|
||||
|
||||
def _format_enhanced_cob_for_dashboard(self, symbol: str, cob_data: Dict) -> Dict:
|
||||
"""Format Enhanced WebSocket COB data for dashboard"""
|
||||
try:
|
||||
# Extract data from enhanced WebSocket format
|
||||
bids = cob_data.get('bids', [])
|
||||
asks = cob_data.get('asks', [])
|
||||
stats = cob_data.get('stats', {})
|
||||
|
||||
# Format for dashboard
|
||||
dashboard_data = {
|
||||
'type': 'cob_update',
|
||||
'data': {
|
||||
'bids': [{'price': bid['price'], 'volume': bid['size'] * bid['price'], 'side': 'bid'} for bid in bids[:100]],
|
||||
'asks': [{'price': ask['price'], 'volume': ask['size'] * ask['price'], 'side': 'ask'} for ask in asks[:100]],
|
||||
'svp': [], # SVP data not available from WebSocket
|
||||
'stats': {
|
||||
'symbol': symbol,
|
||||
'timestamp': cob_data.get('timestamp', datetime.now()).isoformat() if isinstance(cob_data.get('timestamp'), datetime) else cob_data.get('timestamp', datetime.now().isoformat()),
|
||||
'mid_price': stats.get('mid_price', 0),
|
||||
'spread_bps': (stats.get('spread', 0) / stats.get('mid_price', 1)) * 10000 if stats.get('mid_price', 0) > 0 else 0,
|
||||
'bid_liquidity': stats.get('bid_volume', 0) * stats.get('best_bid', 0),
|
||||
'ask_liquidity': stats.get('ask_volume', 0) * stats.get('best_ask', 0),
|
||||
'total_bid_liquidity': stats.get('bid_volume', 0) * stats.get('best_bid', 0),
|
||||
'total_ask_liquidity': stats.get('ask_volume', 0) * stats.get('best_ask', 0),
|
||||
'imbalance': (stats.get('bid_volume', 0) - stats.get('ask_volume', 0)) / (stats.get('bid_volume', 0) + stats.get('ask_volume', 0)) if (stats.get('bid_volume', 0) + stats.get('ask_volume', 0)) > 0 else 0,
|
||||
'liquidity_imbalance': (stats.get('bid_volume', 0) - stats.get('ask_volume', 0)) / (stats.get('bid_volume', 0) + stats.get('ask_volume', 0)) if (stats.get('bid_volume', 0) + stats.get('ask_volume', 0)) > 0 else 0,
|
||||
'bid_levels': len(bids),
|
||||
'ask_levels': len(asks),
|
||||
'exchanges_active': [cob_data.get('exchange', 'binance')],
|
||||
'bucket_size': 1.0,
|
||||
'websocket_status': self.websocket_status.get(symbol, 'unknown'),
|
||||
'source': cob_data.get('source', 'enhanced_websocket')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dashboard_data
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error formatting enhanced COB data for dashboard: {e}")
|
||||
return {
|
||||
'type': 'error',
|
||||
'data': {'error': str(e)}
|
||||
}
|
||||
|
||||
def get_websocket_status(self) -> Dict[str, str]:
|
||||
"""Get current WebSocket status for all symbols"""
|
||||
return self.websocket_status.copy()
|
||||
|
||||
async def _start_cob_provider_background(self):
|
||||
"""Start COB provider in background task"""
|
||||
|
Reference in New Issue
Block a user