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