Administrator
2023-09-13 8ea6200de76e128b54ad51e75014b5fc051b55ca
huaxin_client/trade_client.py
@@ -83,15 +83,20 @@
    __cancel_buy_sinfo_set = set()
    __cancel_sell_sinfo_set = set()
    @classmethod
    def set_login_info(cls, session_id, front_id):
        cls.__session_id = session_id
        cls.__front_id = front_id
    # sinfo char(32)
    def buy(self, code, count, price, sinfo):
    def buy(self, code, count, price, sinfo, order_ref):
        if not ENABLE_ORDER:
            return
        if sinfo in self.__buy_sinfo_set:
            raise Exception(f'下单请求已经提交:{sinfo}')
        async_log_util.info(logger_trade, f"{code}华鑫本地真实下单开始")
        async_log_util.info(logger_local_huaxin_trade_debug,
                            f"进入买入方法:code-{code} sinfo-{sinfo}")
                            f"进入买入方法:code-{code} sinfo-{sinfo} order_ref-{order_ref}")
        self.__buy_sinfo_set.add(sinfo)
        self.req_id += 1
        # 请求报单
@@ -113,6 +118,7 @@
        req_field.Direction = traderapi.TORA_TSTP_D_Buy
        req_field.VolumeTotalOriginal = count
        req_field.SInfo = sinfo
        req_field.OrderRef = order_ref
        '''
        上交所支持限价指令和最优五档剩撤、最优五档剩转限两种市价指令,对于科创板额外支持本方最优和对手方最优两种市价指令和盘后固定价格申报指令
@@ -153,11 +159,11 @@
        return
    # 撤买
    def cancel_buy(self, code, order_sys_id, sinfo):
    def cancel_buy(self, code, sinfo, order_sys_id=None, order_ref=None):
        if sinfo in self.__cancel_buy_sinfo_set:
            raise Exception(f'撤单请求已经提交:{sinfo}')
        async_log_util.info(logger_local_huaxin_trade_debug,
                            f"进入撤单方法:code-{code} order_sys_id-{order_sys_id} sinfo-{sinfo}")
                            f"进入撤单方法:code-{code} order_sys_id-{order_sys_id}  order_ref-{order_ref} sinfo-{sinfo}")
        self.__cancel_buy_sinfo_set.add(sinfo)
        self.req_id += 1
        # 请求撤单
@@ -175,7 +181,12 @@
        # req_field.SessionID = self.__session_id
        # req_field.OrderRef = 1
        # (2)系统报单编号方式
        req_field.OrderSysID = order_sys_id
        if order_sys_id:
            req_field.OrderSysID = order_sys_id
        elif order_ref is not None:
            req_field.OrderRef = order_ref
            req_field.SessionID = self.__session_id
            req_field.FrontID = self.__front_id
        # OrderActionRef报单操作引用,用法同报单引用,可根据需要选填
@@ -489,6 +500,7 @@
            logger.info('Login success! [%d]' % nRequestID)
            self.__front_id = pRspUserLoginField.FrontID
            self.__session_id = pRspUserLoginField.SessionID
            TradeSimpleApi.set_login_info(self.__session_id, self.__front_id)
            if 0:
                # 查询股东账号
@@ -603,8 +615,6 @@
                                   pOrderField.OrderRef, pOrderField.OrderLocalID,
                                   pOrderField.LimitPrice, pOrderField.VolumeTotalOriginal, pOrderField.OrderSysID,
                                   pOrderField.OrderStatus, pOrderField.InsertTime))
            OrderIDManager.set_system_order_id(pOrderField.SecurityID, pOrderField.SInfo, pOrderField.OrderSysID)
            if pOrderField.OrderStatus != traderapi.TORA_TSTP_OST_Unknown:
                order_data = {"sinfo": pOrderField.SInfo, "securityID": pOrderField.SecurityID,
                              "orderLocalID": pOrderField.OrderLocalID,
@@ -820,14 +830,14 @@
            volume = data["volume"]
            price = data["price"]
            sinfo = data["sinfo"]
            local_order_id = data.get("local_order_id")
            order_ref = data.get("order_ref")
            if direction == 1:
                async_log_util.info(logger_trade, f"{code}华鑫本地开始下单")
                # 买
                try:
                    req_rid_dict[sinfo] = (client_id, request_id, sk, local_order_id)
                    threading.Thread(target=lambda: self.__tradeSimpleApi.buy(code, volume, price, sinfo),
                    req_rid_dict[sinfo] = (client_id, request_id, sk, order_ref)
                    threading.Thread(target=lambda: self.__tradeSimpleApi.buy(code, volume, price, sinfo, order_ref),
                                     daemon=True).start()
                    async_log_util.info(logger_trade, f"{code}华鑫本地下单线程结束")
                except Exception as e:
@@ -853,19 +863,15 @@
            direction = data["direction"]
            code = data["code"]
            orderSysID = data.get("orderSysID")
            localOrderID = data.get("localOrderID")
            orderRef = data.get("orderRef")
            sinfo = data["sinfo"]
            if direction == 1:
                if not orderSysID and localOrderID:
                    orderSysID = OrderIDManager.get_system_id_by_local_id(localOrderID)
                # 撤买
                try:
                    if not orderSysID:
                        if localOrderID:
                            OrderIDManager.add_need_cancel_local_order_id(localOrderID)
                        raise Exception("没有找到系统订单号")
                    if not orderSysID and orderRef is None:
                        raise Exception("没有找到系统订单号或者报单引用")
                    req_rid_dict[sinfo] = (client_id, request_id, sk)
                    self.__tradeSimpleApi.cancel_buy(code, orderSysID, sinfo)
                    self.__tradeSimpleApi.cancel_buy(code, sinfo, order_sys_id=orderSysID, order_ref=orderRef)
                    async_log_util.info(logger_local_huaxin_trade_debug,
                                        f"撤单结束:code-{code} order_sys_id-{orderSysID} sinfo-{sinfo}")
                except Exception as e:
@@ -999,51 +1005,6 @@
    else:
        strategy_pipe.send(data)
# 订单号管理
class OrderIDManager:
    # 尚未撤单的本地订单号
    not_canceled_local_order_ids = set()
    local_order_id_map = {}
    __TradeSimpleApi = TradeSimpleApi()
    @classmethod
    def get_system_id_by_local_id(cls, local_order_id):
        return cls.local_order_id_map.get(local_order_id)
    # 设置系统订单ID
    @classmethod
    def set_system_order_id(cls, code, sinfo, orderSystemId):
        # 获取本地订单ID
        local_order_id = None
        if req_rid_dict and sinfo in req_rid_dict:
            temp_params = req_rid_dict.get(sinfo)
            if len(temp_params) > 3:
                local_order_id = temp_params[3]
        if local_order_id:
            if local_order_id not in cls.local_order_id_map and orderSystemId:
                cls.local_order_id_map[local_order_id] = orderSystemId
                async_log_util.info(logger_local_huaxin_trade_debug,
                                    f"本地订单号与系统订单号映射,{code}:{local_order_id} {orderSystemId}")
            if local_order_id in cls.not_canceled_local_order_ids:
                async_log_util.info(logger_local_huaxin_trade_debug, f"执行等待撤单,{code}:{local_order_id} {orderSystemId}")
                # 执行撤单
                cls.not_canceled_local_order_ids.discard(local_order_id)
                for i in range(3):
                    try:
                        cls.__TradeSimpleApi.cancel_buy(code, orderSystemId,
                                                        f"lcb-{code}-{round(time.time() * 1000)}")
                        break
                    except Exception as e:
                        logger_local_huaxin_trade_debug.exception(e)
                        time.sleep(0.01)
    @classmethod
    def add_need_cancel_local_order_id(cls, local_order_id):
        cls.not_canceled_local_order_ids.add(local_order_id)
# 交易反馈回调
def __traderapi_callback(type, req_id, data):
    async_log_util.info(logger_local_huaxin_trade_debug, "回调:type-{} req_id-{}", type, req_id)
@@ -1056,8 +1017,8 @@
            client_id, request_id = temp_params[0], temp_params[1]
            # 本地订单号-系统订单号映射
            if len(temp_params) >= 4 and type == TYPE_ORDER:
                local_order_id = temp_params[3]
                data["localOrderId"] = local_order_id
                order_ref = temp_params[3]
                data["orderRef"] = order_ref
            async_log_util.info(logger_local_huaxin_trade_debug, "API回调 request_id-{}", request_id)
            # 测试