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