"""
|
华鑫交易结果处理器
|
"""
|
import copy
|
import json
|
import time
|
|
from log_module import async_log_util
|
from log_module.log import logger_trade, hx_logger_trade_debug
|
from trade.huaxin_trade_record_manager import TradeOrderIdManager
|
from trade.sell_rule_manager import AutoCancelSellModeManager
|
|
from utils import huaxin_util, tool
|
import concurrent.futures
|
|
|
class HuaxinOrderEntity:
|
def __init__(self, code, orderStatus, orderRef, accountID, orderSysID, direction=None, insertDate=None,
|
insertTime=None,
|
acceptTime=None, is_shadow_order=False, sinfo=None):
|
self.code = code
|
self.orderStatus = orderStatus
|
self.orderRef = orderRef
|
self.accountID = accountID
|
self.orderSysID = orderSysID
|
self.insertTime = insertTime
|
self.insertDate = insertDate
|
self.acceptTime = acceptTime
|
self.direction = direction
|
self.is_shadow_order = is_shadow_order
|
self.sinfo = sinfo
|
|
|
class CancelOrderManager:
|
__canceling_order_dict = {}
|
__recancel_order_count = {}
|
|
__instance = None
|
|
def __new__(cls, *args, **kwargs):
|
if not cls.__instance:
|
cls.__instance = super(CancelOrderManager, cls).__new__(cls, *args, **kwargs)
|
return cls.__instance
|
|
# 开始撤单
|
def start_cancel(self, code, order_ref, order_sys_id):
|
if code not in self.__canceling_order_dict:
|
self.__canceling_order_dict[code] = set()
|
self.__canceling_order_dict[code].add(json.dumps((order_ref, order_sys_id, int(time.time() * 1000))))
|
|
def __cancel_finish(self, code, order_ref, order_sys_id):
|
if code not in self.__canceling_order_dict:
|
return
|
if not self.__canceling_order_dict[code]:
|
return
|
infos = copy.deepcopy(self.__canceling_order_dict[code])
|
for info in infos:
|
_info = json.loads(info)
|
if _info[0] == order_ref or _info[1] == order_sys_id:
|
# 匹配到目标数据
|
self.__canceling_order_dict[code].discard(info)
|
|
def __add_recancel_count(self, code, order_ref, order_sys_id):
|
key = f"{code}_{order_ref}_{order_sys_id}"
|
if key not in self.__recancel_order_count:
|
self.__recancel_order_count[key] = 0
|
self.__recancel_order_count[key] += 1
|
|
def __can_recancel(self, code, order_ref, order_sys_id):
|
key = f"{code}_{order_ref}_{order_sys_id}"
|
if key not in self.__recancel_order_count:
|
return True
|
return self.__recancel_order_count[key] < 2
|
|
# 撤单成功
|
def cancel_success(self, code, order_ref, order_sys_id):
|
self.__cancel_finish(code, order_ref, order_sys_id)
|
|
# 买入成功
|
def buy_success(self, code, order_ref, order_sys_id):
|
self.__cancel_finish(code, order_ref, order_sys_id)
|
|
# 传入重新下单
|
def run(self, re_cancel_method):
|
while True:
|
try:
|
if self.__canceling_order_dict:
|
for code in self.__canceling_order_dict:
|
infos = self.__canceling_order_dict[code]
|
infos = copy.deepcopy(infos)
|
for info in infos:
|
_info = json.loads(info)
|
timestamp = _info[2]
|
# 查询是否还能重新撤单
|
if not self.__can_recancel(code, _info[0], _info[1]):
|
self.__canceling_order_dict[code].discard(info)
|
continue
|
|
if time.time() * 1000 - timestamp > 100:
|
async_log_util.info(logger_trade, f"{code}触发重新撤单:{info}")
|
# 100ms后才进行
|
self.__add_recancel_count(code, _info[0], _info[1])
|
re_cancel_method(1, code, _info[1], orderRef=_info[0], recancel=True)
|
time.sleep(0.05)
|
except:
|
pass
|
|
|
class TradeResultProcessor:
|
__TradeOrderIdManager = TradeOrderIdManager()
|
__processed_keys = set()
|
__thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=50)
|
# 订单索引号字典
|
order_ref_dict = {}
|
|
# 返回是否要监控撤单
|
@classmethod
|
def is_need_watch_cancel(cls, order: HuaxinOrderEntity):
|
# 机器买入的不能撤单
|
if order.sinfo.find("ba_") == 0:
|
return False
|
|
# if order.direction != str(huaxin_util.TORA_TSTP_D_Sell):
|
# return False
|
cls.order_ref_dict[order.orderRef] = order
|
|
# 下单时间在9:30以后的如果2s没成交就撤单
|
if tool.trade_time_sub(order.insertTime, "09:30:00") >= 0 and str(
|
order.orderStatus) == huaxin_util.TORA_TSTP_OST_Accepted:
|
sell_mode = AutoCancelSellModeManager().get_mode_cache(order.code)
|
if sell_mode == AutoCancelSellModeManager.MODE_CANCEL_MECHINE:
|
# 不撤手动买入/卖出的单
|
if order.orderRef < 90000:
|
# 非系统单
|
return False
|
return False
|
return True
|
return False
|
|
@classmethod
|
def get_huaxin_order_by_order_ref(cls, order_ref) -> HuaxinOrderEntity:
|
return cls.order_ref_dict.get(order_ref)
|
|
@classmethod
|
def get_huaxin_sell_order_by_code(cls, code):
|
results = []
|
for k in cls.order_ref_dict:
|
entity = cls.order_ref_dict[k]
|
if entity.code == code and entity.direction == huaxin_util.TORA_TSTP_D_Sell:
|
results.append(entity)
|
return results
|
|
@classmethod
|
def order_success(cls, order: HuaxinOrderEntity):
|
async_log_util.info(hx_logger_trade_debug, f"处理华鑫订单下单成功:{order.code}, {order.orderRef}, {order.orderSysID}")
|
# 加入系统订单号
|
cls.__TradeOrderIdManager.add_order_id(order.code, order.accountID, order.orderSysID)
|
# 删除临时订单号
|
cls.__TradeOrderIdManager.remove_order_ref(order.code, order.orderRef)
|
return None
|
|
@classmethod
|
def cancel_order_success(cls, code, accountId, orderSysID):
|
cls.__TradeOrderIdManager.remove_order_id(code, accountId, orderSysID)
|
|
|
def cancel_order(direction, code, orderSysID, orderRef=None, blocking=False, sinfo=None, request_id=None,
|
recancel=False):
|
pass
|
|
|
if __name__ == "__main__":
|
CancelOrderManager().start_cancel("000333", 1, "123123")
|
# CancelOrderManager().cancel_success("000333", 1, "123123")
|
# CancelOrderManager().buy_success("000333", 1, "123123")
|
CancelOrderManager().run(cancel_order)
|