From 38395204ab04bbca22a5e22be988d826afd5b227 Mon Sep 17 00:00:00 2001
From: Administrator <admin@example.com>
Date: 星期四, 10 十一月 2022 15:46:27 +0800
Subject: [PATCH] 修复bug,优化下单

---
 l2_data_manager_new.py |  370 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 348 insertions(+), 22 deletions(-)

diff --git a/l2_data_manager_new.py b/l2_data_manager_new.py
index 4c01846..52f1f4f 100644
--- a/l2_data_manager_new.py
+++ b/l2_data_manager_new.py
@@ -1,4 +1,5 @@
 import datetime
+import json
 import logging
 import random
 import time as t
@@ -18,8 +19,8 @@
 import tool
 import trade_manager
 from l2_data_manager import L2DataException, TradePointManager, local_today_datas, L2DataUtil, load_l2_data, \
-    local_today_num_operate_map, L2LimitUpMoneyStatisticUtil
-from log import logger_l2_trade, logger_l2_trade_cancel, logger_l2_trade_buy, logger_l2_process
+    local_today_num_operate_map
+from log import logger_l2_trade, logger_l2_trade_cancel, logger_l2_trade_buy, logger_l2_process, logger_buy_1_volumn
 
 # TODO l2鏁版嵁绠$悊
 from trade_data_manager import CodeActualPriceProcessor
@@ -205,8 +206,6 @@
                 total_datas = local_today_datas[code]
                 __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time, "l2鏁版嵁棰勫鐞嗘椂闂�")
                 if len(add_datas) > 0:
-
-                    _start_time = round(t.time() * 1000)
                     latest_time = add_datas[len(add_datas) - 1]["val"]["time"]
                     # 鏃堕棿宸笉鑳藉お澶ф墠鑳藉鐞�
                     # TODO 鏆傛椂鍏抽棴澶勭悊
@@ -236,9 +235,12 @@
     # 澶勭悊鏈寕鍗�
     @classmethod
     def __process_not_order(cls, code, start_index, end_index, capture_time):
-        _start_time = t.time()
+        __start_time = t.time()
         # 鑾峰彇闃堝��
         threshold_money, msg = cls.__get_threshmoney(code)
+        if round(t.time() * 1000) - __start_time > 10:
+            __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
+                                               "鑾峰彇m鍊兼暟鎹�楁椂")
         cls.__start_compute_buy(code, start_index, end_index, threshold_money, capture_time)
 
     # 澶勭悊宸叉寕鍗�
@@ -262,7 +264,7 @@
         if cancel_data:
             cls.debug(code, "瑙﹀彂鎾ゅ崟锛屾挙鍗曚綅缃細{} 锛屾挙鍗曞師鍥狅細{}", cancel_data["index"], cancel_msg)
             # 鎾ゅ崟
-            cls.cancel_buy(code,cancel_msg)
+            cls.cancel_buy(code, cancel_msg)
             # 缁х画璁$畻涓嬪崟
             cls.__process_not_order(code, cancel_data["index"] + 1, end_index, capture_time)
         else:
@@ -304,6 +306,11 @@
     @classmethod
     def __can_buy(cls, code):
 
+        # 閲忔瘮瓒呰繃1.3鐨勪笉鑳戒拱
+        volumn_rate = l2_trade_factor.L2TradeFactorUtil.get_volumn_rate_by_code(code)
+        if volumn_rate >= 1.3:
+            return False, "鏈�澶ч噺姣旇秴杩�1.3涓嶈兘涔�"
+
         limit_up_time = limit_up_time_manager.get_limit_up_time(code)
         if limit_up_time is not None and l2_data_manager.L2DataUtil.get_time_as_second(
                 limit_up_time) >= l2_data_manager.L2DataUtil.get_time_as_second(
@@ -320,7 +327,8 @@
 
         if cls.__codeActualPriceProcessor.is_under_water(code):
             # 姘翠笅鎹炰笖鏉垮潡涓殑绁ㄥ皬浜�21涓嶈兘涔�
-            if global_util.industry_hot_num.get(industry) <= 16:
+            if global_util.industry_hot_num.get(industry) is not None and global_util.industry_hot_num.get(
+                    industry) <= 16:
                 return False, "姘翠笅鎹�,鏉垮潡涓殑绁ㄥ皬浜�2鍙�,涓簕}".format(global_util.industry_hot_num.get(industry))
 
             if codes_index.get(code) != 0:
@@ -418,19 +426,19 @@
                 # 濡傛灉鏄粖澶╃涓�娆℃湁涓嬪崟寮�濮嬩俊鍙凤紝闇�瑕佽缃ぇ鍗曡捣濮嬬偣
                 cls.l2BigNumForMProcessor.set_begin_pos(code, buy_single_index)
 
+        _start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "涓嬪崟淇″彿璁$畻鏃堕棿")
+
         if buy_single_index is None:
             # 鏈幏鍙栧埌涔板叆淇″彿锛岀粓姝㈢▼搴�
             return None
 
