Administrator
2025-05-26 a846b46f15ad309a62fe400cf78dd7fc888155d7
l2/l2_data_manager_new.py
@@ -19,6 +19,7 @@
from log_module import async_log_util, log_export
from third_data import kpl_data_manager, block_info
from third_data.kpl_data_constant import LimitUpDataConstant
from trade.buy_radical.block_special_codes_manager import BlockSpecialCodesManager
from trade.buy_radical.radical_buy_data_manager import EveryLimitupBigDealOrderManager
from utils import global_util, tool, buy_condition_util, buy_strategy_util, trade_util
import l2_data_util
@@ -27,7 +28,7 @@
from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
    trade_result_manager, current_price_process_manager, trade_data_manager, trade_huaxin, trade_record_log_util, \
    trade_constant, buy_open_limit_up_strategy
from trade.buy_radical import radical_buy_data_manager
from trade.buy_radical import radical_buy_data_manager, radical_buy_strategy
from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \
    transaction_progress, cancel_buy_strategy, place_order_single_data_manager
from l2.cancel_buy_strategy import DCancelBigNumComputer, \
@@ -180,6 +181,7 @@
        num_splites = [round(5000 / limit_up_price), round(10000 / limit_up_price), round(20000 / limit_up_price),
                       round(30000 / limit_up_price)]
        total_num = 0
        buyno_map = local_today_buyno_map.get(code)
        for i in range(max(start_index, processed_index), end_index + 1):
            data = total_datas[i]
            if not L2DataUtil.is_limit_up_price_buy_cancel(data["val"]) and not L2DataUtil.is_limit_up_price_buy(
@@ -189,8 +191,7 @@
            if L2DataUtil.is_limit_up_price_buy_cancel(data["val"]):
                # 获取买入信号
                buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i],
                                                                                                    local_today_buyno_map.get(
                                                                                                        code))
                                                                                                    buyno_map)
                if buy_index is not None and buy_index < begin_pos:
                    continue
@@ -216,6 +217,70 @@
        # print("m值大单计算范围:{}-{}  时间:{}".format(max(start_index, processed_index), end_index,
        #                                      round(t.time() * 1000) - start_time))
class HumanRadicalBuySingleManager:
    """
    人为买入管理
    """
    # 人为下单标记:{"代码":(信号时间, 间隔时间,信号截至时间, radical_result)}
    __human_radical_buy_mark_info = {}
    @classmethod
    def add_single(cls, code, latest_data, radical_result):
        """
        添加买入信号
        @param code:
        @param latest_data:
        @param radical_result:
        @return:
        """
        start_time_with_ms = L2DataUtil.get_time_with_ms(latest_data["val"])
        if tool.is_sh_code(code):
            cls.__human_radical_buy_mark_info[code] = (
                start_time_with_ms, 400, tool.trade_time_add_millionsecond(start_time_with_ms, 3000), radical_result)
        else:
            cls.__human_radical_buy_mark_info[code] = (
                start_time_with_ms, 30, tool.trade_time_add_millionsecond(start_time_with_ms, 2000), radical_result)
    @classmethod
    def remove_single(cls, code):
        """
        移除信号
        @param code:
        @return:
        """
        if code in cls.__human_radical_buy_mark_info:
            cls.__human_radical_buy_mark_info.pop(code)
    @classmethod
    def has_single(cls, code):
        """
        是否有信号
        @param code:
        @return:
        """
        if code in cls.__human_radical_buy_mark_info:
            return True
        return False
    @classmethod
    def is_valid(cls, code, data):
        """
        信号是否有效
        @param code:
        @return: 是否有效,无效消息/有效对象
        """
        if code not in cls.__human_radical_buy_mark_info:
            return False, "没有人买入信号"
        single_time_ms, space_time_ms, expire_time_ms, _ = cls.__human_radical_buy_mark_info[code]
        now_time_ms = L2DataUtil.get_time_with_ms(data["val"])
        if tool.trade_time_sub_with_ms(now_time_ms,
                                       expire_time_ms) > 0:
            cls.__human_radical_buy_mark_info.pop(code)
            async_log_util.info(logger_l2_not_buy_reasons, f"{code}#大单足够,人为下单: 超过信号生效时间-{now_time_ms}/{expire_time_ms}")
            return False, "超过信号生效时间"
        return True, cls.__human_radical_buy_mark_info[code]
