real_trader/src/core/app_state.py
2025-05-16 14:12:20 +08:00

148 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
应用核心状态管理和基础交易逻辑。
包含全局交易实例、日志记录器以及登录/登出等核心功能。
"""
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("交易实例已销毁")