-        _start_time = t.time()
-
         # 璁$畻m鍊煎ぇ鍗�
         cls.l2BigNumForMProcessor.process(code, max(buy_single_index, compute_start_index), compute_end_index,
                                           gpcode_manager.get_limit_up_price(code))
-        _start_time = t.time()
+
+        _start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "璁$畻m鍊煎ぇ鍗�")
 
         threshold_money, msg = cls.__get_threshmoney(code)
-        _start_time = t.time()
         # 涔板叆绾拱棰濈粺璁�
         compute_index, buy_nums, buy_count, rebegin_buy_pos = cls.__sum_buy_num_for_order_3(code, max(buy_single_index,
                                                                                                       compute_start_index),
@@ -438,10 +446,10 @@
                                                                                             count, threshold_money,
                                                                                             buy_single_index,
                                                                                             capture_time)
+        _start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "绾拱棰濈粺璁℃椂闂�")
 
         cls.debug(code, "m鍊�-{} m鍊煎洜瀛�-{}", threshold_money, msg)
 
-        _start_time = t.time()
         # 涔板叆淇″彿浣嶄笌璁$畻浣嶇疆闂撮殧2s鍙婁互涓婁簡
         if rebegin_buy_pos is not None:
             # 闇�瑕侀噸鏂拌绠楃函涔伴
@@ -463,6 +471,8 @@
 
             # 娑ㄥ仠灏佸崟棰濊绠�
             L2LimitUpMoneyStatisticUtil.process_data(code, buy_single_index, compute_index, buy_single_index, False)
+
+            _start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "璁板綍鎵ц涔板叆鏁版嵁")
 
             # 鏁版嵁鏄惁澶勭悊瀹屾瘯
             if compute_index >= compute_end_index:
@@ -542,12 +552,42 @@
     def __get_threshmoney(cls, code):
         return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code)
 
+    # 鏄惁涓轰竾鎵嬪摜
+    @classmethod
+    def __is_big_money(cls, limit_up_price, val):
+        if int(val["num"]) >= 7888:
+            return True
+        if int(val["num"]) * limit_up_price >= 29900:
+            return True
+        return False
+
+    # 璁$畻涓囨墜鍝ョ瑪鏁�
+    @classmethod
+    def __compute_big_money_count(cls, total_datas, start_index, end_index):
+        count = 0
+        for i in range(start_index, end_index + 1):
+            if L2DataUtil.is_limit_up_price_buy(total_datas[i]["val"]):
+                count += total_datas[i]["re"]
+            elif L2DataUtil.is_limit_up_price_buy_cancel(total_datas[i]["val"]):
+                count -= total_datas[i]["re"]
+        return count
+
     # 缁熻涔板叆鍑�涔伴噺锛屼笉璁$畻鍦ㄤ拱鍏ヤ俊鍙蜂箣鍓嶇殑涔版挙鍗�
     @classmethod
     def __sum_buy_num_for_order_3(cls, code, compute_start_index, compute_end_index, origin_num, origin_count,
                                   threshold_money, buy_single_index, capture_time):
+        def get_threshold_count():
+            count = threshold_count - sub_threshold_count
+            if count < 3:
+                count = 3
+            return count
         _start_time = t.time()
         total_datas = local_today_datas[code]