class L2TradeDataProcessor:
@@ -325,8 +390,14 @@
                cls.unreal_buy_dict.pop(code)
    @classmethod
    def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo):
    def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo, last_data):
        trade_record_log_util.add_real_place_order_position_log(code, index, order_begin_pos.buy_single_index)
        total_datas = local_today_datas.get(code)
        use_time = tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[index]["val"]),
                                               L2DataUtil.get_time_with_ms(
                                                   total_datas[order_begin_pos.buy_exec_index]["val"]))
        trade_record_log_util.add_place_order_use_time(code,
                                                       f"执行位时间:{L2DataUtil.get_time_with_ms(total_datas[order_begin_pos.buy_exec_index]['val'])} 耗时:{use_time}")
        l2_log.debug(code, "设置真实下单位:{}", index)
        cancel_buy_strategy.set_real_place_position(code, index, order_begin_pos.buy_single_index, is_default=False)
        # 获取真实下单位置之后需要判断F撤
@@ -391,7 +462,7 @@
        finally:
            if datas:
                l2.l2_data_util.save_l2_data(code, None, datas)
            origin_datas.clear()
            # origin_datas.clear()
    @classmethod
    def __recompute_real_order_index(cls, code, pre_real_order_index, order_info, compute_type):
@@ -401,13 +472,13 @@
            code, order_info, pre_real_order_index, compute_type)
        if real_order_index and pre_real_order_index != real_order_index:
            try:
                exec_index = order_info[6]
                exec_index = order_info[3]
                order_begin_pos = cls.__get_order_begin_pos(
                    code)
                async_log_util.info(logger_debug,
                                    f"下单位矫正:真实下单位-{real_order_index} 订单信息-{order_info}  下单信息-{order_begin_pos.to_dict()}")
                if order_begin_pos and order_begin_pos.buy_exec_index == exec_index:
                    cls.set_real_place_order_index(code, real_order_index, order_begin_pos)
                    cls.set_real_place_order_index(code, real_order_index, order_begin_pos, order_info[1])
                    async_log_util.info(logger_real_place_order_position,
                                        f"真实下单位置矫正:{code}-({real_order_index},1)")
            except Exception as e:
@@ -419,7 +490,7 @@
        now_time_str = tool.get_now_time_str()
        # 将本次中断设置为
        cls.__break_current_batch_data_for_buy_dict[code] = False
        if len(add_datas) > 0:
        if add_datas:
            # 记录当前批数据的索引
            cls.__processing_data_indexes[code] = (add_datas[0]["index"], add_datas[-1]["index"])
            if code not in cls.__trade_log_placr_order_info_dict:
