From 6a0d3ff5832e57ee1b1374d086f24b3c1679b332 Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期五, 05 九月 2025 18:22:24 +0800 Subject: [PATCH] bug修复/降低测撤单率 --- l2/place_order_single_data_manager.py | 143 +++++++++++++++++++++++++++++++++++------------ 1 files changed, 106 insertions(+), 37 deletions(-) diff --git a/l2/place_order_single_data_manager.py b/l2/place_order_single_data_manager.py index ab1ffd6..7d12cb4 100644 --- a/l2/place_order_single_data_manager.py +++ b/l2/place_order_single_data_manager.py @@ -16,6 +16,7 @@ """ __latest_sell_data = {} + # 鏈�杩戠殑娑ㄥ仠鍗栧鎵樺垪琛� __latest_limit_up_sell_list_dict = {} __latest_limit_up_sell_order_no_set_dict = {} @@ -55,15 +56,16 @@ if code not in cls.__latest_limit_up_sell_list_dict: cls.__latest_limit_up_sell_list_dict[code] = [] cls.__latest_limit_up_sell_list_dict[code].append(data) - async_log_util.info(logger_debug, f"娣诲姞娑ㄥ仠鍗栨暟鎹細{code}-{data}") + # async_log_util.info(logger_debug, f"娣诲姞娑ㄥ仠鍗栨暟鎹細{code}-{data}") if code not in cls.__latest_limit_up_sell_order_no_set_dict: cls.__latest_limit_up_sell_order_no_set_dict[code] = set() cls.__latest_limit_up_sell_order_no_set_dict[code].add(data['val']['orderNo']) # 鍙繚鐣欏墠20鐨勬暟鎹� if len(cls.__latest_limit_up_sell_list_dict[code]) > 20: + delete_datas = cls.__latest_limit_up_sell_list_dict[code][:-20] cls.__latest_limit_up_sell_list_dict[code] = cls.__latest_limit_up_sell_list_dict[code][-20:] # 鍒犻櫎涔嬪墠鐨刴ap - for d in cls.__latest_limit_up_sell_list_dict[code][0:-20]: + for d in delete_datas: cls.__latest_limit_up_sell_order_no_set_dict[code].discard(d["val"]["orderNo"]) @classmethod @@ -94,38 +96,41 @@ return len(sell_list) @classmethod - def process_passive_limit_up_sell_data(cls, code, datas, limit_up_price): + def process_passive_limit_up_sell_data(cls, code, fdatas): """ 娣诲姞娑ㄥ仠琚姩鍗栨垚浜ゆ暟鎹� - @param data: 鏁版嵁鏍煎紡锛�(data['SecurityID'], data['TradePrice'], data['TradeVolume'], + @param fdata: 鏁版嵁鏍煎紡锛�(data['SecurityID'], data['TradePrice'], data['TradeVolume'], # data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'], # data['SellNo'], data['ExecType']) - @return: + + [(鏁版嵁鏈韩, 鏄惁涓诲姩涔�, 鏄惁娑ㄥ仠, 鎬绘垚浜ら, 涓嶅惈ms鏃堕棿锛屽惈ms鏃堕棿)] + @return: 娑ㄥ仠鍗栨槸鍚﹀凡缁忓悆瀹� """ try: start_time = time.time() sell_list = cls.__latest_limit_up_sell_list_dict.get(code) if not sell_list: - return - sell_info = sell_list[-1] - for data in datas: + return False + last_sell_info = sell_list[-1] + for data in fdatas: # 杩囨护琚姩涔� - if data[6] < data[7]: + if not data[1]: # 鍑虹幇琚姩涔伴渶瑕佸皢鍘嗗彶澶у崟娓呯┖ if cls.__active_buy_order_datas_dict.get(code): cls.__active_buy_order_datas_dict[code].clear() continue + money = data[3] # 缁熻涔板崟鏁版嵁 if code not in cls.__latest_active_buy_order_data_dict: # [涔板崟鍙凤紝褰撳墠鎴愪氦鑲℃暟, 褰撳墠鎴愪氦閲戦, 寮�濮嬫椂闂�, 缁撴潫鏃堕棿] - cls.__latest_active_buy_order_data_dict[code] = [data[6], data[2], data[2] * data[1], data[3], - data[3]] + cls.__latest_active_buy_order_data_dict[code] = [data[0][6], data[0][2], money, data[0][3], + data[0][3]] else: - if data[6] == cls.__latest_active_buy_order_data_dict[code][0]: + if data[0][6] == cls.__latest_active_buy_order_data_dict[code][0]: # 鍚屼竴涔板崟鍙� - cls.__latest_active_buy_order_data_dict[code][1] += data[2] - cls.__latest_active_buy_order_data_dict[code][2] += data[2] * data[1] - cls.__latest_active_buy_order_data_dict[code][4] = data[3] + cls.__latest_active_buy_order_data_dict[code][1] += data[0][2] + cls.__latest_active_buy_order_data_dict[code][2] += money + cls.__latest_active_buy_order_data_dict[code][4] = data[0][3] else: # 涓嶅悓涔板崟鍙� if cls.__latest_active_buy_order_data_dict[code][2] >= 2990000: @@ -135,29 +140,30 @@ cls.__active_buy_order_datas_dict[code].append( cls.__latest_active_buy_order_data_dict[code]) - cls.__latest_active_buy_order_data_dict[code] = [data[6], data[2], data[2] * data[1], data[3], - data[3]] + cls.__latest_active_buy_order_data_dict[code] = [data[0][6], data[0][2], money, data[0][3], + data[0][3]] - if data[1] != limit_up_price: + if not data[2]: # 鎺掗櫎涓诲姩鍗�/闈炴定鍋滃崠 continue - sell_no = data[7] - if sell_no != sell_info['val']['orderNo']: + sell_no = data[0][7] + if sell_no != last_sell_info['val']['orderNo']: continue # 闇�瑕佸垽鏂綋鍓嶅崟鏄惁宸茬粡鎴愪氦瀹屾垚 if code not in cls.__latest_sell_data: - cls.__latest_sell_data[code] = [sell_no, data[2]] + cls.__latest_sell_data[code] = [sell_no, data[0][2]] else: if cls.__latest_sell_data[code][0] == sell_no: - cls.__latest_sell_data[code][1] += data[2] + cls.__latest_sell_data[code][1] += data[0][2] else: - cls.__latest_sell_data[code] = [sell_no, data[2]] - sell_info_num = sell_info['val']['num'] + cls.__latest_sell_data[code] = [sell_no, data[0][2]] + sell_info_num = last_sell_info['val']['num'] deal_num = cls.__latest_sell_data[code][1] // 100 if sell_info_num == deal_num: use_time = round((time.time() - start_time) * 1000, 3) l2_log.info(code, logger_l2_trade_buy, - f"鎵惧埌鏈�杩戠殑琚姩娑ㄥ仠鍗栧崟鏁版嵁锛歿sell_info['val']['orderNo']}, 鎴愪氦鏁版嵁锛歿data} 璁$畻鑰楁椂锛歿use_time}ms, 鍙互瑙﹀彂涓嬪崟") + f"鎵惧埌鏈�杩戠殑琚姩娑ㄥ仠鍗栧崟鏁版嵁锛歿last_sell_info['val']['orderNo']}, 鎴愪氦鏁版嵁锛歿data} 璁$畻鑰楁椂锛歿use_time}ms, 鍙互瑙﹀彂涓嬪崟") + # 灏嗗巻鍙插ぇ鍗曞垪琛ㄤ笌鏈�杩戠殑澶у崟鍔犲叆鍒楄〃 big_buy_order_datas = [] if code in cls.__active_buy_order_datas_dict: @@ -167,10 +173,65 @@ # 鎴愪氦瀹屾垚 L2TradeSingleDataManager.set_latest_sell_data(code, data, big_buy_order_datas) l2_log.info(code, logger_l2_trade_buy, "琚姩鍗栨暟鎹鐞嗗畬姣�") + if tool.is_sz_code(code): + # 娑ㄥ仠涓诲姩鍗栧凡缁忚鍚冨畬锛屽彲浠ユ竻闄� + return True break - # l2_log.info(code, logger_l2_trade_buy, f"鎵惧埌鏈�杩戠殑琚姩娑ㄥ仠鍗栧崟鏁版嵁锛歿data['val']['orderNo']}, 鍙互瑙﹀彂涓嬪崟") except Exception as e: logger_debug.exception(e) + return False + + @classmethod + def filter_last_limit_up_sell_data(cls, code, fdatas): + """ + 绛涢�夊嚭鏈�鍚庝竴鏉℃定鍋滃崠鎴愪氦鏁版嵁 + @param code: + @param fdatas: + @return: (鎴愪氦鏁版嵁, 鍗栧崟鏁版嵁) + """ + + def compute_last_sell(): + # 鏈�澶т拱鍗曞彿 + max_buy_order_no = fdatas[-1][0][6] + for i in range(len(sell_list) - 1, -1, -1): + if sell_list[i]['val']['orderNo'] > max_buy_order_no: + continue + return sell_list[i] + return None + + if not fdatas[-1][2]: + # 鏈�鍚庝竴鏉℃暟鎹笉鏄定鍋滄垚浜ゆ暟鎹� + return None + + sell_list = cls.__latest_limit_up_sell_list_dict.get(code) + if not sell_list: + return None + last_sell_info = compute_last_sell() + if not last_sell_info: + return None + for data in fdatas: + if not data[2]: + # 鎺掗櫎涓诲姩鍗�/闈炴定鍋滃崠 + continue + sell_no = data[0][7] + if sell_no != last_sell_info['val']['orderNo']: + continue + # 闇�瑕佸垽鏂綋鍓嶅崟鏄惁宸茬粡鎴愪氦瀹屾垚 + if code not in cls.__latest_sell_data: + cls.__latest_sell_data[code] = [sell_no, data[0][2]] + else: + if cls.__latest_sell_data[code][0] == sell_no: + cls.__latest_sell_data[code][1] += data[0][2] + else: + cls.__latest_sell_data[code] = [sell_no, data[0][2]] + sell_info_num = last_sell_info['val']['num'] + deal_num = cls.__latest_sell_data[code][1] // 100 + if sell_info_num == deal_num: + # 鏈�鍚庝竴绗旀定鍋滃崠宸茬粡鎴愪氦瀹屾垚 + l2_log.info(code, logger_l2_trade_buy, + f"鎵惧埌鏈�杩戠殑琚姩娑ㄥ仠鍗栧崟鏁版嵁锛歿last_sell_info}, 鎴愪氦鏁版嵁锛歿data} 鍙互瑙﹀彂涓嬪崟") + return data, last_sell_info + return None @classmethod def add_active_limit_up_sell_data(cls, data): @@ -205,12 +266,20 @@ @return: """ - def OnLimitUpActiveBuy(self, code, huaxin_timestamp, buy_no): + def OnLimitUpActiveBuy(self, code, transaction_data, no_left_limit_up_sell): """ 娑ㄥ仠涓诲姩涔拌Е鍙� @param code: - @param huaxin_timestamp: - @param buy_no: + @param transaction_data: 鎴愪氦鏁版嵁 + @param no_left_limit_up_sell: 鏄惁杩樺墿浣欐定鍋滃崠 + @return: + """ + + def OnLastLimitUpSellDeal(self, code, data): + """ + 鏈�鍚庝竴绗旀定鍋滃崠鎴愪氦 + @param code: 浠g爜 + @param data: 鎴愪氦鐨勬暟鎹� @return: """ @@ -235,28 +304,27 @@ cls.__callback = callback @classmethod - def set_latest_sell_data(cls, code, data, big_active_buy_order_datas): + def set_latest_sell_data(cls, code, fdata, big_active_buy_order_datas): """ 璁剧疆鏈�杩戞垚浜ょ殑娑ㄥ仠鍗栬鍔ㄦ垚浜ゆ暟鎹� @param code: 浠g爜 - @param data: L2閫愮瑪鎴愪氦鏁版嵁 鏁版嵁鏍煎紡锛�(data['SecurityID'], data['TradePrice'], data['TradeVolume'], + @param fdata: L2閫愮瑪鎴愪氦鏁版嵁 鏁版嵁鏍煎紡锛�(data['SecurityID'], data['TradePrice'], data['TradeVolume'], # data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'], # data['SellNo'], data['ExecType']) @param big_active_buy_order_datas: 澶т富鍔ㄤ拱鍗曟暟鎹細[[涔板崟鍙凤紝褰撳墠鎴愪氦鑲℃暟, 褰撳墠鎴愪氦閲戦, 寮�濮嬫椂闂�, 缁撴潫鏃堕棿],....] @return: """ - deal_time = l2_huaxin_util.convert_time(data[3], True) + deal_time = fdata[5] # 鐢熸晥鏃堕棿鍦�1s浠ュ唴 - cls.__latest_sell_data_dict[code] = (data, tool.trade_time_add_millionsecond(deal_time, 1000)) + cls.__latest_sell_data_dict[code] = (fdata[0], tool.trade_time_add_millionsecond(deal_time, 1000)) if cls.__callback: big_buy_order_count = 0 if big_active_buy_order_datas: for b in big_active_buy_order_datas: - if b[0] > data[7]: + if b[0] > fdata[0][7]: # 涔板崟鍦ㄥ崠鍗曚箣鍚� big_buy_order_count += 1 - cls.__callback.OnTradeSingle(code, big_buy_order_count, cls.TYPE_PASSIVE, cls.__latest_sell_data_dict[code]) @classmethod @@ -278,8 +346,9 @@ # cls.__callback.OnTradeSingle(code, 0, cls.TYPE_ACTIVE, cls.__latest_sell_active_deal_data_dict[code]) @classmethod - def set_limit_up_active_buy(cls, code, huaxin_timestamp, buy_no): - cls.__callback.OnLimitUpActiveBuy(code, huaxin_timestamp, buy_no) + def set_limit_up_active_buy(cls, code, transaction_datas, no_left_limit_up_sell): + if transaction_datas: + cls.__callback.OnLimitUpActiveBuy(code, transaction_datas, no_left_limit_up_sell) @classmethod def get_valid_trade_single(cls, code, latest_time_with_ms): -- Gitblit v1.8.0