cob ma data for models

This commit is contained in:
Dobromir Popov
2025-09-09 02:07:04 +03:00
parent 317c703ea0
commit 729e0bccb1
3 changed files with 132 additions and 11 deletions

View File

@@ -166,8 +166,14 @@ class CleanTradingDashboard:
self.cob_update_count = 0
self.last_cob_broadcast: dict = {} # Rate limiting for UI updates
self.cob_data_history: Dict[str, deque] = {
'ETH/USDT': deque(maxlen=61), # Store ~60 seconds of 1s snapshots
'BTC/USDT': deque(maxlen=61)
'ETH/USDT': deque(maxlen=120), # Store ~120 seconds of 1s snapshots for MA calculations
'BTC/USDT': deque(maxlen=120)
}
# COB imbalance moving averages for different timeframes
self.cob_imbalance_ma: Dict[str, Dict[str, float]] = {
'ETH/USDT': {},
'BTC/USDT': {}
}
# Initialize timezone
@@ -314,9 +320,14 @@ class CleanTradingDashboard:
# Get COB data from orchestrator
cob_data = self._get_cob_data_with_buckets(symbol, limit)
# Add COB imbalance moving averages
cob_imbalance_mas = self.cob_imbalance_ma.get(symbol, {})
return jsonify({
'symbol': symbol,
'data': cob_data,
'cob_imbalance_ma': cob_imbalance_mas,
'timestamp': datetime.now().isoformat()
})
except Exception as e:
@@ -1183,8 +1194,12 @@ class CleanTradingDashboard:
# Determine COB data source mode
cob_mode = self._get_cob_mode()
eth_components = self.component_manager.format_cob_data(eth_snapshot, 'ETH/USDT', eth_imbalance_stats, cob_mode)
btc_components = self.component_manager.format_cob_data(btc_snapshot, 'BTC/USDT', btc_imbalance_stats, cob_mode)
# Get COB imbalance moving averages
eth_ma_data = self.cob_imbalance_ma.get('ETH/USDT', {})
btc_ma_data = self.cob_imbalance_ma.get('BTC/USDT', {})
eth_components = self.component_manager.format_cob_data(eth_snapshot, 'ETH/USDT', eth_imbalance_stats, cob_mode, eth_ma_data)
btc_components = self.component_manager.format_cob_data(btc_snapshot, 'BTC/USDT', btc_imbalance_stats, cob_mode, btc_ma_data)
return eth_components, btc_components
@@ -5170,10 +5185,11 @@ class CleanTradingDashboard:
}
}
# Store in history (keep last 15 seconds)
# Store in history (keep last 120 seconds for MA calculations)
self.cob_data_history[symbol].append(cob_snapshot)
if len(self.cob_data_history[symbol]) > 15: # Keep 15 seconds
self.cob_data_history[symbol] = self.cob_data_history[symbol][-15:]
# Calculate COB imbalance moving averages for different timeframes
self._calculate_cob_imbalance_mas(symbol)
# Update latest data
self.latest_cob_data[symbol] = cob_snapshot
@@ -5189,7 +5205,41 @@ class CleanTradingDashboard:
except Exception as e:
logger.debug(f"Error collecting COB data for {symbol}: {e}")
def _calculate_cob_imbalance_mas(self, symbol: str):
"""Calculate COB imbalance moving averages for different timeframes"""
try:
history = self.cob_data_history[symbol]
if len(history) < 2:
return
# Extract imbalance values from history
imbalances = [snapshot['stats']['imbalance'] for snapshot in history if 'stats' in snapshot and 'imbalance' in snapshot['stats']]
if not imbalances:
return
# Calculate moving averages for different timeframes
timeframes = {
'10s': min(10, len(imbalances)), # 10 second MA
'30s': min(30, len(imbalances)), # 30 second MA
'60s': min(60, len(imbalances)), # 60 second MA
}
for timeframe, periods in timeframes.items():
if len(imbalances) >= periods:
# Calculate simple moving average
ma_value = sum(imbalances[-periods:]) / periods
self.cob_imbalance_ma[symbol][timeframe] = ma_value
else:
# If not enough data, use current imbalance
self.cob_imbalance_ma[symbol][timeframe] = imbalances[-1]
logger.debug(f"COB imbalance MAs for {symbol}: {self.cob_imbalance_ma[symbol]}")
except Exception as e:
logger.debug(f"Error calculating COB imbalance MAs for {symbol}: {e}")
def _generate_bucketed_cob_data(self, symbol: str, cob_snapshot: dict):
"""Generate bucketed COB data for model feeding"""
try:

View File

@@ -272,7 +272,7 @@ class DashboardComponentManager:
logger.error(f"Error formatting system status: {e}")
return [html.P(f"Error: {str(e)}", className="text-danger small")]
def format_cob_data(self, cob_snapshot, symbol, cumulative_imbalance_stats=None, cob_mode="Unknown"):
def format_cob_data(self, cob_snapshot, symbol, cumulative_imbalance_stats=None, cob_mode="Unknown", imbalance_ma_data=None):
"""Format COB data into a split view with summary, imbalance stats, and a compact ladder."""
try:
if not cob_snapshot:
@@ -317,7 +317,7 @@ class DashboardComponentManager:
}
# --- Left Panel: Overview and Stats ---
overview_panel = self._create_cob_overview_panel(symbol, stats, cumulative_imbalance_stats, cob_mode)
overview_panel = self._create_cob_overview_panel(symbol, stats, cumulative_imbalance_stats, cob_mode, imbalance_ma_data)
# --- Right Panel: Compact Ladder ---
ladder_panel = self._create_cob_ladder_panel(bids, asks, mid_price, symbol)
@@ -331,7 +331,7 @@ class DashboardComponentManager:
logger.error(f"Error formatting split COB data: {e}")
return html.P(f"Error: {str(e)}", className="text-danger small")
def _create_cob_overview_panel(self, symbol, stats, cumulative_imbalance_stats, cob_mode="Unknown"):
def _create_cob_overview_panel(self, symbol, stats, cumulative_imbalance_stats, cob_mode="Unknown", imbalance_ma_data=None):
"""Creates the left panel with summary and imbalance stats."""
mid_price = stats.get('mid_price', 0)
spread_bps = stats.get('spread_bps', 0)
@@ -373,6 +373,20 @@ class DashboardComponentManager:
html.Div(imbalance_stats_display),
# COB Imbalance Moving Averages
ma_display = []
if imbalance_ma_data:
ma_display.append(html.H6("Imbalance MAs", className="mt-3 mb-2 small text-muted text-uppercase"))
for timeframe, ma_value in imbalance_ma_data.items():
ma_color = "text-success" if ma_value > 0 else "text-danger"
ma_text = f"MA {timeframe}: {ma_value:.3f}"
ma_display.append(html.Div([
html.Strong(f"{timeframe}: ", className="small"),
html.Span(ma_text, className=f"small {ma_color}")
], className="mb-1"))
html.Div(ma_display),
html.Hr(className="my-2"),
html.Table([