231 lines
8.3 KiB
Python
231 lines
8.3 KiB
Python
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() |