From 0d491d14e35e7e431e3720da8635ffea38cc8c09 Mon Sep 17 00:00:00 2001 From: zhiyong Date: Sun, 11 May 2025 02:24:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=9B=98=E7=99=BB=E9=99=86?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5,=20=E5=8F=91=E9=80=81=E9=82=AE=E4=BB=B6,=20?= =?UTF-8?q?=E5=B9=B6=E6=AF=8F=E5=B0=8F=E6=97=B6=E5=B0=9D=E8=AF=95=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config.py | 2 +- src/real/xt_trader.py | 62 ++++++++++++++++++++++++++++---------- src/trade_server.py | 70 +++++++++++++++++++++++++++++++++---------- 3 files changed, 102 insertions(+), 32 deletions(-) diff --git a/src/config.py b/src/config.py index 0570656..5e2ee0c 100644 --- a/src/config.py +++ b/src/config.py @@ -9,7 +9,7 @@ class Config: # Trading settings TRADE_TIMEOUT = 5 # 交易超时时间(秒) - SIMULATION_MODE = True + SIMULATION_MODE = False # Trading hours MARKET_OPEN_TIME = "09:20" diff --git a/src/real/xt_trader.py b/src/real/xt_trader.py index 6e7d1b3..a614c3e 100644 --- a/src/real/xt_trader.py +++ b/src/real/xt_trader.py @@ -16,7 +16,7 @@ logger = get_logger('real_trader') class MyXtQuantTraderCallback: def __init__(self, trader_instance): - self.trader_instance: XtTrader = trader_instance + self.trader_instance = trader_instance def on_connected(self): logger.info("连接成功") def on_disconnected(self): @@ -102,16 +102,44 @@ class XtTrader(BaseTrader): return self.is_logged_in() and not self.connection_failed def login(self): - if not self.started: - self.xt_trader.start() - self.started = True - if not self.connected: - result = self.xt_trader.connect() - self.connected = (result == 0) - if not self.subscribed: - result = self.xt_trader.subscribe(self.account) - self.subscribed = (result == 0) - return self.connected and self.subscribed + """尝试登录交易系统 + + Returns: + bool: 登录是否成功 + """ + success = True + + try: + if not self.started: + self.xt_trader.start() + self.started = True + + if not self.connected: + result = self.xt_trader.connect() + self.connected = (result == 0) + if not self.connected: + success = False + + if not self.subscribed and self.connected: + result = self.xt_trader.subscribe(self.account) + self.subscribed = (result == 0) + if not self.subscribed: + success = False + + # 登录失败,设置失败状态 + if not success: + self.connection_failed = True + self.last_reconnect_time = time.time() + self.notify_connection_failure("登录失败") + + return success + except Exception as e: + logger.error(f"登录异常: {str(e)}") + # 设置失败状态 + self.connection_failed = True + self.last_reconnect_time = time.time() + self.notify_connection_failure(f"登录异常: {str(e)}") + return False def logout(self): if self.started: @@ -347,9 +375,13 @@ class XtTrader(BaseTrader): logger.error(f"获取行情失败: {code}, {str(e)}") return None - def notify_connection_failure(self): - """通知交易连接失败""" - self.connection_error_message = f"交易系统连接失败,将在{self.reconnect_interval//60}分钟后自动尝试重连" + def notify_connection_failure(self, message="交易连接断开且重连失败"): + """通知交易连接失败 + + Args: + message: 错误信息 + """ + self.connection_error_message = f"交易系统连接失败:{message},将在{self.reconnect_interval//60}分钟后自动尝试重连" # 调用回调通知上层应用 if self.connect_failed_callback: @@ -364,7 +396,7 @@ class XtTrader(BaseTrader): 时间:{time_str} {trader_info} -错误信息:交易连接断开且重连失败 +错误信息:{message} 系统将在{self.reconnect_interval//60}分钟后自动尝试重连。如需立即恢复,请手动重启交易系统。 """ diff --git a/src/trade_server.py b/src/trade_server.py index 7314606..cf42b3f 100644 --- a/src/trade_server.py +++ b/src/trade_server.py @@ -49,9 +49,9 @@ def get_trader(): return _trader_instance def login(): + global _trader_instance + try: - global _trader_instance - # 如果已经有实例,先销毁 if _trader_instance is not None and is_real_mode(): _trader_instance.logout() @@ -61,16 +61,40 @@ def login(): _trader_instance = SimulationTrader() if Config.SIMULATION_MODE else XtTrader(connect_failed_callback=on_connect_failed) logger.info("开始登录") - _trader_instance.login() - result = _trader_instance.get_balance() - if result and result["account_id"] is not None: - logger.info(f"查询余额成功: {result}") + + # 模拟交易直接返回成功 + if Config.SIMULATION_MODE: + return True + + # 如果是实盘交易,调用login方法 + login_success = _trader_instance.login() + + # 验证连接 + if login_success: + result = _trader_instance.get_balance() + if result and result.get("account_id") is not None: + logger.info(f"查询余额成功: {result}") + return True + else: + logger.error(f"登录成功但查询余额失败: {result}") + _trader_instance.connection_failed = True + _trader_instance.last_reconnect_time = time.time() + _trader_instance.notify_connection_failure("登录成功但查询余额失败") + return False else: - logger.error(f"登录失败: {result}") - raise Exception(f"登录失败: {result}") + logger.error("登录失败") + # 不需要在这里设置失败状态,在XtTrader.login方法中已设置 + return False except Exception as e: - logger.error(f"登录失败: {e}") - raise Exception(f"登录失败: {e}") + logger.error(f"登录初始化异常: {str(e)}") + # 如果是实盘模式并且已经成功创建了实例,设置失败状态 + if is_real_mode() and _trader_instance is not None: + _trader_instance.connection_failed = True + _trader_instance.last_reconnect_time = time.time() + _trader_instance.notify_connection_failure(f"登录初始化异常: {str(e)}") + return False + # 如果创建实例失败,则抛出异常 + raise Exception(f"登录失败,无法创建交易实例: {e}") def logout(): global _trader_instance @@ -125,12 +149,26 @@ def _check_reconnect(): logger.error(f"重连检查错误: {str(e)}") -# 程序启动时初始化交易实例 -login() - - -# 设置并启动调度器 -setup_scheduler() +# 初始化交易系统 +try: + # 程序启动时初始化交易实例 - 尝试登录,但即使失败也继续启动服务 + login_success = login() + if not login_success and is_real_mode(): + logger.warning("初始登录失败,系统将在稍后定期尝试重连") + + # 设置并启动调度器 + setup_scheduler() + + logger.info("交易系统初始化完成") +except Exception as e: + logger.error(f"交易系统初始化异常: {e}") + # 即使初始化失败也尝试启动调度器 + try: + setup_scheduler() + logger.info("调度器启动成功,将尝试定期重新初始化交易系统") + except Exception as scheduler_e: + logger.error(f"调度器启动失败: {scheduler_e}") + raise app = Flask(__name__)