multicandle chart
This commit is contained in:
parent
7ea193d70f
commit
3347ecb494
81
realtime.py
81
realtime.py
@ -524,6 +524,68 @@ class ExchangeWebSocket:
|
||||
"""Check if the WebSocket is running"""
|
||||
return self.ws.running if self.ws else False
|
||||
|
||||
class CandleCache:
|
||||
def __init__(self, max_candles: int = 2000):
|
||||
self.candles = {
|
||||
'1s': deque(maxlen=max_candles),
|
||||
'1m': deque(maxlen=max_candles),
|
||||
'1h': deque(maxlen=max_candles),
|
||||
'1d': deque(maxlen=max_candles)
|
||||
}
|
||||
logger.info("Initialized CandleCache with max candles: {}".format(max_candles))
|
||||
|
||||
def add_candles(self, interval: str, new_candles: pd.DataFrame):
|
||||
if interval in self.candles and not new_candles.empty:
|
||||
for _, row in new_candles.iterrows():
|
||||
self.candles[interval].append(row)
|
||||
logger.debug(f"Added {len(new_candles)} candles to {interval} cache")
|
||||
|
||||
def get_recent_candles(self, interval: str, count: int = 500) -> pd.DataFrame:
|
||||
if interval in self.candles and self.candles[interval]:
|
||||
recent_candles = list(self.candles[interval])[-count:]
|
||||
return pd.DataFrame(recent_candles)
|
||||
return pd.DataFrame()
|
||||
|
||||
def update_cache(self, interval: str, new_candles: pd.DataFrame):
|
||||
if interval not in self.candles:
|
||||
logger.warning(f"Invalid interval {interval} for cache update")
|
||||
return
|
||||
|
||||
if new_candles.empty:
|
||||
logger.debug(f"No new candles to update {interval} cache")
|
||||
return
|
||||
|
||||
# Check if timestamp column exists
|
||||
if 'timestamp' not in new_candles.columns:
|
||||
logger.warning(f"No timestamp column in new candles for {interval}")
|
||||
return
|
||||
|
||||
last_cached_time = None
|
||||
if self.candles[interval]:
|
||||
try:
|
||||
# Get the timestamp from the last cached candle
|
||||
last_cached_candle = self.candles[interval][-1]
|
||||
if isinstance(last_cached_candle, dict) and 'timestamp' in last_cached_candle:
|
||||
last_cached_time = last_cached_candle['timestamp']
|
||||
logger.debug(f"Last cached timestamp for {interval}: {last_cached_time}")
|
||||
except (IndexError, KeyError) as e:
|
||||
logger.error(f"Error accessing timestamp from last cached candle: {e}")
|
||||
|
||||
try:
|
||||
# Only filter if we have a valid last_cached_time
|
||||
if last_cached_time is not None:
|
||||
filtered_candles = new_candles[new_candles['timestamp'] > last_cached_time]
|
||||
logger.debug(f"Filtered {len(filtered_candles)} new candles for {interval}")
|
||||
self.add_candles(interval, filtered_candles)
|
||||
else:
|
||||
# If no previous candles, add all
|
||||
logger.debug(f"No previous candles, adding all {len(new_candles)} candles to {interval} cache")
|
||||
self.add_candles(interval, new_candles)
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating cache for {interval}: {str(e)}")
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
class RealTimeChart:
|
||||
def __init__(self, symbol: str):
|
||||
self.symbol = symbol
|
||||
@ -536,8 +598,13 @@ class RealTimeChart:
|
||||
'1h': None,
|
||||
'1d': None
|
||||
}
|
||||
self.candle_cache = CandleCache() # Initialize local candle cache
|
||||
logger.info(f"Initializing RealTimeChart for {symbol}")
|
||||
|
||||
|
||||
# We'll populate the cache as data comes in rather than trying to load on startup
|
||||
# when there might not be any ticks available yet
|
||||
logger.info(f"Cache will be populated as data becomes available for {symbol}")
|
||||
|
||||
# Button style
|
||||
button_style = {
|
||||
'background-color': '#4CAF50',
|
||||
@ -794,8 +861,16 @@ class RealTimeChart:
|
||||
|
||||
# Fetch and cache OHLCV data for different intervals
|
||||
for interval_key in self.ohlcv_cache.keys():
|
||||
if self.ohlcv_cache[interval_key] is None:
|
||||
self.ohlcv_cache[interval_key] = self.tick_storage.get_candles(interval_seconds=self._interval_to_seconds(interval_key))
|
||||
try:
|
||||
new_candles = self.tick_storage.get_candles(interval_seconds=self._interval_to_seconds(interval_key))
|
||||
if not new_candles.empty:
|
||||
# Update the cache with new candles
|
||||
self.candle_cache.update_cache(interval_key, new_candles)
|
||||
# Get the updated candles from cache for display
|
||||
self.ohlcv_cache[interval_key] = self.candle_cache.get_recent_candles(interval_key)
|
||||
logger.debug(f"Updated cache for {interval_key}, now has {len(self.ohlcv_cache[interval_key])} candles")
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating cache for {interval_key}: {str(e)}")
|
||||
|
||||
# Add OHLCV subcharts
|
||||
for i, (interval_key, ohlcv_df) in enumerate(self.ohlcv_cache.items(), start=3):
|
||||
|
Loading…
x
Reference in New Issue
Block a user