275 lines
9.4 KiB
Python
275 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Stable Dashboard Runner - Prioritizes System Stability
|
|
|
|
This runner focuses on:
|
|
1. System stability and reliability
|
|
2. Core trading functionality
|
|
3. Minimal resource usage
|
|
4. Robust error handling
|
|
5. Graceful degradation
|
|
|
|
Deferred features (until stability is achieved):
|
|
- TensorBoard integration
|
|
- Complex training loops
|
|
- Advanced visualizations
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import logging
|
|
import threading
|
|
import signal
|
|
from pathlib import Path
|
|
|
|
# Fix environment issues before imports
|
|
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
|
|
os.environ['OMP_NUM_THREADS'] = '2' # Reduced from 4 for stability
|
|
|
|
# Fix matplotlib backend
|
|
import matplotlib
|
|
matplotlib.use('Agg')
|
|
|
|
# Add project root to path
|
|
project_root = Path(__file__).parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
from core.config import setup_logging, get_config
|
|
from system_stability_audit import SystemStabilityAuditor
|
|
|
|
# Setup logging with reduced verbosity for stability
|
|
setup_logging()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Reduce logging noise from other modules
|
|
logging.getLogger('werkzeug').setLevel(logging.ERROR)
|
|
logging.getLogger('dash').setLevel(logging.ERROR)
|
|
logging.getLogger('matplotlib').setLevel(logging.ERROR)
|
|
|
|
class StableDashboardRunner:
|
|
"""
|
|
Stable dashboard runner with focus on reliability
|
|
"""
|
|
|
|
def __init__(self):
|
|
"""Initialize stable dashboard runner"""
|
|
self.config = get_config()
|
|
self.running = False
|
|
self.dashboard = None
|
|
self.stability_auditor = None
|
|
|
|
# Core components
|
|
self.data_provider = None
|
|
self.orchestrator = None
|
|
self.trading_executor = None
|
|
|
|
# Stability monitoring
|
|
self.last_health_check = time.time()
|
|
self.health_check_interval = 30 # Check every 30 seconds
|
|
|
|
logger.info("Stable Dashboard Runner initialized")
|
|
|
|
def initialize_components(self):
|
|
"""Initialize core components with error handling"""
|
|
try:
|
|
logger.info("Initializing core components...")
|
|
|
|
# Initialize data provider
|
|
from core.data_provider import DataProvider
|
|
self.data_provider = DataProvider()
|
|
logger.info("✓ Data provider initialized")
|
|
|
|
# Initialize trading executor
|
|
from core.trading_executor import TradingExecutor
|
|
self.trading_executor = TradingExecutor()
|
|
logger.info("✓ Trading executor initialized")
|
|
|
|
# Initialize orchestrator with minimal features for stability
|
|
from core.orchestrator import TradingOrchestrator
|
|
self.orchestrator = TradingOrchestrator(
|
|
data_provider=self.data_provider,
|
|
enhanced_rl_training=False # Disabled for stability
|
|
)
|
|
logger.info("✓ Orchestrator initialized (training disabled for stability)")
|
|
|
|
# Initialize dashboard
|
|
from web.clean_dashboard import CleanTradingDashboard
|
|
self.dashboard = CleanTradingDashboard(
|
|
data_provider=self.data_provider,
|
|
orchestrator=self.orchestrator,
|
|
trading_executor=self.trading_executor
|
|
)
|
|
logger.info("✓ Dashboard initialized")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error initializing components: {e}")
|
|
return False
|
|
|
|
def start_stability_monitoring(self):
|
|
"""Start system stability monitoring"""
|
|
try:
|
|
self.stability_auditor = SystemStabilityAuditor()
|
|
self.stability_auditor.start_monitoring()
|
|
logger.info("✓ Stability monitoring started")
|
|
except Exception as e:
|
|
logger.error(f"Error starting stability monitoring: {e}")
|
|
|
|
def health_check(self):
|
|
"""Perform system health check"""
|
|
try:
|
|
current_time = time.time()
|
|
if current_time - self.last_health_check < self.health_check_interval:
|
|
return
|
|
|
|
self.last_health_check = current_time
|
|
|
|
# Check stability score
|
|
if self.stability_auditor:
|
|
report = self.stability_auditor.get_stability_report()
|
|
stability_score = report.get('stability_score', 0)
|
|
|
|
if stability_score < 50:
|
|
logger.warning(f"Low stability score: {stability_score:.1f}/100")
|
|
# Attempt to fix issues
|
|
self.stability_auditor.fix_common_issues()
|
|
elif stability_score < 80:
|
|
logger.info(f"Moderate stability: {stability_score:.1f}/100")
|
|
else:
|
|
logger.debug(f"Good stability: {stability_score:.1f}/100")
|
|
|
|
# Check component health
|
|
if self.dashboard and hasattr(self.dashboard, 'app'):
|
|
logger.debug("✓ Dashboard responsive")
|
|
|
|
if self.data_provider:
|
|
logger.debug("✓ Data provider active")
|
|
|
|
if self.orchestrator:
|
|
logger.debug("✓ Orchestrator active")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in health check: {e}")
|
|
|
|
def run(self):
|
|
"""Run the stable dashboard"""
|
|
try:
|
|
logger.info("=" * 60)
|
|
logger.info("STABLE TRADING DASHBOARD")
|
|
logger.info("=" * 60)
|
|
logger.info("Priority: System Stability & Core Functionality")
|
|
logger.info("Training: Disabled (will be enabled after stability)")
|
|
logger.info("TensorBoard: Deferred (documented in design)")
|
|
logger.info("Focus: Dashboard, Data, Basic Trading")
|
|
logger.info("=" * 60)
|
|
|
|
# Initialize components
|
|
if not self.initialize_components():
|
|
logger.error("Failed to initialize components")
|
|
return False
|
|
|
|
# Start stability monitoring
|
|
self.start_stability_monitoring()
|
|
|
|
# Start health check thread
|
|
health_thread = threading.Thread(target=self._health_check_loop, daemon=True)
|
|
health_thread.start()
|
|
|
|
# Get dashboard port
|
|
port = int(os.environ.get('DASHBOARD_PORT', '8051'))
|
|
|
|
logger.info(f"Starting dashboard on http://127.0.0.1:{port}")
|
|
logger.info("Press Ctrl+C to stop")
|
|
|
|
self.running = True
|
|
|
|
# Start dashboard (this blocks)
|
|
if self.dashboard and hasattr(self.dashboard, 'app'):
|
|
self.dashboard.app.run_server(
|
|
host='127.0.0.1',
|
|
port=port,
|
|
debug=False,
|
|
use_reloader=False, # Disable reloader for stability
|
|
threaded=True
|
|
)
|
|
else:
|
|
logger.error("Dashboard not properly initialized")
|
|
return False
|
|
|
|
except KeyboardInterrupt:
|
|
logger.info("Dashboard stopped by user")
|
|
self.shutdown()
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Error running dashboard: {e}")
|
|
import traceback
|
|
logger.error(traceback.format_exc())
|
|
return False
|
|
|
|
def _health_check_loop(self):
|
|
"""Health check loop running in background"""
|
|
while self.running:
|
|
try:
|
|
self.health_check()
|
|
time.sleep(self.health_check_interval)
|
|
except Exception as e:
|
|
logger.error(f"Error in health check loop: {e}")
|
|
time.sleep(60) # Wait longer on error
|
|
|
|
def shutdown(self):
|
|
"""Graceful shutdown"""
|
|
try:
|
|
logger.info("Shutting down stable dashboard...")
|
|
self.running = False
|
|
|
|
# Stop stability monitoring
|
|
if self.stability_auditor:
|
|
self.stability_auditor.stop_monitoring()
|
|
logger.info("✓ Stability monitoring stopped")
|
|
|
|
# Stop components
|
|
if self.orchestrator and hasattr(self.orchestrator, 'stop'):
|
|
self.orchestrator.stop()
|
|
logger.info("✓ Orchestrator stopped")
|
|
|
|
if self.data_provider and hasattr(self.data_provider, 'stop'):
|
|
self.data_provider.stop()
|
|
logger.info("✓ Data provider stopped")
|
|
|
|
logger.info("Stable dashboard shutdown complete")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error during shutdown: {e}")
|
|
|
|
def signal_handler(signum, frame):
|
|
"""Handle shutdown signals"""
|
|
logger.info("Received shutdown signal")
|
|
sys.exit(0)
|
|
|
|
def main():
|
|
"""Main function"""
|
|
# Setup signal handlers
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
try:
|
|
runner = StableDashboardRunner()
|
|
success = runner.run()
|
|
|
|
if success:
|
|
logger.info("Dashboard completed successfully")
|
|
sys.exit(0)
|
|
else:
|
|
logger.error("Dashboard failed")
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fatal error: {e}")
|
|
import traceback
|
|
logger.error(traceback.format_exc())
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |