""" 应用核心状态管理和基础交易逻辑。 包含全局交易实例、日志记录器以及登录/登出等核心功能。 """ import time from typing import Optional from config import Config # 使用相对导入 from logger_config import get_logger from real.xt_trader import XtTrader from simulation.simulation_trader import SimulationTrader from base_trader import BaseTrader from real.real_trader_manager import RealTraderManager # 确保导入 # 获取日志记录器 logger = get_logger("app_state") # 可以考虑是否需要区分 logger 名称 # 全局交易实例(采用单例模式) _trader_instance: Optional[BaseTrader] = None _real_trader_manager_instance: Optional[RealTraderManager] = None def is_real_mode() -> bool: """检查当前是否为实盘交易模式。""" return not Config.SIMULATION_MODE def on_connect_failed() -> None: """交易连接失败的回调函数。""" logger.critical("交易系统连接失败,API将返回错误状态") def get_trader() -> Optional[BaseTrader]: """ 获取交易实例(模拟或实盘)。 根据配置和当前时间(是否为交易日/交易时间),返回合适的交易实例。 在非交易日或非交易时间(实盘模式下),会返回一个临时的、标记为连接失败的实例。 Returns: Optional[BaseTrader]: 交易实例或 None。 """ global _trader_instance 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 get_real_trader_manager() -> Optional[RealTraderManager]: """ 获取实盘交易管理器单例。 如果当前为模拟模式,则返回 None。 Returns: Optional[RealTraderManager]: 实盘交易管理器实例或 None。 """ global _real_trader_manager_instance if _real_trader_manager_instance is None: current_trader = get_trader() if Config.SIMULATION_MODE: _real_trader_manager_instance = None elif current_trader is not None: _real_trader_manager_instance = RealTraderManager(current_trader) else: _real_trader_manager_instance = None return _real_trader_manager_instance def login() -> bool: """ 初始化并登录交易实例。 会根据配置(实盘/模拟)创建相应的交易实例并尝试登录。 Returns: bool: 登录是否成功。 Raises: Exception: 如果在实盘模式下创建实例失败。 """ global _trader_instance try: if _trader_instance is not None and is_real_mode(): # _trader_instance is BaseTrader or its child, which should have logout _trader_instance.logout() _trader_instance = None _trader_instance = SimulationTrader() if Config.SIMULATION_MODE else XtTrader(connect_failed_callback=on_connect_failed) logger.info("开始登录") if Config.SIMULATION_MODE: return True # _trader_instance is XtTrader here, which has login login_success = _trader_instance.login() if login_success: # _trader_instance is XtTrader here 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}") if _trader_instance: _trader_instance.connection_failed = True # BaseTrader property _trader_instance.last_reconnect_time = time.time() # BaseTrader property _trader_instance.notify_connection_failure("登录成功但查询余额失败") # BaseTrader method return False else: logger.error("登录失败") return False except Exception as 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() -> None: """登出并销毁交易实例。""" global _trader_instance if _trader_instance is not None: _trader_instance.logout() logger.info("登出成功") if is_real_mode(): _trader_instance = None logger.info("交易实例已销毁")