improve stream

This commit is contained in:
Dobromir Popov
2025-09-02 18:15:12 +03:00
parent c55175c44d
commit 1c013f2806
4 changed files with 330 additions and 104 deletions

View File

@@ -347,17 +347,27 @@ class CleanTradingDashboard:
def _get_ohlcv_data_with_indicators(self, symbol: str, timeframe: str, limit: int = 300):
"""Get OHLCV data with technical indicators from data stream monitor"""
try:
# Get OHLCV data from data stream monitor
# Get OHLCV data from data stream monitor based on symbol and timeframe
if hasattr(self.orchestrator, 'data_stream_monitor') and self.orchestrator.data_stream_monitor:
stream_key = f"ohlcv_{timeframe}"
# Determine stream key based on symbol and timeframe
if symbol == 'BTC/USDT' and timeframe == '1m':
stream_key = 'btc_1m'
else:
stream_key = f"ohlcv_{timeframe}"
if stream_key in self.orchestrator.data_stream_monitor.data_streams:
ohlcv_data = list(self.orchestrator.data_stream_monitor.data_streams[stream_key])
# Filter by symbol if needed (for ETH data in mixed streams)
if symbol != 'BTC/USDT':
ohlcv_data = [item for item in ohlcv_data if item.get('symbol') == symbol]
# Take the last 'limit' items
ohlcv_data = ohlcv_data[-limit:] if len(ohlcv_data) > limit else ohlcv_data
if not ohlcv_data:
return []
# Fallback to data provider if stream is empty
return self._get_ohlcv_from_provider(symbol, timeframe, limit)
# Convert to DataFrame for indicator calculation
df_data = []
@@ -372,78 +382,46 @@ class CleanTradingDashboard:
})
if not df_data:
return []
return self._get_ohlcv_from_provider(symbol, timeframe, limit)
df = pd.DataFrame(df_data)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df.set_index('timestamp', inplace=True)
# Add technical indicators
df['sma_20'] = df['close'].rolling(window=20).mean()
df['sma_50'] = df['close'].rolling(window=50).mean()
df['ema_12'] = df['close'].ewm(span=12).mean()
df['ema_26'] = df['close'].ewm(span=26).mean()
# RSI
delta = df['close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
rs = gain / loss
df['rsi'] = 100 - (100 / (1 + rs))
# MACD
df['macd'] = df['ema_12'] - df['ema_26']
df['macd_signal'] = df['macd'].ewm(span=9).mean()
df['macd_histogram'] = df['macd'] - df['macd_signal']
# Bollinger Bands
df['bb_middle'] = df['close'].rolling(window=20).mean()
bb_std = df['close'].rolling(window=20).std()
df['bb_upper'] = df['bb_middle'] + (bb_std * 2)
df['bb_lower'] = df['bb_middle'] - (bb_std * 2)
# Volume indicators
df['volume_sma'] = df['volume'].rolling(window=20).mean()
df['volume_ratio'] = df['volume'] / df['volume_sma']
df = self._add_technical_indicators(df)
# Convert to list of dictionaries
result = []
for _, row in df.iterrows():
data_point = {
'timestamp': row.name.isoformat() if hasattr(row.name, 'isoformat') else str(row.name),
'open': float(row['open']),
'high': float(row['high']),
'low': float(row['low']),
'close': float(row['close']),
'volume': float(row['volume']),
'indicators': {
'sma_20': float(row['sma_20']) if pd.notna(row['sma_20']) else None,
'sma_50': float(row['sma_50']) if pd.notna(row['sma_50']) else None,
'ema_12': float(row['ema_12']) if pd.notna(row['ema_12']) else None,
'ema_26': float(row['ema_26']) if pd.notna(row['ema_26']) else None,
'rsi': float(row['rsi']) if pd.notna(row['rsi']) else None,
'macd': float(row['macd']) if pd.notna(row['macd']) else None,
'macd_signal': float(row['macd_signal']) if pd.notna(row['macd_signal']) else None,
'macd_histogram': float(row['macd_histogram']) if pd.notna(row['macd_histogram']) else None,
'bb_upper': float(row['bb_upper']) if pd.notna(row['bb_upper']) else None,
'bb_middle': float(row['bb_middle']) if pd.notna(row['bb_middle']) else None,
'bb_lower': float(row['bb_lower']) if pd.notna(row['bb_lower']) else None,
'volume_ratio': float(row['volume_ratio']) if pd.notna(row['volume_ratio']) else None
}
}
result.append(data_point)
return result
return self._dataframe_to_api_format(df)
# Fallback to data provider if stream monitor not available
return self._get_ohlcv_from_provider(symbol, timeframe, limit)
except Exception as e:
logger.error(f"Error getting OHLCV data: {e}")
return []
def _get_ohlcv_from_provider(self, symbol: str, timeframe: str, limit: int = 300):
"""Fallback to get OHLCV data directly from data provider"""
try:
ohlcv_data = self.data_provider.get_ohlcv(symbol, timeframe, limit=limit)
if ohlcv_data is None or ohlcv_data.empty:
return []
# Add technical indicators
df = ohlcv_data.copy()
df = self._add_technical_indicators(ohlcv_data.copy())
# Convert to list of dictionaries
return self._dataframe_to_api_format(df)
except Exception as e:
logger.error(f"Error getting OHLCV from provider: {e}")
return []
def _add_technical_indicators(self, df):
"""Add technical indicators to DataFrame"""
try:
# Basic indicators
df['sma_20'] = df['close'].rolling(window=20).mean()
df['sma_50'] = df['close'].rolling(window=50).mean()
@@ -472,7 +450,15 @@ class CleanTradingDashboard:
df['volume_sma'] = df['volume'].rolling(window=20).mean()
df['volume_ratio'] = df['volume'] / df['volume_sma']
# Convert to list of dictionaries
return df
except Exception as e:
logger.error(f"Error adding technical indicators: {e}")
return df
def _dataframe_to_api_format(self, df):
"""Convert DataFrame to API format with indicators"""
try:
result = []
for _, row in df.iterrows():
data_point = {
@@ -502,7 +488,7 @@ class CleanTradingDashboard:
return result
except Exception as e:
logger.error(f"Error getting OHLCV data: {e}")
logger.error(f"Error converting to API format: {e}")
return []
def _get_cob_data_with_buckets(self, symbol: str, limit: int = 300):