@@ -490,7 +561,7 @@
                        if place_order_index:
                            order_begin_pos = cls.__get_order_begin_pos(
                                code)
                            cls.set_real_place_order_index(code, place_order_index, order_begin_pos)
                            cls.set_real_place_order_index(code, place_order_index, order_begin_pos, order_info[1])
                            try:
                                cls.__re_compute_threading_pool.submit(
                                    cls.__recompute_real_order_index, code, place_order_index, order_info,
@@ -813,15 +884,20 @@
            if not cls.__WantBuyCodesManager.is_in_cache(
                    code) and not gpcode_manager.GreenListCodeManager().is_in_cache(code):
                return False, True, f"只买想买:没在想买单和绿单", True
        if cls.__TradeTargetCodeModeManager.get_mode_cache() == TradeTargetCodeModeManager.MODE_ONLY_BUY_SPECIAL_CODES:
            special_blocks = BlockSpecialCodesManager().get_code_blocks(code)
            if not special_blocks:
                return False, True, f"只买辨识度", True
        # if not cls.__WantBuyCodesManager.is_in_cache(code):
        average_rate = cls.__Buy1PriceManager.get_average_rate(code)
        if average_rate:
            if tool.is_ge_code(code):
                if average_rate <= 0.1:
                    return False, True, f"均价涨幅({average_rate})小于10%", True
                if average_rate < 0.08:
                    return False, True, f"均价涨幅({average_rate})小于8%", True
            else:
                if average_rate <= 0.05:
                    return False, True, f"均价涨幅({average_rate})小于5%", True
                if average_rate < 0.04:
                    return False, True, f"均价涨幅({average_rate})小于4%", True
        return True, False, f"", False
    @classmethod
@@ -878,7 +954,7 @@
        params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc()
        l2_log.debug(code, params_desc)
        #################清除本次下单的大单数据###############
        EveryLimitupBigDealOrderManager.clear(code)
        EveryLimitupBigDealOrderManager.clear(code, "下单成功")
        ############记录下单时的数据############
        try:
            jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache(
@@ -963,12 +1039,22 @@
                                                             local_today_datas.get(code))
                return False
            else:
                l2_log.debug(code, "可以下单,原因:{}, 下单模式:{}", reason, order_begin_pos.mode)
                try:
                    # 判断是否为首封下单
                    order_begin_pos.first_limit_up_buy = radical_buy_data_manager.is_first_limit_up_buy(code)
                    if not constant.CAN_BUY_FIRST_LIMIT_UP and order_begin_pos.first_limit_up_buy:
                        reason = "首封不下单"
                        l2_log.debug(code, "不可以下单,原因:{}", reason)
                        trade_record_log_util.add_cant_place_order_log(code, reason)
                        cls.__break_current_batch_data_for_buy_dict[code] = True
                        trade_result_manager.real_cancel_success(code, order_begin_pos.buy_single_index,
                                                                 order_begin_pos.buy_exec_index,
                                                                 local_today_datas.get(code))
                        return False
                    l2_log.debug(code, "可以下单,原因:{}, 下单模式:{}", reason, order_begin_pos.mode)
                    l2_log.debug(code, "开始执行买入")
                    trade_manager.start_buy(code, capture_timestamp, last_data,
                                            last_data_index, order_begin_pos.mode, order_begin_pos.buy_exec_index)
@@ -1378,7 +1464,7 @@
                     order_begin_pos.threshold_money,
                     order_begin_pos.num,
                     order_begin_pos.count, order_begin_pos.at_limit_up, total_datas[order_begin_pos.buy_exec_index],
                     cls.volume_rate_info[code], order_begin_pos.mode)
                     cls.volume_rate_info[code], order_begin_pos.mode_desc)
        cls.__save_order_begin_data(code, order_begin_pos)
        cls.__LimitUpTimeManager.save_limit_up_time(code, total_datas[order_begin_pos.buy_exec_index]["val"]["time"])
        l2_log.debug(code, "delete_buy_cancel_point")
