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

@ -1,10 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Scalping Dashboard Runner - 100% REAL MARKET DATA ONLY Run Ultra-Fast Scalping Dashboard (500x Leverage)
CRITICAL: This dashboard uses EXCLUSIVELY real market data. This script starts the custom scalping dashboard with:
NO synthetic, mock, or simulated data is allowed. - Full-width 1s ETH/USDT candlestick chart
All trading decisions come from real market analysis. - 3 small ETH charts: 1m, 1h, 1d
- 1 small BTC 1s chart
- Ultra-fast 100ms updates for scalping
- Real-time PnL tracking and logging
""" """
import logging import logging

View File

@ -48,6 +48,14 @@ class TradingDashboard:
self.current_prices = {} self.current_prices = {}
self.last_update = datetime.now() 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 # Create Dash app
self.app = dash.Dash(__name__, external_stylesheets=[ self.app = dash.Dash(__name__, external_stylesheets=[
'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css',
@ -76,7 +84,7 @@ class TradingDashboard:
# Auto-refresh component # Auto-refresh component
dcc.Interval( dcc.Interval(
id='interval-component', 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 n_intervals=0
), ),
@ -189,24 +197,30 @@ class TradingDashboard:
symbol = self.config.symbols[0] if self.config.symbols else "ETH/USDT" symbol = self.config.symbols[0] if self.config.symbols else "ETH/USDT"
try: try:
# Try to get fresh current price from latest data # Try to get fresh current price from latest data - OPTIMIZED FOR SPEED
fresh_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=True) 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: if fresh_data is not None and not fresh_data.empty:
current_price = float(fresh_data['close'].iloc[-1]) 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: else:
# Fallback to cached data # Quick fallback to 1m data
cached_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=False) fresh_data = self.data_provider.get_historical_data(symbol, '1m', limit=1, refresh=True)
if cached_data is not None and not cached_data.empty: if fresh_data is not None and not fresh_data.empty:
base_price = float(cached_data['close'].iloc[-1]) current_price = float(fresh_data['close'].iloc[-1])
# Apply small realistic price movement for demo logger.debug(f"[TICK] Fresh 1m price for {symbol}: ${current_price:.2f}")
current_price = self._simulate_price_update(symbol, base_price)
logger.debug(f"Simulated price update for {symbol}: ${current_price:.2f} (base: ${base_price:.2f})")
else: else:
current_price = None # Use cached data with simulation
logger.warning(f"No price data available for {symbol}") 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: 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 current_price = None
# Get model performance metrics with fallback # Get model performance metrics with fallback
@ -233,10 +247,12 @@ class TradingDashboard:
wins += 1 wins += 1
# Format outputs with safe defaults and update indicators # 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" price_text = f"${current_price:.2f}" if current_price else "No Data"
if current_price: 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_text = f"${total_pnl:.2f}"
pnl_class = "text-success mb-1" if total_pnl >= 0 else "text-danger mb-1" 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%" 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: for tf in timeframes_to_try:
try: try:
# FORCE FRESH DATA on each update for real-time charts # FORCE FRESH DATA on each update for real-time charts - OPTIMIZED FOR SPEED
df = self.data_provider.get_historical_data(symbol, tf, limit=200, refresh=True) 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: if df is not None and not df.empty and len(df) > 5:
actual_timeframe = tf 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 break
else: else:
logger.warning(f"⚠️ No fresh data for {symbol} {tf}") logger.warning(f"[WARN] No fresh data for {symbol} {tf}")
except Exception as e: 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 continue
# If still no fresh data, try cached data as fallback # If still no fresh data, try cached data as fallback
if df is None or df.empty: 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: for tf in timeframes_to_try:
try: try:
df = self.data_provider.get_historical_data(symbol, tf, limit=200, refresh=False) 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: if df is not None and not df.empty and len(df) > 5:
actual_timeframe = tf 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 break
except Exception as e: 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 continue
# If still no data, create empty chart # If still no data, create empty chart
@ -427,11 +444,11 @@ class TradingDashboard:
)) ))
# Update layout with current timestamp # 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 latest_price = df['close'].iloc[-1] if not df.empty else 0
fig.update_layout( 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", template="plotly_dark",
height=400, height=400,
xaxis_rangeslider_visible=False, xaxis_rangeslider_visible=False,