+        # 璁$畻浠庝拱鍏ヤ俊鍙峰紑濮嬪埌璁$畻寮�濮嬩綅缃殑澶у崟鏁伴噺
+        sub_threshold_count = cls.__compute_big_money_count(total_datas, buy_single_index, compute_start_index - 1)
+        if sub_threshold_count < 0:
+            sub_threshold_count = 0
+
         buy_nums = origin_num
         buy_count = origin_count
         limit_up_price = gpcode_manager.get_limit_up_price(code)
@@ -563,7 +603,8 @@
         for i in range(compute_start_index, compute_end_index + 1):
             data = total_datas[i]
             _val = total_datas[i]["val"]
-            if L2DataUtil.get_time_as_second(_val["time"]) - buy_single_time_seconds > 1:
+            # 蹇呴』涓鸿繛缁�3绉掑唴鐨勬暟鎹�
+            if L2DataUtil.get_time_as_second(_val["time"]) - buy_single_time_seconds > 2:
                 TradePointManager.delete_buy_point(code)
                 if i == compute_end_index:
                     # 鏁版嵁澶勭悊瀹屾瘯
@@ -573,16 +614,19 @@
                     for ii in range(buy_single_index + 1, compute_end_index + 1):
                         if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]:
                             return None, buy_nums, buy_count, ii
-
             # 娑ㄥ仠涔�
             if L2DataUtil.is_limit_up_price_buy(_val):
+                if cls.__is_big_money(limit_up_price,_val):
+                    sub_threshold_count += int(total_datas[i]["re"])
                 # 娑ㄥ仠涔�
                 buy_nums += int(_val["num"]) * int(total_datas[i]["re"])
                 buy_count += int(total_datas[i]["re"])
-                if buy_nums >= threshold_num and buy_count >= threshold_count:
-                    logger_l2_trade_buy.info("{}鑾峰彇鍒颁拱鍏ユ墽琛岀偣锛歿} 缁熻绾拱鎵嬫暟锛歿} 鐩爣绾拱鎵嬫暟锛歿} 缁熻绾拱鍗曟暟锛歿} 鐩爣绾拱鍗曟暟锛歿}", code, i, buy_nums,
-                                             threshold_num, buy_count, threshold_count)
+                if buy_nums >= threshold_num and buy_count >= get_threshold_count():
+                    logger_l2_trade_buy.info("{}鑾峰彇鍒颁拱鍏ユ墽琛岀偣锛歿} 缁熻绾拱鎵嬫暟锛歿} 鐩爣绾拱鎵嬫暟锛歿} 缁熻绾拱鍗曟暟锛歿} 鐩爣绾拱鍗曟暟锛歿}, 澶у崟鏁伴噺锛歿}", code, i, buy_nums,
+                                             threshold_num, buy_count, get_threshold_count(),sub_threshold_count)
             elif L2DataUtil.is_limit_up_price_buy_cancel(_val):
