more cobfixes

This commit is contained in:
Dobromir Popov
2025-08-08 19:15:16 +03:00
parent be1753c96a
commit 71ba37ccc2
4 changed files with 101 additions and 13 deletions

View File

@ -4386,11 +4386,11 @@ class DataProvider:
# Ensure symbol keys exist in the dictionary with proper deque initialization
for sym in ['ETH/USDT', 'BTC/USDT']:
if sym not in self.cob_raw_ticks:
# Use deque with maxlen for automatic size management (15 min at ~100 ticks/sec)
self.cob_raw_ticks[sym] = deque(maxlen=90000)
# Use deque with maxlen for automatic size management (30 min at ~100 ticks/sec)
self.cob_raw_ticks[sym] = deque(maxlen=180000)
if sym not in self.cob_1s_aggregated:
# 1s aggregated: 15 minutes = 900 seconds
self.cob_1s_aggregated[sym] = deque(maxlen=900)
# 1s aggregated: 30 minutes = 1800 seconds
self.cob_1s_aggregated[sym] = deque(maxlen=1800)
# Add to raw ticks - deque automatically handles size limit with maxlen
self.cob_raw_ticks[symbol].append(cob_data)
@ -4452,7 +4452,7 @@ class DataProvider:
elif not isinstance(self.cob_data_cache[symbol], (list, deque)):
self.cob_data_cache[symbol] = []
self.cob_data_cache[symbol].append(standard_cob_data)
if len(self.cob_data_cache[symbol]) > 300: # Keep 5 minutes
if len(self.cob_data_cache[symbol]) > 1800: # Keep 30 minutes
self.cob_data_cache[symbol].pop(0)
# Notify subscribers

View File

@ -341,10 +341,31 @@ def save_inference_audit_image(base_data, model_name: str, symbol: str, out_root
ax6 = fig.add_subplot(gs[1, 2])
_plot_data_summary(ax6, base_data, symbol)
# COB data (bottom, spanning all columns)
# COB data (bottom, spanning all columns) with optional heatmap overlay above it
ax7 = fig.add_subplot(gs[2, :])
_plot_cob_data(ax7, prices, bid_v, ask_v, imb, current_price, symbol)
# Optional: append a small heatmap figure to the side if available
try:
heat_times = getattr(base_data, 'cob_heatmap_times', [])
heat_prices = getattr(base_data, 'cob_heatmap_prices', [])
heat_vals = getattr(base_data, 'cob_heatmap_values', [])
if heat_times and heat_prices and heat_vals:
import numpy as np
# Create an inset axes on ax7 for compact heatmap
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
inset_ax = inset_axes(ax7, width="25%", height="100%", loc='upper right', borderpad=1)
z = np.array(heat_vals, dtype=float)
if z.size > 0:
col_max = np.maximum(z.max(axis=0), 1e-9)
zn = (z / col_max).T
inset_ax.imshow(zn, aspect='auto', origin='lower', cmap='turbo')
inset_ax.set_title('COB Heatmap', fontsize=8)
inset_ax.set_xticks([])
inset_ax.set_yticks([])
except Exception as _hm_ex:
logger.debug(f"Audit heatmap overlay skipped: {_hm_ex}")
# Add overall title with model and timestamp info
fig.suptitle(f"{model_name} - {safe_symbol} - {datetime.utcnow().strftime('%H:%M:%S')}",
fontsize=14, fontweight='bold')

View File

@ -1487,6 +1487,70 @@ class CleanTradingDashboard:
fig.update_layout(margin=dict(l=10, r=10, t=20, b=10))
return fig
@self.app.callback(
Output('cob-heatmap-btc', 'figure'),
[Input('interval-component', 'n_intervals')]
)
def update_cob_heatmap_btc(n):
try:
times, prices, matrix = [], [], []
if hasattr(self.data_provider, 'get_cob_heatmap_matrix'):
times, prices, matrix, mids = self.data_provider.get_cob_heatmap_matrix(
'BTC/USDT', seconds=300, bucket_radius=10, metric='liquidity'
)
if not times or not prices or not matrix:
fig = go.Figure()
fig.add_annotation(text="No COB heatmap data", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
fig.update_layout(margin=dict(l=10, r=10, t=20, b=10))
return fig
z = np.array(matrix, dtype=float)
col_max = np.maximum(z.max(axis=0), 1e-9)
zn = z / col_max
fig = go.Figure(data=go.Heatmap(
z=zn.T,
x=[t.strftime('%H:%M:%S') for t in times],
y=[f"{p:.2f}" for p in prices],
colorscale='Turbo',
colorbar=dict(title='Norm'),
zmin=0.0,
zmax=1.0
))
try:
bucket_size = abs(prices[1] - prices[0]) if len(prices) > 1 else 1.0
price_line = mids if 'mids' in locals() and mids else []
if price_line:
y_vals = []
y_labels = [float(p) for p in prices]
for m in price_line:
if m and bucket_size > 0:
idx = int(round((m - y_labels[0]) / bucket_size))
idx = max(0, min(len(y_labels) - 1, idx))
y_vals.append(y_labels[idx])
else:
y_vals.append(None)
fig.add_trace(go.Scatter(
x=[t.strftime('%H:%M:%S') for t in times],
y=[f"{yv:.2f}" if yv is not None else None for yv in y_vals],
mode='lines',
line=dict(color='white', width=1.5),
name='Mid Price'
))
except Exception as _line_ex:
logger.debug(f"Price line overlay skipped: {_line_ex}")
fig.update_layout(
title="BTC COB Heatmap (liquidity, per-bucket normalized)",
xaxis_title="Time",
yaxis_title="Price",
margin=dict(l=10, r=10, t=30, b=10)
)
return fig
except Exception as e:
logger.error(f"Error rendering BTC COB heatmap: {e}")
fig = go.Figure()
fig.add_annotation(text=f"Heatmap Error: {str(e)}", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
fig.update_layout(margin=dict(l=10, r=10, t=20, b=10))
return fig
# Original training metrics callback - temporarily disabled for testing
# @self.app.callback(
# Output('training-metrics', 'children'),

View File

@ -410,15 +410,18 @@ class DashboardLayoutManager:
], style={"width": "38%", "marginLeft": "2%"}),
], className="d-flex mb-3"),
# COB Heatmap (ETH)
# Mini COB Heatmaps (ETH and BTC)
html.Div([
html.Div([
html.H6([
html.I(className="fas fa-fire me-2"),
"ETH/USDT COB Heatmap (last 5m, ±10 buckets)"
], className="card-title mb-2"),
dcc.Graph(id='cob-heatmap-eth', config={'displayModeBar': False}, style={"height": "300px"})
], className="card-body p-2")
html.Div([
html.H6([html.I(className="fas fa-fire me-2"), "ETH Heatmap"], className="card-title mb-2"),
dcc.Graph(id='cob-heatmap-eth', config={'displayModeBar': False}, style={"height": "220px"})
], className="card-body p-2", style={"flex": "1"}),
html.Div([
html.H6([html.I(className="fas fa-fire me-2"), "BTC Heatmap"], className="card-title mb-2"),
dcc.Graph(id='cob-heatmap-btc', config={'displayModeBar': False}, style={"height": "220px"})
], className="card-body p-2", style={"flex": "1", "marginLeft": "1rem"})
], className="d-flex")
], className="card"),
# Second row: Pending Orders (left) and Closed Trades (right)