@@ -1436,9 +1522,36 @@
        _start_time = tool.get_now_timestamp()
        total_datas = local_today_datas[code]
        # ---------计算激进买入的信号---------
        # 不需要根据人为下单来下单
        # if not HumanRadicalBuySingleManager.has_single(code):
        #     # ---------计算激进买入的信号---------
        #     radical_result = cls.__compute_radical_order_begin_pos(code, compute_start_index, compute_end_index)
        # else:
        #     human_radical_result = cls.__compute_human_radical_order_begin_pos(code, compute_start_index,
        #                                                                        compute_end_index)
        #     l2_log.debug(code, f"大单足够,人为下单计算结果({compute_start_index}-{compute_end_index}):{human_radical_result}")
        #     if human_radical_result[0]:
        #         radical_result = list(human_radical_result[2])
        #         # 改变执行位置
        #         radical_result[1] = human_radical_result[1]["index"]
        #     else:
        #         radical_result = None
        radical_result = cls.__compute_radical_order_begin_pos(code, compute_start_index, compute_end_index)
        if radical_result[0]:
        if radical_result and radical_result[0]:
            # if not HumanRadicalBuySingleManager.has_single(code):
            #     big_order_deal_enough_result = radical_buy_data_manager.is_big_order_deal_enough(code,
            #                                                                                      code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days(
            #                                                                                          code), 0)
            #     if big_order_deal_enough_result[6] <= 0:
            #         HumanRadicalBuySingleManager.add_single(code, total_datas[-1], radical_result)
            #         async_log_util.info(logger_l2_not_buy_reasons, f"{code}#大单足够,需要根据人为下单({compute_start_index}-{compute_end_index}):{radical_result[1]}")
            #         return
            # #下单前一步,移除人为下单信号
            # is_human_radical_buy = HumanRadicalBuySingleManager.has_single(code)
            # HumanRadicalBuySingleManager.remove_single(code)
            buy_single_index, buy_exec_index = radical_result[1], radical_result[1]
            buy_volume_rate = cls.volume_rate_info[code][0]
            refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, total_datas[buy_single_index]["val"][
@@ -1458,7 +1571,9 @@
                                                     mode=OrderBeginPosInfo.MODE_RADICAL,
                                                     mode_desc=f"大单不足扫入:{radical_result[2]}",
                                                     sell_info=sell_info,
                                                     threshold_money=threshold_money)
                                                     threshold_money=threshold_money,
                                                     min_order_no=radical_result[5]
                                                     )
            order_begin_pos_info.at_limit_up = cls.__is_at_limit_up_buy(code)
            ordered = cls.__process_with_find_exec_index(code, order_begin_pos_info, compute_end_index,
                                                         block_info=radical_result[3])
@@ -1467,7 +1582,36 @@
                # 监听大单
                RDCancelBigNumComputer().set_watch_indexes(code, radical_result[4])
            return
        else:
            radical_result = cls.__compute_radical_order_begin_pos_for_many_sell(code, compute_start_index,
                                                                                 compute_end_index)
            if radical_result[0]:
                buy_single_index, buy_exec_index = radical_result[0][0], radical_result[0][1]
                buy_volume_rate = cls.volume_rate_info[code][0]
                refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code,
                                                                                total_datas[buy_single_index]["val"][
                                                                                    "time"])
                if refer_sell_data:
                    sell_info = (refer_sell_data[0], refer_sell_data[1])
                else:
                    sell_info = (total_datas[buy_single_index]["val"]["time"], 0)
                threshold_money = 0
                order_begin_pos_info = OrderBeginPosInfo(buy_single_index=buy_single_index,
                                                         buy_exec_index=buy_exec_index,
                                                         buy_compute_index=buy_exec_index,
                                                         num=total_datas[buy_single_index]["val"]["num"], count=1,
                                                         max_num_set=set(),
                                                         buy_volume_rate=buy_volume_rate,
                                                         mode=OrderBeginPosInfo.MODE_RADICAL,
                                                         mode_desc=f"总抛压大扫入:{radical_result[2]}",
                                                         sell_info=sell_info,
                                                         threshold_money=threshold_money)
                order_begin_pos_info.at_limit_up = cls.__is_at_limit_up_buy(code)
                ordered = cls.__process_with_find_exec_index(code, order_begin_pos_info, compute_end_index,
                                                             block_info=radical_result[2])
                if ordered:
                    radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, radical_result[2])
        if RadicalBuyDealCodesManager().get_code_blocks(code):
            # 已经扫入下过单
            return
