more cobfixes
This commit is contained in:
@ -4386,11 +4386,11 @@ class DataProvider:
|
|||||||
# Ensure symbol keys exist in the dictionary with proper deque initialization
|
# Ensure symbol keys exist in the dictionary with proper deque initialization
|
||||||
for sym in ['ETH/USDT', 'BTC/USDT']:
|
for sym in ['ETH/USDT', 'BTC/USDT']:
|
||||||
if sym not in self.cob_raw_ticks:
|
if sym not in self.cob_raw_ticks:
|
||||||
# Use deque with maxlen for automatic size management (15 min at ~100 ticks/sec)
|
# Use deque with maxlen for automatic size management (30 min at ~100 ticks/sec)
|
||||||
self.cob_raw_ticks[sym] = deque(maxlen=90000)
|
self.cob_raw_ticks[sym] = deque(maxlen=180000)
|
||||||
if sym not in self.cob_1s_aggregated:
|
if sym not in self.cob_1s_aggregated:
|
||||||
# 1s aggregated: 15 minutes = 900 seconds
|
# 1s aggregated: 30 minutes = 1800 seconds
|
||||||
self.cob_1s_aggregated[sym] = deque(maxlen=900)
|
self.cob_1s_aggregated[sym] = deque(maxlen=1800)
|
||||||
|
|
||||||
# Add to raw ticks - deque automatically handles size limit with maxlen
|
# Add to raw ticks - deque automatically handles size limit with maxlen
|
||||||
self.cob_raw_ticks[symbol].append(cob_data)
|
self.cob_raw_ticks[symbol].append(cob_data)
|
||||||
@ -4452,7 +4452,7 @@ class DataProvider:
|
|||||||
elif not isinstance(self.cob_data_cache[symbol], (list, deque)):
|
elif not isinstance(self.cob_data_cache[symbol], (list, deque)):
|
||||||
self.cob_data_cache[symbol] = []
|
self.cob_data_cache[symbol] = []
|
||||||
self.cob_data_cache[symbol].append(standard_cob_data)
|
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)
|
self.cob_data_cache[symbol].pop(0)
|
||||||
|
|
||||||
# Notify subscribers
|
# Notify subscribers
|
||||||
|
@ -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])
|
ax6 = fig.add_subplot(gs[1, 2])
|
||||||
_plot_data_summary(ax6, base_data, symbol)
|
_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, :])
|
ax7 = fig.add_subplot(gs[2, :])
|
||||||
_plot_cob_data(ax7, prices, bid_v, ask_v, imb, current_price, symbol)
|
_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
|
# Add overall title with model and timestamp info
|
||||||
fig.suptitle(f"{model_name} - {safe_symbol} - {datetime.utcnow().strftime('%H:%M:%S')}",
|
fig.suptitle(f"{model_name} - {safe_symbol} - {datetime.utcnow().strftime('%H:%M:%S')}",
|
||||||
fontsize=14, fontweight='bold')
|
fontsize=14, fontweight='bold')
|
||||||
|
@ -1487,6 +1487,70 @@ class CleanTradingDashboard:
|
|||||||
fig.update_layout(margin=dict(l=10, r=10, t=20, b=10))
|
fig.update_layout(margin=dict(l=10, r=10, t=20, b=10))
|
||||||
return fig
|
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
|
# Original training metrics callback - temporarily disabled for testing
|
||||||
# @self.app.callback(
|
# @self.app.callback(
|
||||||
# Output('training-metrics', 'children'),
|
# Output('training-metrics', 'children'),
|
||||||
|
@ -410,15 +410,18 @@ class DashboardLayoutManager:
|
|||||||
], style={"width": "38%", "marginLeft": "2%"}),
|
], style={"width": "38%", "marginLeft": "2%"}),
|
||||||
], className="d-flex mb-3"),
|
], className="d-flex mb-3"),
|
||||||
|
|
||||||
# COB Heatmap (ETH)
|
# Mini COB Heatmaps (ETH and BTC)
|
||||||
html.Div([
|
html.Div([
|
||||||
html.Div([
|
html.Div([
|
||||||
html.H6([
|
html.Div([
|
||||||
html.I(className="fas fa-fire me-2"),
|
html.H6([html.I(className="fas fa-fire me-2"), "ETH Heatmap"], className="card-title mb-2"),
|
||||||
"ETH/USDT COB Heatmap (last 5m, ±10 buckets)"
|
dcc.Graph(id='cob-heatmap-eth', config={'displayModeBar': False}, style={"height": "220px"})
|
||||||
], className="card-title mb-2"),
|
], className="card-body p-2", style={"flex": "1"}),
|
||||||
dcc.Graph(id='cob-heatmap-eth', config={'displayModeBar': False}, style={"height": "300px"})
|
html.Div([
|
||||||
], className="card-body p-2")
|
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"),
|
], className="card"),
|
||||||
|
|
||||||
# Second row: Pending Orders (left) and Closed Trades (right)
|
# Second row: Pending Orders (left) and Closed Trades (right)
|
||||||
|
Reference in New Issue
Block a user