import os import time import logging import pandas as pd import numpy as np import signal import sys import requests import json import hashlib import hmac import base64 import schedule from datetime import datetime, timezone, timedelta from dotenv import load_dotenv from logging.handlers import RotatingFileHandler from okxapiclient import OKXAPIClient from multistrategyrunner import MultiStrategyRunner # Load environment variables load_dotenv() def setup_logging(): """Configure logging system""" # Set environment variable to ensure UTF-8 encoding os.environ['PYTHONIOENCODING'] = 'utf-8' # Create formatter formatter = logging.Formatter( '%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # File handler - using UTF-8 encoding file_handler = RotatingFileHandler( 'trading_system.log', maxBytes=10 * 1024 * 1024, backupCount=5, encoding='utf-8' ) file_handler.setFormatter(formatter) file_handler.setLevel(logging.INFO) # Console handler - handle encoding issues class SafeStreamHandler(logging.StreamHandler): def emit(self, record): try: msg = self.format(record) stream = self.stream if hasattr(stream, 'buffer'): stream.buffer.write(msg.encode('utf-8') + b'\n') stream.buffer.flush() else: stream.write(msg + self.terminator) self.flush() except UnicodeEncodeError: safe_msg = msg.encode('ascii', 'ignore').decode('ascii') stream.write(safe_msg + self.terminator) self.flush() except Exception: self.handleError(record) console_handler = SafeStreamHandler() console_handler.setFormatter(formatter) console_handler.setLevel(logging.INFO) # Configure root logger logging.basicConfig( level=logging.INFO, handlers=[file_handler, console_handler] ) return logging.getLogger(__name__) logger = setup_logging() def _handle_sigterm(runner): def _h(_sig, _frm): print("SIGTERM received, stopping strategies...") try: runner.stop_all_strategies() finally: sys.exit(0) return _h def main(): """Main function""" print("=" * 60) print(" " * 20 + "Multi-Currency Intelligent Trading System") print("=" * 60) print("Core Features:") print(" • DeepSeek AI Driven Decisions") print(" • KDJ + RSI + ATR Technical Indicators") print(" • Multi-level Risk Control") print(" • Position Status Persistence") print("=" * 60) # Check environment variables required_env_vars = ['OKX_API_KEY', 'OKX_SECRET_KEY', 'OKX_PASSWORD'] if not all(os.getenv(var) for var in required_env_vars): print("❌ Please set OKX API environment variables") return # Create strategy runner runner = MultiStrategyRunner() if os.getenv("SERVICE_MODE") == "1": print("Starting in SERVICE_MODE (no menu)…") signal.signal(signal.SIGTERM, _handle_sigterm(runner)) signal.signal(signal.SIGINT, _handle_sigterm(runner)) runner.start_all_strategies() while True: time.sleep(5) # Add debug mode switch debug_mode = False def toggle_debug_mode(): nonlocal debug_mode debug_mode = not debug_mode runner.api.log_http = debug_mode print(f"Debug mode {'enabled' if debug_mode else 'disabled'}") try: while True: print("\n" + "=" * 50) print(" " * 15 + "Trading System Control Panel") print("=" * 50) print("1. Start All Strategies") print("2. Start Specific Strategy") print("3. Stop All Strategies") print("4. Stop Specific Strategy") print("5. View System Status") print("6. Manual Position Sync") print("7. Toggle Debug Mode") print("8. Exit System") print("=" * 50) choice = input("Please enter choice (1-8): ").strip() if choice == '1': print("Starting all trading strategies...") runner.start_all_strategies() print("✅ All strategies started") elif choice == '2': print("\nSelect currency to start:") symbols = list(runner.symbol_configs.keys()) for i, symbol in enumerate(symbols, 1): config = runner.symbol_configs[symbol] print(f"{i}. {symbol} ({config['name']})") print(f"{len(symbols)+1}. Back") symbol_choice = input("Please enter choice: ").strip() if symbol_choice.isdigit(): index = int(symbol_choice) - 1 if 0 <= index < len(symbols): symbol = symbols[index] runner.start_strategy(symbol) print(f"✅ Started {symbol} strategy") elif index == len(symbols): continue else: print("❌ Invalid choice") else: print("❌ Invalid input") elif choice == '3': print("Stopping all trading strategies...") runner.stop_all_strategies() print("✅ All strategies stopped") elif choice == '4': print("\nSelect currency to stop:") symbols = list(runner.symbol_configs.keys()) for i, symbol in enumerate(symbols, 1): config = runner.symbol_configs[symbol] print(f"{i}. {symbol} ({config['name']})") print(f"{len(symbols)+1}. Back") symbol_choice = input("Please enter choice: ").strip() if symbol_choice.isdigit(): index = int(symbol_choice) - 1 if 0 <= index < len(symbols): symbol = symbols[index] runner.stop_strategy(symbol) print(f"✅ Stopped {symbol} strategy") elif index == len(symbols): continue else: print("❌ Invalid choice") else: print("❌ Invalid input") elif choice == '5': status = runner.get_status() print(f"\nSystem Status: {'Running' if status['running'] else 'Stopped'}") print(f"Active Strategies: {len(status['active_strategies'])}") for symbol in status['active_strategies']: print(f" • {symbol}") print("\nPosition Status:") for symbol, detail in status['strategies_detail'].items(): base_amount = detail['base_amount'] entry_price = detail['entry_price'] if base_amount > 0: print(f" {symbol}: Position {base_amount:.10f} @ ${entry_price:.2f}") elif choice == '6': print("Manual sync all currency positions...") for symbol, strategy in runner.strategies.items(): strategy.sync_with_exchange() print("✅ Sync completed") elif choice == '7': toggle_debug_mode() elif choice == '8': print("Exiting system, please wait for all strategies to stop...") break else: print("❌ Invalid choice, please re-enter") except KeyboardInterrupt: print("\nReceived interrupt signal, exiting...") if __name__ == "__main__": main()