+                if cls.__is_big_money(limit_up_price, _val):
+                    sub_threshold_count -= int(total_datas[i]["re"])
                 # 娑ㄥ仠涔版挙
                 # 鍒ゆ柇涔板叆浣嶇疆鏄惁鍦ㄤ拱鍏ヤ俊鍙蜂箣鍓�
                 buy_index, buy_data = l2_data_util.get_buy_data_with_cancel_data(total_datas[i],
@@ -608,12 +652,12 @@
             cls.buy_debug(code, "浣嶇疆-{}锛屾�绘墜鏁帮細{}锛岀洰鏍囨墜鏁帮細{}", i,
                           buy_nums, threshold_num)
             # 鏈夋挙鍗曚俊鍙凤紝涓斿皬浜庨槇鍊�
-            if buy_nums >= threshold_num and buy_count >= threshold_count:
+            if buy_nums >= threshold_num and buy_count >= get_threshold_count():
                 return i, buy_nums, buy_count, None
 
-        cls.buy_debug(code, "灏氭湭鑾峰彇鍒颁拱鍏ユ墽琛岀偣锛岃捣濮嬭绠椾綅缃細{} 缁熻绾拱鎵嬫暟锛歿} 鐩爣绾拱鎵嬫暟锛歿}  缁熻绾拱鍗曟暟锛歿} 鐩爣绾拱鍗曟暟锛歿}", compute_start_index,
+        cls.buy_debug(code, "灏氭湭鑾峰彇鍒颁拱鍏ユ墽琛岀偣锛岃捣濮嬭绠椾綅缃細{} 缁熻绾拱鎵嬫暟锛歿} 鐩爣绾拱鎵嬫暟锛歿}  缁熻绾拱鍗曟暟锛歿} 鐩爣绾拱鍗曟暟锛歿} 澶у崟鏁伴噺锛歿}", compute_start_index,
                       buy_nums,
-                      threshold_num, buy_count, threshold_count)
+                      threshold_num, buy_count, get_threshold_count(),sub_threshold_count)
 
         return None, buy_nums, buy_count, None
 
@@ -682,8 +726,290 @@
         print("鏃堕棿鑺辫垂:", round((t.time() - _start) * 1000))
         pass
 
+    @classmethod
+    def test2(cls):
+        code = "002864"
+        load_l2_data(code)
+        limit_up_time_manager.load_limit_up_time()
+        limit_up_time = limit_up_time_manager.get_limit_up_time(code)
+        if limit_up_time is not None and l2_data_manager.L2DataUtil.get_time_as_second(
+                limit_up_time) >= l2_data_manager.L2DataUtil.get_time_as_second(
+            "14:30:00"):
+            return False, "14:30鍚庢定鍋滅殑涓嶈兘涔帮紝娑ㄥ仠鏃堕棿涓簕}".format(limit_up_time)
+
+        # 鍚屼竴鏉垮潡涓�佷簩鍚庨潰鐨勪笉鑳戒拱
+        industry, codes = ths_industry_util.get_same_industry_codes(code, gpcode_manager.get_gp_list())
+        if industry is None:
+            return True, "娌℃湁鑾峰彇鍒拌涓�"
+        codes_index = limit_up_time_manager.sort_code_by_limit_time(codes)
+        if codes_index is not None and codes_index.get(code) is not None and codes_index.get(code) > 1:
+            return False, "鍚屼竴鏉垮潡涓�佷笁,鑰佸洓,...涓嶈兘涔�"
+
+        if cls.__codeActualPriceProcessor.is_under_water(code):
+            # 姘翠笅鎹炰笖鏉垮潡涓殑绁ㄥ皬浜�21涓嶈兘涔�
+            if global_util.industry_hot_num.get(industry) is not None and global_util.industry_hot_num.get(
+                    industry) <= 16:
+                return False, "姘翠笅鎹�,鏉垮潡涓殑绁ㄥ皬浜�2鍙�,涓簕}".format(global_util.industry_hot_num.get(industry))
+
+            if codes_index.get(code) != 0:
+                return False, "姘翠笅鎹�,涓嶆槸鑰佸ぇ锛屾槸鑰亄}".format(codes_index.get(code))
+
+        # 13:30鍚庢定鍋滐紝鏈澘鍧椾腑娑ㄥ仠绁ㄦ暟<29涓嶈兘涔�
+        limit_up_time = limit_up_time_manager.get_limit_up_time(code)
+        if limit_up_time is not None:
+            if int(limit_up_time.replace(":", "")) >= 133000 and global_util.industry_hot_num.get(industry) is not None:
+                if global_util.industry_hot_num.get(industry) < 16:
+                    return False, "13:30鍚庢定鍋滐紝鏈澘鍧椾腑娑ㄥ仠绁ㄦ暟<16涓嶈兘涔�"
+
+        if codes_index.get(code) is not None and codes_index.get(code) == 1:
+            # 濡傛灉鑰佸ぇ宸茬粡涔版垚鍔熶簡锛岃�佷簩灏变笉闇�瑕佷拱浜�
+            first_codes = []
+            for key in codes_index:
+                if codes_index.get(key) == 0:
+                    first_codes.append(key)
+
+            for key in first_codes:
+                state = trade_manager.get_trade_state(key)
+                if state == trade_manager.TRADE_STATE_BUY_SUCCESS:
+                    # 鑰佸ぇ宸茬粡涔版垚鍔熶簡
+                    return False, "鑰佸ぇ{}宸茬粡涔版垚鍔燂紝鑰佷簩鏃犻渶璐拱".format(key)
+
+            # 鏈�9鐐瑰崐娑ㄥ仠鐨勮�佸ぇ鎵嶈兘涔拌�佷簩锛屼笉鐒朵笉鑳戒拱
+            # 鑾峰彇鑰佸ぇ鐨勬定鍋滄椂闂�
+            for key in first_codes:
+                # 鎵惧埌浜嗚�佸ぇ
+                time_ = limit_up_time_manager.get_limit_up_time(key)
+                if time_ == "09:30:00":
+                    return True, "9:30娑ㄥ仠鐨勮�佸ぇ锛岃�佷簩鍙互涓嬪崟"
+            return False, "鑰佸ぇ闈�9:30娑ㄥ仠锛岃�佷簩涓嶈兘涓嬪崟"
+
+
+# 娑ㄥ仠灏佸崟棰濈粺璁�
+class L2LimitUpMoneyStatisticUtil:
+    _redisManager = redis_manager.RedisManager(1)
+
+    @classmethod
+    def __get_redis(cls):
+        return cls._redisManager.getRedis()
+
+    # 璁剧疆l2鐨勬瘡涓�绉掓定鍋滃皝鍗曢鏁版嵁
+    @classmethod
+    def __set_l2_second_money_record(cls, code, time, num, from_index, to_index):
+        old_num, old_from, old_to = cls.__get_l2_second_money_record(code, time)
+        if old_num is None:
+            old_num = num
+            old_from = from_index
+            old_to = to_index
+        else:
+            old_num += num
+            old_to = to_index
+
+        key = "l2_limit_up_second_money-{}-{}".format(code, time.replace(":", ""))
+
+        cls.__get_redis().setex(key, tool.get_expire(), json.dumps((old_num, old_from, old_to)))
+
+    @classmethod
+    def __get_l2_second_money_record(cls, code, time):
+        key = "l2_limit_up_second_money-{}-{}".format(code, time.replace(":", ""))
+        val = cls.__get_redis().get(key)
+        return cls.__format_second_money_record_val(val)
+
+    @classmethod
+    def __format_second_money_record_val(cls, val):
+        if val is None:
+            return None, None, None
+        val = json.loads(val)
+        return val[0], val[1], val[2]
+
+    @classmethod
+    def __get_l2_second_money_record_keys(cls, code, time_regex):
+        key = "l2_limit_up_second_money-{}-{}".format(code, time_regex)
+        keys = cls.__get_redis().keys(key)
+        return keys
+
+    # 璁剧疆l2鏈�鏂扮殑灏佸崟棰濇暟鎹�
+    @classmethod
+    def __set_l2_latest_money_record(cls, code, index, num):
+        key = "l2_limit_up_money-{}".format(code)
+        cls.__get_redis().setex(key, tool.get_expire(), json.dumps((num, index)))
+
+    # 杩斿洖鏁伴噺,绱㈠紩
+    @classmethod
+    def __get_l2_latest_money_record(cls, code):
+        key = "l2_limit_up_money-{}".format(code)
+        result = cls.__get_redis().get(key)
+        if result:
+            result = json.loads(result)
+            return result[0], result[1]
+        else:
+            return 0, -1
+
+    # 鐭鏁版嵁
+    # 鐭鏂规硶涓哄彇鐭鏃堕棿涓や晶鐨勭鍒嗗竷鏁版嵁锛岀敤浜庣‘瀹氳绠楃粨鏉熷潗鏍�
+    @classmethod
+    def verify_num(cls, code, num, time_str):
+        # 璁板綍涔�1鐭鏃ュ織
+        logger_buy_1_volumn.info("娑ㄥ仠灏佸崟閲忕煫姝o細浠g爜-{} 閲�-{} 鏃堕棿-{}", code, num, time_str)
+        time_ = time_str.replace(":", "")
+        key = None
+        for i in range(4, -2, -2):
+            # 鑾峰彇鏈�(鍒嗛挓/灏忔椂/澶�)鍐呯鍒嗗竷鏁版嵁
+            time_regex = "{}*".format(time_[:i])
+            keys_ = cls.__get_l2_second_money_record_keys(code, time_regex)
+            if keys_ and len(keys_) > 1:
+                # 闇�瑕佹帓搴�
+                keys = []
+                for k in keys_:
+                    keys.append(k)
+                keys.sort(key=lambda tup: int(tup.split("-")[-1]))
+                # 鏈�2涓厓绱�
+                for index in range(0, len(keys) - 1):
+                    time_1 = keys[index].split("-")[-1]
+                    time_2 = keys[index + 1].split("-")[-1]
+                    if int(time_1) <= int(time_) <= int(time_2):
+                        # 鍦ㄦ鏃堕棿鑼冨洿鍐�
+                        if time_ == time_2:
+                            key = keys[index + 1]
+                        else:
+                            key = keys[index]
+                        break
+            if key:
+                val = cls.__get_redis().get(key)
+                old_num, old_from, old_to = cls.__format_second_money_record_val(val)
+                end_index = old_to
+                # 淇濆瓨鏈�杩戠殑鏁版嵁
+                cls.__set_l2_latest_money_record(code, end_index, num)
+                logger_buy_1_volumn.info("娑ㄥ仠灏佸崟閲忕煫姝g粨鏋滐細浠g爜-{} 浣嶇疆-{} 閲�-{}", code, end_index, num)
+                break
+
+    # 璁$畻閲忥紝鐢ㄤ簬娑ㄥ仠灏佸崟閲忕殑璁$畻
+    @classmethod
+    def __compute_num(cls, code, data, buy_single_data):
+        if L2DataUtil.is_limit_up_price_buy_cancel(data["val"]) or L2DataUtil.is_sell(data["val"]):
+            # 娑ㄥ仠涔版挙涓庡崠
+            return 0 - int(data["val"]["num"]) * data["re"]
+        else:
+            # 鍗栨挙
+            if L2DataUtil.is_sell_cancel(data["val"]):
+                # 鍗栨挙鐨勪拱鏁版嵁鏄惁鍦ㄤ拱鍏ヤ俊鍙蜂箣鍓嶏紝濡傛灉鍦ㄤ箣鍓嶅氨涓嶈绠楋紝涓嶅湪涔嬪墠灏辫绠�
+                if l2_data_util.is_sell_index_before_target(data, buy_single_data,
+                                                            local_today_num_operate_map.get(code)):
+                    return 0
+
+            return int(data["val"]["num"]) * data["re"]
+
+    @classmethod
+    def clear(cls, code):
+        key = "l2_limit_up_money-{}".format(code)
+        cls.__get_redis().delete(key)
+
+    # 杩斿洖鍙栨秷鐨勬爣蹇楁暟鎹�
+    # with_cancel 鏄惁闇�瑕佸垽鏂槸鍚︽挙閿�
+    @classmethod
+    def process_data(cls, code, start_index, end_index, buy_single_begin_index, with_cancel=True):
+        start_time = round(t.time() * 1000)
+        total_datas = local_today_datas[code]
+        time_dict_num = {}
+        # 璁板綍璁$畻鐨勫潗鏍�
+        time_dict_num_index = {}
+        num_dict = {}
+        # 缁熻鏃堕棿鍒嗗竷
+        time_dict = {}
+        for i in range(start_index, end_index + 1):
+            data = total_datas[i]
+            val = data["val"]
+            time_ = val["time"]
+            if time_ not in time_dict:
+                time_dict[time_] = i
+
+        for i in range(start_index, end_index + 1):
+            data = total_datas[i]
+            val = data["val"]
+            time_ = val["time"]
+            if time_ not in time_dict_num:
+                time_dict_num[time_] = 0
+                time_dict_num_index[time_] = {"s": i, "e": i}
+            time_dict_num_index[time_]["e"] = i
+            num = cls.__compute_num(code, data, total_datas[buy_single_begin_index])
+            num_dict[i] = num
+            time_dict_num[time_] = time_dict_num[time_] + num
+        for t_ in time_dict_num:
+            cls.__set_l2_second_money_record(code, t_, time_dict_num[t_], time_dict_num_index[t_]["s"],
+                                             time_dict_num_index[t_]["e"])
+
+        print("淇濆瓨娑ㄥ仠灏佸崟棰濇椂闂达細", round(t.time() * 1000) - start_time)
+
+        # 绱鏈�鏂扮殑閲戦
+        total_num, index = cls.__get_l2_latest_money_record(code)
+        record_msg = f"鍚岃姳椤轰拱1淇℃伅 {total_num},{index}"
+
+        if index == -1:
+            # 娌℃湁鑾峰彇鍒版渶鏂扮殑鐭灏佸崟棰濓紝闇�瑕佷粠涔板叆淇″彿寮�濮嬬偣璁$畻
+            index = buy_single_begin_index - 1
+            total_num = 0
+
+        cancel_index = None
+        cancel_msg = None
+        # 寰呰绠楅噺
+        limit_up_price = gpcode_manager.get_limit_up_price(code)
+        min_volumn = round(10000000 / (limit_up_price * 100))
+        # 涓嶅悓鏃堕棿鐨勬暟鎹紑濮嬪潗鏍�
+        time_start_index_dict = {}
+        # 鏁版嵁鏃堕棿鍒嗗竷
+        time_list = []
+        # 鍒板綋鍓嶆椂闂寸疮绉殑涔�1閲�
+        time_total_num_dict = {}
+        for i in range(index + 1, end_index + 1):
+            data = total_datas[i]
+            time_ = data["val"]["time"]
+            if time_ not in time_start_index_dict:
+                # 璁板綍姣忎竴绉掔殑寮�濮嬩綅缃�
+                time_start_index_dict[time_] = i
+                # 璁板綍鏃堕棿鍒嗗竷
+                time_list.append(time_)
+                # 涓婁竴娈垫椂闂寸殑鎬绘暟
+                time_total_num_dict[time_] = total_num
+
+            val = num_dict.get(i)
+            if val is None:
+                val = cls.__compute_num(code, data, total_datas[buy_single_begin_index])
+            total_num += val
+            # 濡傛灉鏄噺灏忛」锛屼笖鍦ㄥ鐞嗘暟鎹殑鑼冨洿鍐咃紝灏遍渶瑕佸垽鏂槸鍚﹁鎾ゅ崟浜�
+            if val < 0 and start_index <= i <= end_index:
+                # 绱灏佸崟閲戦灏忎簬1000涓�
+                if total_num < min_volumn:
+                    cancel_index = i
+                    cancel_msg = "灏佸崟閲戦灏忎簬1000涓�"
+                    break
+                # 鐩搁偦2s鍐呯殑鏁版嵁鍑忓皬50%
+                # 涓�1s鐨勬�绘暟
+                last_second_total_volumn = time_total_num_dict.get(time_list[-1])
+                if last_second_total_volumn > 0 and (
+                        last_second_total_volumn - total_num) / last_second_total_volumn >= 0.5:
+                    # 鐩搁偦2s鍐呯殑鏁版嵁鍑忓皬50%
+                    cancel_index = i
+                    cancel_msg = "鐩搁偦2s({})鍐呯殑灏佸崟閲忓噺灏�50%({}->{})".format(time_, last_second_total_volumn,
+                                                                     total_num)
+                    break
+        if not with_cancel:
+            cancel_index = None
+
+        print("灏佸崟棰濊绠楁椂闂达細", round(t.time() * 1000) - start_time)
+        process_end_index = end_index
+        if cancel_index:
+            process_end_index = cancel_index
+        # 淇濆瓨鏈�鏂扮疮璁¢噾棰�
+        # cls.__set_l2_latest_money_record(code, process_end_index, total_num)
+        l2_data_log.l2_time(code, round(t.time() * 1000) - start_time, "l2鏁版嵁灏佸崟棰濊绠楁椂闂�",
+                            False)
+        if cancel_index:
+            L2TradeDataProcessor.cancel_debug(code, "鏁版嵁澶勭悊浣嶇疆锛歿}-{}锛寋}锛屾渶缁堜拱1涓猴細{}", start_index, end_index, record_msg,
+                                              total_num)
+            return total_datas[cancel_index], cancel_msg
+        return None, None
+
 
 if __name__ == "__main__":
-    L2TradeDataProcessor.test()
+    L2TradeDataProcessor.test2()
     print("----------------------")
-    L2TradeDataProcessor.test()
+    # L2TradeDataProcessor.test()

--
Gitblit v1.8.0