COB heatmap WIP
This commit is contained in:
@ -1473,7 +1473,7 @@ class CleanTradingDashboard:
|
||||
def update_cob_heatmap_eth(n):
|
||||
"""Render ETH COB 1s heatmap (±10 buckets, last 5 minutes)."""
|
||||
try:
|
||||
# Unified heatmap source from provider
|
||||
# Unified heatmap source from provider (show last 300s)
|
||||
times, prices, matrix = [], [], []
|
||||
if hasattr(self.data_provider, 'get_cob_heatmap_matrix'):
|
||||
times, prices, matrix, mids = self.data_provider.get_cob_heatmap_matrix('ETH/USDT', seconds=300, bucket_radius=10, metric='liquidity')
|
||||
@ -1483,13 +1483,13 @@ class CleanTradingDashboard:
|
||||
fig.update_layout(margin=dict(l=10, r=10, t=20, b=10))
|
||||
return fig
|
||||
z = np.array(matrix, dtype=float)
|
||||
# Normalize per-column for visualization stability (visual only)
|
||||
# Normalize per-time column (visual only) and transpose to [buckets x time]
|
||||
col_max = np.maximum(z.max(axis=0), 1e-9)
|
||||
zn = z / col_max
|
||||
zn = (z / col_max).T
|
||||
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],
|
||||
z=zn,
|
||||
x=times,
|
||||
y=prices,
|
||||
colorscale='Turbo',
|
||||
colorbar=dict(title='Norm'),
|
||||
zmin=0.0,
|
||||
@ -1523,7 +1523,8 @@ class CleanTradingDashboard:
|
||||
fig.update_layout(
|
||||
title="ETH COB Heatmap (liquidity, per-bucket normalized)",
|
||||
xaxis_title="Time",
|
||||
yaxis_title="Price",
|
||||
yaxis_title="Price (USD)",
|
||||
xaxis_type='date',
|
||||
margin=dict(l=10, r=10, t=30, b=10)
|
||||
)
|
||||
return fig
|
||||
@ -1540,7 +1541,7 @@ class CleanTradingDashboard:
|
||||
)
|
||||
def update_cob_heatmap_btc(n):
|
||||
try:
|
||||
# Unified heatmap source from provider
|
||||
# Unified heatmap source from provider (show last 300s)
|
||||
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')
|
||||
@ -1551,11 +1552,11 @@ class CleanTradingDashboard:
|
||||
return fig
|
||||
z = np.array(matrix, dtype=float)
|
||||
col_max = np.maximum(z.max(axis=0), 1e-9)
|
||||
zn = z / col_max
|
||||
zn = (z / col_max).T
|
||||
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],
|
||||
z=zn,
|
||||
x=times,
|
||||
y=prices,
|
||||
colorscale='Turbo',
|
||||
colorbar=dict(title='Norm'),
|
||||
zmin=0.0,
|
||||
@ -1586,7 +1587,8 @@ class CleanTradingDashboard:
|
||||
fig.update_layout(
|
||||
title="BTC COB Heatmap (liquidity, per-bucket normalized)",
|
||||
xaxis_title="Time",
|
||||
yaxis_title="Price",
|
||||
yaxis_title="Price (USD)",
|
||||
xaxis_type='date',
|
||||
margin=dict(l=10, r=10, t=30, b=10)
|
||||
)
|
||||
return fig
|
||||
@ -2189,7 +2191,20 @@ class CleanTradingDashboard:
|
||||
if symbol in self.current_prices and self.current_prices[symbol] > 0:
|
||||
return self.current_prices[symbol]
|
||||
|
||||
# Return None instead of hardcoded fallbacks - let the UI handle missing data
|
||||
# FINAL FALLBACK: Use latest COB mid_price (real data) if available
|
||||
try:
|
||||
if hasattr(self.data_provider, 'get_latest_cob_data'):
|
||||
snap = self.data_provider.get_latest_cob_data(symbol)
|
||||
if snap and isinstance(snap.get('stats'), dict):
|
||||
mid = float(snap['stats'].get('mid_price', 0) or 0)
|
||||
if mid > 0:
|
||||
self.current_prices[symbol] = mid
|
||||
logger.info(f"Using COB mid_price as current price for {symbol}: ${mid:.2f}")
|
||||
return mid
|
||||
except Exception as _:
|
||||
pass
|
||||
|
||||
# Return None if absolutely nothing available
|
||||
return None
|
||||
|
||||
def _create_price_chart(self, symbol: str) -> go.Figure:
|
||||
@ -2422,50 +2437,7 @@ class CleanTradingDashboard:
|
||||
|
||||
# Mini 1-second chart (if available)
|
||||
if has_mini_chart and ws_data_1s is not None:
|
||||
# Overlay COB heatmap (up to 5 minutes) behind the 1s price line
|
||||
try:
|
||||
hm_seconds = 300 # 5 minutes
|
||||
bucket_radius = 10 # ±10 buckets
|
||||
# Prefer raw liquidity for visual; models can still use normalized features internally
|
||||
times, prices, matrix, mids = self.data_provider.get_cob_heatmap_matrix(
|
||||
symbol=symbol,
|
||||
seconds=hm_seconds,
|
||||
bucket_radius=bucket_radius,
|
||||
metric='liquidity'
|
||||
)
|
||||
if times and prices and matrix:
|
||||
# Align times to local tz-naive to match chart
|
||||
try:
|
||||
_local_tz = datetime.now().astimezone().tzinfo
|
||||
except Exception:
|
||||
_local_tz = None
|
||||
x_vals = []
|
||||
for t in times:
|
||||
try:
|
||||
if hasattr(t, 'tzinfo') and t.tzinfo is not None:
|
||||
tt = t.astimezone(_local_tz) if _local_tz else t
|
||||
tt = tt.replace(tzinfo=None)
|
||||
else:
|
||||
tt = t
|
||||
x_vals.append(tt)
|
||||
except Exception:
|
||||
x_vals.append(t)
|
||||
# Plot heatmap beneath the 1s price line
|
||||
fig.add_trace(
|
||||
go.Heatmap(
|
||||
x=x_vals,
|
||||
y=prices, # numeric prices to share axis with 1s line
|
||||
z=matrix,
|
||||
colorscale='Turbo',
|
||||
showscale=False,
|
||||
zsmooth='best',
|
||||
opacity=0.8,
|
||||
name='COB Liquidity'
|
||||
),
|
||||
row=2, col=1
|
||||
)
|
||||
except Exception as e:
|
||||
logger.debug(f"COB heatmap overlay skipped: {e}")
|
||||
# Removed COB heatmap overlay on the mini 1s chart per request
|
||||
# Align mini chart to local tz-naive
|
||||
try:
|
||||
if hasattr(ws_data_1s.index, 'tz') and ws_data_1s.index.tz is not None:
|
||||
|
Reference in New Issue
Block a user