fix: 限价单后撤单下市价单没有工作
This commit is contained in:
parent
e79d622b2c
commit
9736919a49
@ -4,6 +4,8 @@ from abc import ABC, abstractmethod
|
|||||||
from logger_config import get_logger
|
from logger_config import get_logger
|
||||||
from position_manager import PositionManager
|
from position_manager import PositionManager
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
from config import Config
|
||||||
|
import os
|
||||||
|
|
||||||
# 获取日志记录器
|
# 获取日志记录器
|
||||||
|
|
||||||
@ -14,6 +16,7 @@ class BaseTrader(ABC):
|
|||||||
"""初始化交易基类"""
|
"""初始化交易基类"""
|
||||||
self.position_managers: Dict[str, PositionManager] = {}
|
self.position_managers: Dict[str, PositionManager] = {}
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
|
self._load_all_position_managers_from_data_dir() # 新增:自动加载所有持仓管理器
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -230,3 +233,18 @@ class BaseTrader(ABC):
|
|||||||
self.position_managers[strategy_name].clear()
|
self.position_managers[strategy_name].clear()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _load_all_position_managers_from_data_dir(self):
|
||||||
|
"""从Config.DATA_DIR目录下的持仓文件自动加载所有PositionManager"""
|
||||||
|
data_dir = Config.DATA_DIR
|
||||||
|
if not os.path.exists(data_dir):
|
||||||
|
self.logger.info(f"持仓数据目录不存在: {data_dir}")
|
||||||
|
return
|
||||||
|
for fname in os.listdir(data_dir):
|
||||||
|
if fname.endswith('_positions.json'):
|
||||||
|
strategy_name = fname[:-len('_positions.json')]
|
||||||
|
try:
|
||||||
|
self.position_managers[strategy_name] = PositionManager(strategy_name)
|
||||||
|
self.logger.info(f"已自动加载策略持仓: {strategy_name}")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"加载策略持仓失败: {strategy_name}, 错误: {e}")
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import schedule
|
import schedule
|
||||||
import weakref
|
|
||||||
from xtquant import xtconstant
|
from xtquant import xtconstant
|
||||||
from logger_config import get_logger
|
from logger_config import get_logger
|
||||||
from config import Config
|
from config import Config
|
||||||
@ -43,7 +42,7 @@ class RealTraderManager:
|
|||||||
position_manager: StrategyPositionManager实例
|
position_manager: StrategyPositionManager实例
|
||||||
"""
|
"""
|
||||||
# 使用传入的trader实例,使用弱引用避免循环引用
|
# 使用传入的trader实例,使用弱引用避免循环引用
|
||||||
self.trader = weakref.proxy(trader)
|
self.trader = trader
|
||||||
|
|
||||||
# 启动调度器
|
# 启动调度器
|
||||||
self._start_scheduler()
|
self._start_scheduler()
|
||||||
@ -159,12 +158,7 @@ class RealTraderManager:
|
|||||||
f"已提交订单: ID={order_id}, 策略={strategy_name}, 代码={code}, 方向={direction}, 数量={amount}, 价格={price}, 类型={order_type}"
|
f"已提交订单: ID={order_id}, 策略={strategy_name}, 代码={code}, 方向={direction}, 数量={amount}, 价格={price}, 类型={order_type}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 设置60秒后检查订单状态
|
threading.Timer(60, self.check_and_retry, args=(order_id, strategy_name)).start()
|
||||||
threading.Timer(
|
|
||||||
60,
|
|
||||||
self.check_and_retry,
|
|
||||||
args=(order_id, strategy_name)
|
|
||||||
).start()
|
|
||||||
|
|
||||||
return {"success": True, "order_id": order_id}
|
return {"success": True, "order_id": order_id}
|
||||||
|
|
||||||
@ -205,56 +199,62 @@ class RealTraderManager:
|
|||||||
order_id: 订单ID
|
order_id: 订单ID
|
||||||
strategy_name: 策略名称
|
strategy_name: 策略名称
|
||||||
"""
|
"""
|
||||||
position_manager = self.trader.get_position_manager(strategy_name)
|
try:
|
||||||
order_info = position_manager.get_pending_order(order_id)
|
logger.info(f"开始检查订单状态: ID={order_id}, 策略={strategy_name}")
|
||||||
if not order_info:
|
position_manager = self.trader.get_position_manager(strategy_name)
|
||||||
logger.warning(f"订单信息不存在, 可能全部完成或者撤单: ID={order_id}")
|
order_info = position_manager.get_pending_order(order_id)
|
||||||
return
|
if not order_info:
|
||||||
|
logger.warning(f"订单信息不存在, 可能全部完成或者撤单: ID={order_id}")
|
||||||
|
return
|
||||||
|
|
||||||
order_type = order_info.order_type
|
order_type = order_info.order_type
|
||||||
|
|
||||||
# 使用trader的handle_order_update方法更新订单状态
|
# 使用trader的handle_order_update方法更新订单状态
|
||||||
status = self.trader.handle_order_update(order_id, strategy_name)
|
status = self.trader.handle_order_update(order_id, strategy_name)
|
||||||
|
|
||||||
# 如果状态为None,说明处理失败,则直接返回
|
# 如果状态为None,说明处理失败,则直接返回
|
||||||
if status is None:
|
if status is None:
|
||||||
logger.warning(f"订单状态更新失败: ID={order_id}")
|
logger.warning(f"订单状态更新失败: ID={order_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 重新获取订单信息,因为可能已经被更新
|
# 重新获取订单信息,因为可能已经被更新
|
||||||
order_info = position_manager.get_pending_order(order_id)
|
order_info = position_manager.get_pending_order(order_id)
|
||||||
if not order_info:
|
if not order_info:
|
||||||
logger.info(f"订单已完成: ID={order_id}")
|
logger.info(f"订单已完成: ID={order_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
if order_type == ORDER_TYPE_MARKET:
|
if order_type == ORDER_TYPE_MARKET:
|
||||||
# 市价单,如果未完成则继续检查
|
# 市价单,如果未完成则继续检查
|
||||||
if status in [ORDER_STATUS_PENDING, ORDER_STATUS_PARTIAL]:
|
if status in [ORDER_STATUS_PENDING, ORDER_STATUS_PARTIAL]:
|
||||||
logger.info(f"市价单未完成,60秒后继续检查: ID={order_id}, 状态={status}")
|
logger.info(f"市价单未完成,60秒后继续检查: ID={order_id}, 状态={status}")
|
||||||
threading.Timer(60, self.check_and_retry, args=(order_id, strategy_name)).start()
|
schedule.every(60).seconds.do(
|
||||||
|
run_threaded(self.check_and_retry), order_id, strategy_name
|
||||||
|
).tag(f"order_{order_id}")
|
||||||
|
else:
|
||||||
|
logger.info(f"市价单已完成: ID={order_id}, 状态={status}")
|
||||||
|
elif order_type == ORDER_TYPE_LIMIT:
|
||||||
|
filled = order_info.filled
|
||||||
|
target_amount = order_info.amount
|
||||||
|
left_amount = target_amount - filled
|
||||||
|
|
||||||
|
# 限价单,这是60秒后的检查,如果未完成则撤单补市价单
|
||||||
|
if status in [ORDER_STATUS_PENDING, ORDER_STATUS_PARTIAL]:
|
||||||
|
# 尝试撤单
|
||||||
|
try:
|
||||||
|
logger.info(f"限价单60秒后仍未完成,尝试撤单: ID={order_id}, 状态={status}")
|
||||||
|
self.trader.cancel(order_id)
|
||||||
|
position_manager.update_order_status(order_id, filled, ORDER_STATUS_CANCELLED)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"撤单失败: order_id={order_id}, error={str(e)}")
|
||||||
|
|
||||||
|
# 计算剩余数量, 如果剩余数量大于0, 则补单
|
||||||
|
self._place_market_order_for_remainder(strategy_name, order_info.code, order_info.direction, left_amount)
|
||||||
|
else:
|
||||||
|
logger.info(f"限价单已完成: ID={order_id}, 状态={status}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"市价单已完成: ID={order_id}, 状态={status}")
|
logger.warning(f"未知订单类型: ID={order_id}, type={order_type}")
|
||||||
elif order_type == ORDER_TYPE_LIMIT:
|
except Exception as e:
|
||||||
filled = order_info.filled
|
logger.error(f"检查订单状态时发生异常: ID={order_id}, error={str(e)}", exc_info=True)
|
||||||
target_amount = order_info.amount
|
|
||||||
left_amount = target_amount - filled
|
|
||||||
|
|
||||||
# 限价单,这是60秒后的检查,如果未完成则撤单补市价单
|
|
||||||
if status in [ORDER_STATUS_PENDING, ORDER_STATUS_PARTIAL]:
|
|
||||||
# 尝试撤单
|
|
||||||
try:
|
|
||||||
logger.info(f"限价单60秒后仍未完成,尝试撤单: ID={order_id}, 状态={status}")
|
|
||||||
self.trader.cancel(order_id)
|
|
||||||
position_manager.update_order_status(order_id, filled, ORDER_STATUS_CANCELLED)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"撤单失败: order_id={order_id}, error={str(e)}")
|
|
||||||
|
|
||||||
# 计算剩余数量, 如果剩余数量大于0, 则补单
|
|
||||||
self._place_market_order_for_remainder(strategy_name, order_info.code, order_info.direction, left_amount)
|
|
||||||
else:
|
|
||||||
logger.info(f"限价单已完成: ID={order_id}, 状态={status}")
|
|
||||||
else:
|
|
||||||
logger.warning(f"未知订单类型: ID={order_id}, type={order_type}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ class MyXtQuantTraderCallback:
|
|||||||
# 使用trader的方法来处理订单状态更新,避免直接调用real_trader_manager
|
# 使用trader的方法来处理订单状态更新,避免直接调用real_trader_manager
|
||||||
self.trader_instance.handle_order_update(order_id, strategy_name)
|
self.trader_instance.handle_order_update(order_id, strategy_name)
|
||||||
logger.info(f"成交回报触发订单状态更新: ID={order_id}, 策略={strategy_name}")
|
logger.info(f"成交回报触发订单状态更新: ID={order_id}, 策略={strategy_name}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"成交回报触发订单状态更新失败: 根据order id未找到策略名 ID={order_id}, 策略={strategy_name}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"成交回报处理异常: {str(e)}", exc_info=True)
|
logger.error(f"成交回报处理异常: {str(e)}", exc_info=True)
|
||||||
def on_stock_position(self, position):
|
def on_stock_position(self, position):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user