@@ -1872,6 +2016,7 @@
        return False, -1, "未获取到积极买的起始信号", '', OrderBeginPosInfo.MODE_NORMAL
    # 计算激进买的下单信号
    # 计算激进买的下单信号
    @classmethod
    def __compute_radical_order_begin_pos(cls, code, start_index, end_index):
        """
@@ -1881,32 +2026,36 @@
        @param code:
        @param start_index:
        @param end_index:
        @return: (是否获取到信号, 信号位置, 扫入板块/消息, 扫入板块大单流入信息, 需要监听的大单)
        @return: (是否获取到信号, 信号位置, 扫入板块/消息, 扫入板块大单流入信息, 需要监听的大单, 统计上板大单成交的最小订单号)
        """
        # 激进买信号的时间
        def __can_order():
            # 判断是否是板上放量
            if cls.__is_at_limit_up_buy(code, start_index):
                return False, None, "板上放量", None
            # if cls.__is_at_limit_up_buy(code, start_index):
            #     return False, None, "板上放量", None
            total_datas = local_today_datas[code]
            limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
            bigger_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code))
            min_num = int(bigger_money / limit_up_price / 100)
            bigger_money_num, current_min_num, total_min_num = int(bigger_money / limit_up_price / 100), int(
                bigger_money / limit_up_price / 100), int(5000 / limit_up_price)
            refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, radical_data[3])
            # 参考总卖额
            refer_sell_money = 0
            if refer_sell_data:
                refer_sell_money = refer_sell_data[1]
            # 判断还需大单的金额(max(每次上板大单,累计成交大单))
            big_order_deal_enough_result = radical_buy_data_manager.is_big_order_deal_enough(code,
                                                                                             code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days(
                                                                                                 code),
                                                                                             refer_sell_money,
                                                                                             for_buy=True)
                                                                                             for_buy=True,
                                                                                             is_almost_open_limit_up=
                                                                                             radical_data[5])
            # 缺乏的大单金额
            lack_money = big_order_deal_enough_result[3]
            current_lack_money = int(big_order_deal_enough_result[5])
            total_lack_money = int(big_order_deal_enough_result[6])
            # 如果有大单成交就不需要看大单
            if constant.CAN_RADICAL_BUY_NEED_BIG_ORDER_EVERYTIME:
                # 每次下单都需要大单
@@ -1917,10 +2066,14 @@
                    # 60s以上就不下单了
                    return False, None, "距离上次统计大单时间过去60s", set()
            if lack_money == 0:
                if not tool.is_sh_code(code):
                    # 非上证的票看50w
                    min_num = int(5000 / limit_up_price)
            if max(current_lack_money, total_lack_money) <= 0:
                # 已经不缺少大单了
                # if not tool.is_sh_code(code):
                # 非上证的票看50w
                current_min_num = int(5000 / limit_up_price)
            # 如果累计大单成交足够,只需看50w
            # if big_order_deal_enough_result[4]:
            #     min_num = int(5000 / limit_up_price)
            # 需要监听的大单
            watch_indexes = set()
            # 总委托大单金额
@@ -1936,8 +2089,6 @@
                val = data["val"]
                if not L2DataUtil.is_limit_up_price_buy(val):
                    continue
                if val["num"] < min_num:
                    continue
                # 撤单不算
                left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i,
                                                                                                         total_datas,
@@ -1952,23 +2103,40 @@
                        # 判断是否为大单
                        order_money = dealing_active_order_info[2] + round(val["price"], 2) * val["num"] * 100
                        if order_money >= bigger_money:
                            lack_money -= order_money
                            watch_indexes.add(i)
                            if lack_money < 0:
                            if val["num"] >= bigger_money_num:
                                watch_indexes.add(i)
                            if val["num"] >= current_min_num:
                                current_lack_money -= order_money
                            if val["num"] >= total_min_num:
                                total_lack_money -= order_money
                            if max(current_lack_money, total_lack_money) < 0:
                                single_index = i
                                break
                if int(val["orderNo"]) <= radical_data[1]:
                    # 主动买单后的数据不算
                    continue
                watch_indexes.add(i)
                lack_money -= round(val["price"], 2) * val["num"] * 100
                if lack_money < 0:
                if val["num"] >= bigger_money_num:
                    watch_indexes.add(i)
                if val["num"] >= current_min_num:
                    current_lack_money -= round(val["price"], 2) * val["num"] * 100
                if val["num"] >= total_min_num:
                    total_lack_money -= round(val["price"], 2) * val["num"] * 100
                if max(current_lack_money, total_lack_money) < 0:
                    single_index = i
                    break
            if single_index is not None:
                return True, single_index, "有大单", watch_indexes
            return False, None, f"大单不足:{trade_index}-{end_index}  缺少的大单-{lack_money}", watch_indexes
                every_time_big_orders = EveryLimitupBigDealOrderManager.list_big_buy_deal_orders(code)
                if every_time_big_orders:
                    min_order_no = min(min(every_time_big_orders, key=lambda e: e[0])[0], radical_data[1])
                else:
                    min_order_no = radical_data[1]
                return True, single_index, f"有大单,大单情况:{big_order_deal_enough_result[1]}", watch_indexes, min_order_no
            return False, None, f"大单不足:{trade_index}-{end_index}  缺少的大单-{max(current_lack_money, total_lack_money)}  大单情况:{big_order_deal_enough_result[1]}", watch_indexes, None
        radical_data = RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.get(code)
        record_codes = radical_buy_data_manager.BlockPlaceOrderRecordManager().get_codes()
