diff --git a/src/base_trader.py b/src/base_trader.py index 435b5b8..4f326c2 100644 --- a/src/base_trader.py +++ b/src/base_trader.py @@ -141,6 +141,7 @@ class BaseTrader(ABC): """ pass + @staticmethod def is_trading_time(self): """判断当前是否为交易时间 @@ -170,8 +171,9 @@ class BaseTrader(ABC): except Exception as e: self.logger.error(f"判断交易时间发生错误: {str(e)}") return False - - def is_trading_date(self, date=None): + + @staticmethod + def is_trading_date(date=None): """判断指定日期是否为交易日 Args: @@ -189,7 +191,8 @@ class BaseTrader(ABC): return is_workday(date) except Exception as e: - self.logger.error(f"判断交易日期发生错误: {str(e)}") + logger = get_logger("BaseTrader") + logger.error(f"判断交易日期发生错误: {str(e)}") return False def get_position_manager(self, strategy_name) -> PositionManager: diff --git a/src/trade_server.py b/src/trade_server.py index 3de269a..ef66653 100644 --- a/src/trade_server.py +++ b/src/trade_server.py @@ -8,6 +8,7 @@ from simulation.simulation_trader import SimulationTrader from logger_config import get_logger from real.real_trader_manager import RealTraderManager from trade_constants import * +from base_trader import BaseTrader # 获取日志记录器 logger = get_logger("server") @@ -43,9 +44,25 @@ def get_real_trader_manager(): def get_trader(): global _trader_instance - if _trader_instance is None: - _trader_instance = SimulationTrader() if Config.SIMULATION_MODE else XtTrader(connect_failed_callback=on_connect_failed) - + # 实盘模式下 + if is_real_mode() and _trader_instance is None: + # 检查是否为交易日 + if not BaseTrader.is_trading_date(): + # 非交易日创建临时实例提供错误信息 + temp_trader = XtTrader(connect_failed_callback=on_connect_failed) + temp_trader.connection_failed = True + temp_trader.connection_error_message = "当前为非交易日,交易系统未连接" + return temp_trader + + # 交易日但非交易时间 + if not BaseTrader.is_trading_time(): + # 非交易时间创建临时实例提供错误信息 + temp_trader = XtTrader(connect_failed_callback=on_connect_failed) + temp_trader.connection_failed = True + temp_trader.connection_error_message = "当前为非交易时间,交易系统未连接" + return temp_trader + + # 返回已存在的实例 return _trader_instance def login(): @@ -109,25 +126,6 @@ def logout(): logger.info("XtTrader实例已销毁") -def setup_scheduler(): - # 设置每日任务 - schedule.every().day.at(Config.MARKET_OPEN_TIME).do(login) - schedule.every().day.at(Config.MARKET_CLOSE_TIME).do(logout) - - # 启动调度线程 - scheduler_thread = threading.Thread(target=_run_scheduler, daemon=True) - scheduler_thread.start() - logger.info("定时任务调度器已启动") - - # 启动重连检查线程(仅在实盘模式下) - if is_real_mode(): - reconnect_thread = threading.Thread(target=_check_reconnect, daemon=True) - reconnect_thread.start() - logger.info("重连检查线程已启动") - - return scheduler_thread - - def _run_scheduler(): """定时任务执行线程""" while True: @@ -149,6 +147,47 @@ def _check_reconnect(): logger.error(f"重连检查错误: {str(e)}") +# 定时任务:检查是否为交易日,并在交易日执行登录操作 +def login_on_trading_day(): + """仅在交易日执行登录操作""" + # 使用BaseTrader中的静态方法检查是否为交易日 + if BaseTrader.is_trading_date(): + logger.info("今天是交易日,执行登录操作") + login() + else: + logger.info("今天不是交易日,跳过登录操作") + + +# 定时任务:检查是否为交易日,并在交易日执行登出操作 +def logout_on_trading_day(): + """仅在交易日执行登出操作""" + # 使用BaseTrader中的静态方法检查是否为交易日 + if BaseTrader.is_trading_date(): + logger.info("今天是交易日,执行登出操作") + logout() + else: + logger.info("今天不是交易日,跳过登出操作") + + +def setup_scheduler(): + # 设置每日任务,仅在交易日执行 + schedule.every().day.at(Config.MARKET_OPEN_TIME).do(login_on_trading_day) + schedule.every().day.at(Config.MARKET_CLOSE_TIME).do(logout_on_trading_day) + + # 启动调度线程 + scheduler_thread = threading.Thread(target=_run_scheduler, daemon=True) + scheduler_thread.start() + logger.info("定时任务调度器已启动") + + # 启动重连检查线程(仅在实盘模式下) + if is_real_mode(): + reconnect_thread = threading.Thread(target=_check_reconnect, daemon=True) + reconnect_thread.start() + logger.info("重连检查线程已启动") + + return scheduler_thread + + # 初始化交易系统 try: # 程序启动时初始化交易实例 - 尝试登录,但即使失败也继续启动服务