better dash

This commit is contained in:
Dobromir Popov
2025-05-25 00:29:21 +03:00
parent cf825239cd
commit 3c23e4ec42
2 changed files with 50 additions and 30 deletions

View File

@ -48,6 +48,14 @@ class TradingDashboard:
self.current_prices = {}
self.last_update = datetime.now()
# Trading session tracking
self.session_start = datetime.now()
self.session_trades = []
self.session_pnl = 0.0
self.current_position = None # {'side': 'BUY', 'price': 3456.78, 'size': 0.1, 'timestamp': datetime}
self.total_realized_pnl = 0.0
self.total_fees = 0.0
# Create Dash app
self.app = dash.Dash(__name__, external_stylesheets=[
'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css',
@ -76,7 +84,7 @@ class TradingDashboard:
# Auto-refresh component
dcc.Interval(
id='interval-component',
interval=5000, # Update every 5 seconds for better real-time feel
interval=1000, # Update every 1 second for real-time tick updates
n_intervals=0
),
@ -189,24 +197,30 @@ class TradingDashboard:
symbol = self.config.symbols[0] if self.config.symbols else "ETH/USDT"
try:
# Try to get fresh current price from latest data
fresh_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=True)
# Try to get fresh current price from latest data - OPTIMIZED FOR SPEED
fresh_data = self.data_provider.get_historical_data(symbol, '1s', limit=5, refresh=True)
if fresh_data is not None and not fresh_data.empty:
current_price = float(fresh_data['close'].iloc[-1])
logger.debug(f"Got fresh price for {symbol}: ${current_price:.2f}")
logger.debug(f"[TICK] Fresh price for {symbol}: ${current_price:.2f}")
else:
# Fallback to cached data
cached_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=False)
if cached_data is not None and not cached_data.empty:
base_price = float(cached_data['close'].iloc[-1])
# Apply small realistic price movement for demo
current_price = self._simulate_price_update(symbol, base_price)
logger.debug(f"Simulated price update for {symbol}: ${current_price:.2f} (base: ${base_price:.2f})")
# Quick fallback to 1m data
fresh_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=True)
if fresh_data is not None and not fresh_data.empty:
current_price = float(fresh_data['close'].iloc[-1])
logger.debug(f"[TICK] Fresh 1m price for {symbol}: ${current_price:.2f}")
else:
current_price = None
logger.warning(f"No price data available for {symbol}")
# Use cached data with simulation
cached_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=False)
if cached_data is not None and not cached_data.empty:
base_price = float(cached_data['close'].iloc[-1])
# Apply small realistic price movement for demo
current_price = self._simulate_price_update(symbol, base_price)
logger.debug(f"[SIM] Simulated price update for {symbol}: ${current_price:.2f} (base: ${base_price:.2f})")
else:
current_price = None
logger.warning(f"[ERROR] No price data available for {symbol}")
except Exception as e:
logger.warning(f"Error getting price for {symbol}: {e}")
logger.warning(f"[ERROR] Error getting price for {symbol}: {e}")
current_price = None
# Get model performance metrics with fallback
@ -233,10 +247,12 @@ class TradingDashboard:
wins += 1
# Format outputs with safe defaults and update indicators
update_time = datetime.now().strftime("%H:%M:%S")
update_time = datetime.now().strftime("%H:%M:%S.%f")[:-3] # Include milliseconds
price_text = f"${current_price:.2f}" if current_price else "No Data"
if current_price:
price_text += f" @ {update_time}"
# Add tick indicator and precise timestamp (no emojis to avoid Unicode issues)
tick_indicator = "[LIVE]" if (datetime.now().microsecond // 100000) % 2 else "[TICK]" # Alternating indicator
price_text += f" {tick_indicator} @ {update_time}"
pnl_text = f"${total_pnl:.2f}"
pnl_class = "text-success mb-1" if total_pnl >= 0 else "text-danger mb-1"
win_rate_text = f"{(wins/total_trades*100):.1f}%" if total_trades > 0 else "0.0%"
@ -348,30 +364,31 @@ class TradingDashboard:
for tf in timeframes_to_try:
try:
# FORCE FRESH DATA on each update for real-time charts
df = self.data_provider.get_historical_data(symbol, tf, limit=200, refresh=True)
# FORCE FRESH DATA on each update for real-time charts - OPTIMIZED FOR SPEED
limit = 100 if tf == '1s' else 50 if tf == '1m' else 30 # Smaller data for faster updates
df = self.data_provider.get_historical_data(symbol, tf, limit=limit, refresh=True)
if df is not None and not df.empty and len(df) > 5:
actual_timeframe = tf
logger.info(f"✅ Got FRESH {len(df)} candles for {symbol} {tf}")
logger.info(f"[FRESH] Got {len(df)} candles for {symbol} {tf}")
break
else:
logger.warning(f"⚠️ No fresh data for {symbol} {tf}")
logger.warning(f"[WARN] No fresh data for {symbol} {tf}")
except Exception as e:
logger.warning(f"⚠️ Error getting fresh {symbol} {tf} data: {e}")
logger.warning(f"[ERROR] Error getting fresh {symbol} {tf} data: {e}")
continue
# If still no fresh data, try cached data as fallback
if df is None or df.empty:
logger.warning(f"⚠️ No fresh data, trying cached data for {symbol}")
logger.warning(f"[WARN] No fresh data, trying cached data for {symbol}")
for tf in timeframes_to_try:
try:
df = self.data_provider.get_historical_data(symbol, tf, limit=200, refresh=False)
if df is not None and not df.empty and len(df) > 5:
actual_timeframe = tf
logger.info(f"✅ Got cached {len(df)} candles for {symbol} {tf}")
logger.info(f"[CACHED] Got {len(df)} candles for {symbol} {tf}")
break
except Exception as e:
logger.warning(f"⚠️ Error getting cached {symbol} {tf} data: {e}")
logger.warning(f"[ERROR] Error getting cached {symbol} {tf} data: {e}")
continue
# If still no data, create empty chart
@ -427,11 +444,11 @@ class TradingDashboard:
))
# Update layout with current timestamp
current_time = datetime.now().strftime("%H:%M:%S")
current_time = datetime.now().strftime("%H:%M:%S.%f")[:-3] # Include milliseconds
latest_price = df['close'].iloc[-1] if not df.empty else 0
fig.update_layout(
title=f"{symbol} Price Chart ({actual_timeframe.upper()}) - {len(df)} candles | ${latest_price:.2f} @ {current_time}",
title=f"{symbol} LIVE CHART ({actual_timeframe.upper()}) | ${latest_price:.2f} | {len(df)} candles | {current_time}",
template="plotly_dark",
height=400,
xaxis_rangeslider_visible=False,