@@ -1989,7 +2157,7 @@
                return False, None, "超过生效时间"
        result = __can_order()
        l2_log.debug(code, f"L2扫入判断:{result}")
        l2_log.debug(code, f"L2扫入判断({start_index}-{end_index}):{result}")
        if result[0]:
            # 已经扫入下过单且允许板上放量扫入的就需要判断板上放量的距离
            if is_radical_buy and constant.CAN_RADICAL_BUY_AT_LIMIT_UP:
@@ -2012,10 +2180,134 @@
            # 如果板上放量不可买入就需要删除信号
            if not constant.CAN_RADICAL_BUY_AT_LIMIT_UP and code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict:
                RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.pop(code)
            return True, result[1], radical_data[2], radical_data[4], result[3]
            return True, result[1], radical_data[2], radical_data[4], result[3], result[4]
        else:
            async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{result[2]}")
        return result
    @classmethod
    def __compute_human_radical_order_begin_pos(cls, code, start_index, end_index):
        """
        处理跟人买
        @param code:
        @param start_index:
        @param end_index:
        @return:
        """
        total_datas = local_today_datas.get(code)
        result = HumanRadicalBuySingleManager.is_valid(code, total_datas[start_index])
        if not result[0]:
            return False, None, result[1]
        result = result[1]
        single_time_ms, space_time_ms, expire_time_ms, radical_result = result[0], result[1], result[2], result[3]
        bigger_num = l2_data_util.get_big_money_val(gpcode_manager.get_limit_up_price_as_num(code),
                                                    tool.is_ge_code(code)) // (
                             gpcode_manager.get_limit_up_price_as_num(code) * 100)
        canceled_buyno_map = local_today_buyno_map.get(code)
        for i in range(start_index, end_index + 1):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            if val["num"] < bigger_num:
                continue
            left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i,
                                                                                                     total_datas,
                                                                                                     canceled_buyno_map)
            if left_count == 0:
                continue
            # 判断是否超过生效时间
            if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[i]["val"]),
                                           expire_time_ms) > 0:
                HumanRadicalBuySingleManager.remove_single(code)
                return False, None, "超过信号生效时间"
            is_valid = False
            # 判断距离上个50w买单的时间是否超过了space_time_ms
            buy_exec_index = radical_result[1]
            for ii in range(i - 1, buy_exec_index, -1):
                data_child = total_datas[ii]
                val_child = data_child["val"]
                if not L2DataUtil.is_limit_up_price_buy(val_child):
                    continue
                if val_child["num"] * float(val_child["price"]) < 5000:
                    continue
                if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(val),
                                               L2DataUtil.get_time_with_ms(val_child)) > space_time_ms:
                    is_valid = True
                    break
            if is_valid:
                return True, data, radical_result
        return False, None, "没有有效信号"
    # 总卖额参考时间使用记录
    __refer_sell_used_times = {}
    @classmethod
    def __compute_radical_order_begin_pos_for_many_sell(cls, code, start_index, end_index):
        """
        计算深证高抛压的卖的买入信号
        @param code:
        @param start_index:
        @param end_index:
        @return: 信号信息(信号位,执行位), 消息, 可买入的板块
        """
        if True:
            return None, "此条不生效", None
        if not tool.is_sz_code(code):
            return None, "非深证的票", None
        # 判断抛压是否大于5000w
        total_datas = local_today_datas.get(code)
        refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, total_datas[-1]["val"]["time"])
        if not refer_sell_data or refer_sell_data[1] < 5e7:
            return None, "总卖额小于5000万", None
        if code in cls.__refer_sell_used_times and refer_sell_data[0] in cls.__refer_sell_used_times:
            return None, f"时间已经被使用:{refer_sell_data[0]}", None
        deal_codes = RadicalBuyDealCodesManager().get_deal_codes()
        if code in deal_codes:
            return None, f"已经成交", None
        f_buy_blocks, orgin_buy_blocks = radical_buy_strategy.compute_can_radical_buy_blocks(code, deal_codes)
        if not f_buy_blocks:
            return None, f"板块不可买入", None
        # 判断是否有涨停买的数据
        has_limit_up = False
        for i in range(start_index, end_index + 1):
            data = total_datas[i]
            val = data["val"]
            if L2DataUtil.is_limit_up_price_buy(val):
                has_limit_up = True
                break
        if not has_limit_up:
            return None, "无涨停买数据", None
        # 查找计数起点
        refer_sell_time_int = int(refer_sell_data[0].replace(":", ""))
        begin_index = start_index
        for i in range(start_index - 1, -1, -1):
            data = total_datas[i]
            val = data["val"]
            if int(val["time"].replace(":", "")) < refer_sell_time_int:
                begin_index = i + 1
                break
        threshold_num = int(round(refer_sell_data[1] / gpcode_manager.get_limit_up_price_as_num(code) / 100))
        total_num = 0
        for i in range(begin_index, end_index + 1):
            data = total_datas[i]
            val = data["val"]
            if L2DataUtil.is_limit_up_price_buy(val):
                total_num += val["num"]
            elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                total_num -= val["num"]
        if total_num > threshold_num:
            if code not in cls.__refer_sell_used_times:
                cls.__refer_sell_used_times[code] = set()
            cls.__refer_sell_used_times[code].add(refer_sell_data[0])
            return (begin_index, end_index), "可以下单", f_buy_blocks
        return None, "总买额不满足", None
    @classmethod
    def test__compute_active_order_begin_pos(cls, code, continue_count, start_index, end_index):
