feat: 实盘登陆失败, 发送邮件, 并每小时尝试连接

This commit is contained in:
zhiyong 2025-05-11 02:24:54 +08:00
parent 1c1b19383c
commit 0d491d14e3
3 changed files with 102 additions and 32 deletions

View File

@ -9,7 +9,7 @@ class Config:
# Trading settings
TRADE_TIMEOUT = 5 # 交易超时时间(秒)
SIMULATION_MODE = True
SIMULATION_MODE = False
# Trading hours
MARKET_OPEN_TIME = "09:20"

View File

@ -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):
"""尝试登录交易系统
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.subscribed:
if not self.connected:
success = False
if not self.subscribed and self.connected:
result = self.xt_trader.subscribe(self.account)
self.subscribed = (result == 0)
return self.connected and self.subscribed
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}分钟后自动尝试重连如需立即恢复请手动重启交易系统
"""

View File

@ -49,9 +49,9 @@ def get_trader():
return _trader_instance
def login():
try:
global _trader_instance
try:
# 如果已经有实例,先销毁
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()
# 模拟交易直接返回成功
if Config.SIMULATION_MODE:
return True
# 如果是实盘交易调用login方法
login_success = _trader_instance.login()
# 验证连接
if login_success:
result = _trader_instance.get_balance()
if result and result["account_id"] is not None:
if result and result.get("account_id") is not None:
logger.info(f"查询余额成功: {result}")
return True
else:
logger.error(f"登录失败: {result}")
raise Exception(f"登录失败: {result}")
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("登录失败")
# 不需要在这里设置失败状态在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()
# 初始化交易系统
try:
# 程序启动时初始化交易实例 - 尝试登录,但即使失败也继续启动服务
login_success = login()
if not login_success and is_real_mode():
logger.warning("初始登录失败,系统将在稍后定期尝试重连")
# 设置并启动调度器
setup_scheduler()
# 设置并启动调度器
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__)