#!/usr/bin/env python3 """ Clean Trading System - Main Entry Point This is the new clean entry point that demonstrates the consolidated architecture: - Single configuration system - Clean data provider - Modular CNN and RL components - Centralized orchestrator - Simple web dashboard Usage: python main_clean.py --mode [train|trade|web] --symbol ETH/USDT """ import asyncio import argparse import logging import sys from pathlib import Path # Add project root to path project_root = Path(__file__).parent sys.path.insert(0, str(project_root)) from core.config import get_config, setup_logging from core.data_provider import DataProvider from core.orchestrator import TradingOrchestrator logger = logging.getLogger(__name__) def run_data_test(): """Test the data provider functionality""" try: config = get_config() logger.info("Testing Data Provider...") # Test data provider data_provider = DataProvider( symbols=['ETH/USDT'], timeframes=['1h', '4h'] ) # Test historical data logger.info("Testing historical data fetching...") df = data_provider.get_historical_data('ETH/USDT', '1h', limit=100) if df is not None: logger.info(f"[SUCCESS] Historical data: {len(df)} candles loaded") logger.info(f" Columns: {list(df.columns)}") logger.info(f" Date range: {df['timestamp'].min()} to {df['timestamp'].max()}") else: logger.error("[FAILED] Failed to load historical data") # Test feature matrix logger.info("Testing feature matrix...") feature_matrix = data_provider.get_feature_matrix('ETH/USDT', ['1h'], window_size=20) if feature_matrix is not None: logger.info(f"[SUCCESS] Feature matrix shape: {feature_matrix.shape}") else: logger.error("[FAILED] Failed to create feature matrix") # Test health check health = data_provider.health_check() logger.info(f"[SUCCESS] Data provider health: {health}") logger.info("Data provider test completed successfully!") except Exception as e: logger.error(f"Error in data test: {e}") import traceback logger.error(traceback.format_exc()) raise def run_orchestrator_test(): """Test the modular orchestrator system""" try: from models import get_model_registry, ModelInterface import numpy as np import torch logger.info("Testing Modular Orchestrator System...") # Test model registry registry = get_model_registry() logger.info(f"[SUCCESS] Model registry initialized with {registry.total_memory_limit_mb}MB limit") # Create a mock model for testing class MockCNNModel(ModelInterface): def __init__(self): config = {'max_memory_mb': 500} # 500MB limit super().__init__('MockCNN', config) self.model_params = torch.randn(1000, 100) # Small mock model def predict(self, features): # Mock prediction: random but consistent np.random.seed(42) action_probs = np.random.dirichlet([1, 1, 1]) # Random probabilities that sum to 1 confidence = np.random.uniform(0.5, 0.9) return action_probs, confidence def get_memory_usage(self): # Estimate memory usage if hasattr(self, 'model_params'): return int(self.model_params.numel() * 4 / (1024*1024)) # 4 bytes per float, convert to MB return 0 class MockRLAgent(ModelInterface): def __init__(self): config = {'max_memory_mb': 300} # 300MB limit super().__init__('MockRL', config) self.q_network = torch.randn(500, 50) # Smaller mock RL model def predict(self, features): # Mock RL prediction np.random.seed(123) action_probs = np.random.dirichlet([2, 1, 2]) # Favor BUY/SELL over HOLD confidence = np.random.uniform(0.6, 0.8) return action_probs, confidence def act_with_confidence(self, state): action_probs, confidence = self.predict(state) action = np.argmax(action_probs) return action, confidence def get_memory_usage(self): if hasattr(self, 'q_network'): return int(self.q_network.numel() * 4 / (1024*1024)) return 0 def act(self, state): return self.act_with_confidence(state)[0] def remember(self, state, action, reward, next_state, done): pass # Mock implementation def replay(self): return 0.0 # Mock implementation # Test model registration logger.info("Testing model registration...") mock_cnn = MockCNNModel() mock_rl = MockRLAgent() success1 = registry.register_model(mock_cnn) success2 = registry.register_model(mock_rl) if success1 and success2: logger.info("[SUCCESS] Both models registered successfully") else: logger.error(f"[FAILED] Model registration failed: CNN={success1}, RL={success2}") # Test memory stats memory_stats = registry.get_memory_stats() logger.info(f"[SUCCESS] Memory stats: {memory_stats}") # Test orchestrator logger.info("Testing orchestrator integration...") data_provider = DataProvider(symbols=['ETH/USDT'], timeframes=['1h']) orchestrator = TradingOrchestrator(data_provider) # Register models with orchestrator success1 = orchestrator.register_model(mock_cnn, weight=0.7) success2 = orchestrator.register_model(mock_rl, weight=0.3) if success1 and success2: logger.info("[SUCCESS] Models registered with orchestrator") else: logger.error(f"[FAILED] Orchestrator registration failed") # Test orchestrator metrics metrics = orchestrator.get_performance_metrics() logger.info(f"[SUCCESS] Orchestrator metrics: {metrics}") logger.info("Modular orchestrator test completed successfully!") except Exception as e: logger.error(f"Error in orchestrator test: {e}") import traceback logger.error(traceback.format_exc()) raise async def main(): """Main entry point""" parser = argparse.ArgumentParser(description='Clean Trading System') parser.add_argument('--mode', choices=['trade', 'train', 'web', 'test', 'orchestrator'], default='test', help='Mode to run the system in') parser.add_argument('--symbol', type=str, help='Override default symbol') parser.add_argument('--config', type=str, default='config.yaml', help='Configuration file path') args = parser.parse_args() # Setup logging setup_logging() try: logger.info("=" * 60) logger.info("CLEAN TRADING SYSTEM STARTING") logger.info("=" * 60) # Run appropriate mode if args.mode == 'test': run_data_test() elif args.mode == 'orchestrator': run_orchestrator_test() else: logger.info(f"Mode '{args.mode}' not yet implemented in clean architecture") except KeyboardInterrupt: logger.info("System shutdown requested by user") except Exception as e: logger.error(f"Fatal error: {e}") import traceback logger.error(traceback.format_exc()) return 1 logger.info("Clean Trading System finished") return 0 if __name__ == "__main__": sys.exit(asyncio.run(main()))