@@ -2089,6 +2381,7 @@
        if place_order_count is None:
            place_order_count = 0
        is_ge_code = tool.is_ge_code(code)
        buy_no_map = local_today_buyno_map.get(code)
        for i in range(compute_start_index, compute_end_index + 1):
            data = total_datas[i]
            _val = total_datas[i]["val"]
@@ -2124,10 +2417,8 @@
            elif L2DataUtil.is_limit_up_price_buy_cancel(_val):
                # 判断买入位置是否在买入信号之前
                buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i],
                                                                                                    local_today_buyno_map.get(
                                                                                                        code))
                                                                                                    buy_no_map)
                if buy_index is not None:
                    # 找到买撤数据的买入点
                    if buy_index >= buy_single_index:
                        max_buy_num_set.discard(buy_index)
@@ -2228,6 +2519,7 @@
        max_buy_num_set = set(max_num_set)
        active_buy_blocks = cls.get_active_buy_blocks(code)
        is_ge_code = tool.is_ge_code(code)
        buyno_map = local_today_buyno_map.get(code)
        for i in range(compute_start_index, compute_end_index + 1):
            data = total_datas[i]
            _val = total_datas[i]["val"]
@@ -2266,8 +2558,7 @@
            elif L2DataUtil.is_limit_up_price_buy_cancel(_val):
                # 判断买入位置是否在买入信号之前
                buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i],
                                                                                                    local_today_buyno_map.get(
                                                                                                        code))
                                                                                                    buyno_map)
                if buy_index is not None:
                    # 找到买撤数据的买入点