""" Dashboard Components Reusable UI components for the Streamlit dashboard. """ import streamlit as st from typing import Dict, Any, List, Optional from datetime import datetime def render_header( symbol: str = "BTC/USDT", price: float = 0.0, change_24h: float = 0.0, connection_status: bool = True, ): """ Render the dashboard header with live price and status. """ col1, col2, col3 = st.columns([2, 1, 1]) with col1: st.markdown(f"""

🤖 DRL Trading System

""", unsafe_allow_html=True) with col2: change_color = "#26a69a" if change_24h >= 0 else "#ef5350" st.markdown(f"""
{symbol}
${price:,.2f}
{'+' if change_24h >= 0 else ''}{change_24h:.2f}%
""", unsafe_allow_html=True) with col3: status_color = "#26a69a" if connection_status else "#ef5350" status_text = "🟢 Connected" if connection_status else "🔴 Disconnected" st.markdown(f"""
{status_text}
Binance Testnet
""", unsafe_allow_html=True) def render_confidence_gauge(confidence: float): """ Render the agent confidence gauge. Args: confidence: Confidence percentage (0-100) """ # Determine color based on confidence if confidence >= 70: color = "#26a69a" label = "High" elif confidence >= 40: color = "#ffc107" label = "Medium" else: color = "#ef5350" label = "Low" st.markdown(f"""
Agent Confidence
{confidence:.0f}%
{label} Confidence
""", unsafe_allow_html=True) def render_pnl_card( total_balance: float, daily_pnl: float, daily_roi: float, initial_balance: float = 10000.0, ): """ Render the P&L summary card. """ total_pnl = total_balance - initial_balance total_roi = (total_pnl / initial_balance) * 100 pnl_color = "#26a69a" if total_pnl >= 0 else "#ef5350" daily_color = "#26a69a" if daily_pnl >= 0 else "#ef5350" st.markdown(f"""
Portfolio Value
${total_balance:,.2f}
Total P&L
{'+' if total_pnl >= 0 else ''}${total_pnl:,.2f}
({'+' if total_roi >= 0 else ''}{total_roi:.2f}%)
Daily P&L
{'+' if daily_pnl >= 0 else ''}${daily_pnl:,.2f}
({'+' if daily_roi >= 0 else ''}{daily_roi:.2f}%)
""", unsafe_allow_html=True) def render_position_card(position: Optional[Dict[str, Any]]): """ Render the current position card. """ if position is None: st.markdown("""
Current Position
No Position
""", unsafe_allow_html=True) return side = position.get('side', 'unknown') is_long = side == 'buy' color = "#26a69a" if is_long else "#ef5350" icon = "📈" if is_long else "📉" entry_price = position.get('entry_price', 0) amount = position.get('amount', 0) unrealized_pnl = position.get('unrealized_pnl', 0) st.markdown(f"""
Current Position
{icon} {'LONG' if is_long else 'SHORT'}
Entry Price: ${entry_price:,.2f}
Size: {amount:.6f}
Unrealized P&L: {'+' if unrealized_pnl >= 0 else ''}${unrealized_pnl:,.2f}
""", unsafe_allow_html=True) def render_trade_history(trades: List[Dict], limit: int = 10): """ Render the trade history table. """ st.markdown("""
Recent Trades
""", unsafe_allow_html=True) if not trades: st.info("No trades yet") return # Prepare data for display display_trades = trades[-limit:][::-1] # Most recent first for trade in display_trades: side = trade.get('side', trade.get('position', 0)) if isinstance(side, int): side = 'LONG' if side == 1 else 'SHORT' else: side = side.upper() is_long = side == 'LONG' or side == 'BUY' color = "#26a69a" if is_long else "#ef5350" pnl = trade.get('pnl', 0) pnl_color = "#26a69a" if pnl >= 0 else "#ef5350" entry = trade.get('entry_price', 0) exit_price = trade.get('exit_price', 0) st.markdown(f"""
{side} ${entry:,.2f} → ${exit_price:,.2f}
{'+' if pnl >= 0 else ''}${pnl:,.2f}
""", unsafe_allow_html=True) def render_circuit_breaker_status(status: Dict[str, Any]): """ Render the circuit breaker status indicator. """ is_tripped = status.get('is_tripped', False) if is_tripped: st.error(f""" ⚠️ **CIRCUIT BREAKER ACTIVATED** Reason: {status.get('trip_reason', 'Unknown')} Cooldown: {status.get('cooldown_remaining', 'Unknown')} """) else: daily_metrics = status.get('daily_metrics', {}) daily_loss = -daily_metrics.get('daily_return', 0) * 100 max_loss = status.get('thresholds', {}).get('max_daily_loss', 0.05) * 100 progress = min(daily_loss / max_loss, 1.0) if max_loss > 0 else 0 if progress < 0.5: status_color = "#26a69a" elif progress < 0.8: status_color = "#ffc107" else: status_color = "#ef5350" st.markdown(f"""
Risk Monitor
Daily Loss: {daily_loss:.2f}% Max: {max_loss:.1f}%
""", unsafe_allow_html=True) def render_training_status(status: Dict[str, Any]): """ Render the self-improvement training status. """ is_finetuning = status.get('is_finetuning', False) finetune_count = status.get('finetune_count', 0) next_finetune = status.get('next_finetune_in', 'Unknown') buffer_size = status.get('buffer_size', 0) if is_finetuning: st.info("🔄 Fine-tuning in progress...") else: st.markdown(f"""
Self-Improvement
Fine-tunes: {finetune_count}
Buffer Size: {buffer_size}
Next Fine-tune: {next_finetune}
""", unsafe_allow_html=True)