COB heatmap!
This commit is contained in:
@ -4756,6 +4756,87 @@ class DataProvider:
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting 1s aggregated COB data for {symbol}: {e}")
|
||||
return []
|
||||
|
||||
def get_cob_heatmap_matrix(
|
||||
self,
|
||||
symbol: str,
|
||||
seconds: int = 300,
|
||||
bucket_radius: int = 10,
|
||||
metric: str = 'imbalance'
|
||||
) -> Tuple[List[datetime], List[float], List[List[float]]]:
|
||||
"""
|
||||
Build a 1s COB heatmap matrix for ±bucket_radius buckets around current price.
|
||||
|
||||
Returns (times, prices, matrix) where matrix is shape [T x B].
|
||||
metric: 'imbalance' or 'liquidity' (uses bid_volume+ask_volume)
|
||||
"""
|
||||
try:
|
||||
times: List[datetime] = []
|
||||
prices: List[float] = []
|
||||
values: List[List[float]] = []
|
||||
|
||||
latest = self.get_latest_cob_data(symbol)
|
||||
if not latest or 'stats' not in latest:
|
||||
return times, prices, values
|
||||
|
||||
mid = float(latest['stats'].get('mid_price', 0) or 0)
|
||||
if mid <= 0:
|
||||
return times, prices, values
|
||||
|
||||
bucket_size = 1.0 if 'ETH' in symbol else 10.0
|
||||
center = round(mid / bucket_size) * bucket_size
|
||||
prices = [center + i * bucket_size for i in range(-bucket_radius, bucket_radius + 1)]
|
||||
|
||||
with self.subscriber_lock:
|
||||
cache_for_symbol = getattr(self, 'cob_data_cache', {}).get(symbol, [])
|
||||
snapshots = list(cache_for_symbol[-seconds:]) if cache_for_symbol else []
|
||||
|
||||
for snap in snapshots:
|
||||
ts_ms = snap.get('timestamp')
|
||||
if isinstance(ts_ms, (int, float)):
|
||||
times.append(datetime.fromtimestamp(ts_ms / 1000.0))
|
||||
else:
|
||||
times.append(datetime.utcnow())
|
||||
|
||||
bids = snap.get('bids') or []
|
||||
asks = snap.get('asks') or []
|
||||
|
||||
bucket_map: Dict[float, Dict[str, float]] = {}
|
||||
for level in bids[:200]:
|
||||
try:
|
||||
price, size = float(level[0]), float(level[1])
|
||||
bp = round(price / bucket_size) * bucket_size
|
||||
if bp not in bucket_map:
|
||||
bucket_map[bp] = {'bid': 0.0, 'ask': 0.0}
|
||||
bucket_map[bp]['bid'] += size
|
||||
except Exception:
|
||||
continue
|
||||
for level in asks[:200]:
|
||||
try:
|
||||
price, size = float(level[0]), float(level[1])
|
||||
bp = round(price / bucket_size) * bucket_size
|
||||
if bp not in bucket_map:
|
||||
bucket_map[bp] = {'bid': 0.0, 'ask': 0.0}
|
||||
bucket_map[bp]['ask'] += size
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
row: List[float] = []
|
||||
for p in prices:
|
||||
b = float(bucket_map.get(p, {}).get('bid', 0.0))
|
||||
a = float(bucket_map.get(p, {}).get('ask', 0.0))
|
||||
if metric == 'liquidity':
|
||||
val = (b + a)
|
||||
else:
|
||||
denom = (b + a)
|
||||
val = (b - a) / denom if denom > 0 else 0.0
|
||||
row.append(val)
|
||||
values.append(row)
|
||||
|
||||
return times, prices, values
|
||||
except Exception as e:
|
||||
logger.error(f"Error building COB heatmap matrix for {symbol}: {e}")
|
||||
return [], [], []
|
||||
|
||||
def get_combined_ohlcv_cob_data(self, symbol: str, timeframe: str = '1s', count: int = 60) -> dict:
|
||||
"""
|
||||
|
Reference in New Issue
Block a user