#!/usr/bin/env python3 """ 系统启动脚本 同时启动: 1. FastAPI 后端服务 (提供前端看板 API) 2. Polymarket 自动交易程序 支持平台:macOS, Linux, Windows """ import subprocess import sys import time import signal import os import platform from datetime import datetime # 检测操作系统 IS_WINDOWS = platform.system() == 'Windows' # 颜色代码 (Windows CMD 默认不支持 ANSI,但现代 Windows Terminal 支持) if IS_WINDOWS: # 尝试启用 Windows ANSI 支持 try: import ctypes kernel32 = ctypes.windll.kernel32 kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) ANSI_SUPPORTED = True except Exception: ANSI_SUPPORTED = False else: ANSI_SUPPORTED = True if ANSI_SUPPORTED: GREEN = '\033[92m' YELLOW = '\033[93m' RED = '\033[91m' RESET = '\033[0m' else: GREEN = YELLOW = RED = RESET = '' def log(message, color=RESET): timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') print(f"{color}[{timestamp}] {message}{RESET}") def start_process(command, name): """启动子进程(跨平台兼容)""" log(f"正在启动 {name}...", YELLOW) try: if IS_WINDOWS: # Windows: 不使用 preexec_fn,使用 CREATE_NEW_PROCESS_GROUP process = subprocess.Popen( command, shell=True, stdout=sys.stdout, stderr=sys.stderr, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP ) else: # macOS / Linux: 使用 setsid 创建新进程组 process = subprocess.Popen( command, shell=True, stdout=sys.stdout, stderr=sys.stderr, preexec_fn=os.setsid ) log(f"{name} 已启动 (PID: {process.pid})", GREEN) return process except Exception as e: log(f"启动 {name} 失败: {e}", RED) return None def terminate_process(process, name): """终止进程(跨平台兼容)""" if process is None: return try: if IS_WINDOWS: # Windows: 使用 terminate() 或发送 CTRL_BREAK_EVENT process.terminate() else: # macOS / Linux: 终止整个进程组 os.killpg(os.getpgid(process.pid), signal.SIGTERM) log(f"{name} 已停止", GREEN) except Exception as e: log(f"停止 {name} 时出错: {e}", RED) # 强制杀死 try: process.kill() except Exception: pass def main(): # 激活 Conda 环境 # 注意:在子进程中直接使用当前已激活的 python 解释器路径,避免 conda activate 问题 python_exec = sys.executable # 1. 启动 API 服务 (Uvicorn) # 使用 --host 0.0.0.0 允许局域网访问 api_cmd = f"{python_exec} -m uvicorn api.main:app --host 0.0.0.0 --port 8000" api_process = start_process(api_cmd, "API 服务 & 前端看板") # 等待几秒确保 API 启动 time.sleep(3) # 2. 启动自动交易程序 # 使用 -u 参数禁用输出缓冲 trade_cmd = f"{python_exec} -u trader/auto_trade_polymarket.py" trade_process = start_process(trade_cmd, "Polymarket 自动交易程序") log("系统启动完成!", GREEN) log("前端访问地址: http://localhost:8000", GREEN) log("按 Ctrl+C 停止所有服务...", YELLOW) try: # 监控子进程状态 while True: if api_process and api_process.poll() is not None: log("API 服务意外退出", RED) break if trade_process and trade_process.poll() is not None: log("自动交易程序意外退出", RED) break time.sleep(1) except KeyboardInterrupt: log("\n正在停止服务...", YELLOW) finally: # 优雅退出 terminate_process(api_process, "API 服务") terminate_process(trade_process, "自动交易程序") log("所有服务已停止", GREEN) if __name__ == "__main__": main()