| | |
| | | __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 |
| | | # 请求报单 |
| | |
| | | req_field.Direction = traderapi.TORA_TSTP_D_Buy |
| | | req_field.VolumeTotalOriginal = count |
| | | req_field.SInfo = sinfo |
| | | req_field.OrderRef = order_ref |
| | | |
| | | ''' |
| | | 上交所支持限价指令和最优五档剩撤、最优五档剩转限两种市价指令,对于科创板额外支持本方最优和对手方最优两种市价指令和盘后固定价格申报指令 |
| | |
| | | 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 |
| | | # 请求撤单 |
| | |
| | | # 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报单操作引用,用法同报单引用,可根据需要选填 |
| | | |
| | |
| | | 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: |
| | | # 查询股东账号 |
| | |
| | | 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, |
| | |
| | | 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: |
| | |
| | | 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: |
| | |
| | | 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) |
| | |
| | | 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) |
| | | # 测试 |