Administrator
2023-08-28 ba52d7ac92a36f413eacaa686f8535e859664ec6
l2/l2_data_manager_new.py
@@ -5,15 +5,17 @@
from code_attribute import big_money_num_manager, code_volumn_manager, code_data_util, industry_codes_sort, \
    limit_up_time_manager, global_data_loader, gpcode_manager
import constant
from db.redis_manager import RedisUtils
from db.redis_manager_delegate import RedisUtils
from l2.huaxin import l2_huaxin_util, huaxin_delegate_postion_manager
from log_module import async_log_util
from third_data import kpl_data_manager, block_info
from trade.deal_big_money_manager import DealComputeProgressManager
from utils import global_util, ths_industry_util, tool
import l2_data_util
from db import redis_manager
from db import redis_manager_delegate as redis_manager
from third_data.code_plate_key_manager import CodePlateKeyBuyManager
from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
    trade_result_manager, first_code_score_manager, current_price_process_manager
    trade_result_manager, first_code_score_manager, current_price_process_manager, trade_data_manager, trade_huaxin
from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager, \
    transaction_progress
from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \
@@ -23,7 +25,7 @@
    local_latest_datas
import l2.l2_data_util
from log_module.log import logger_l2_trade_buy, logger_l2_process, \
    logger_place_order_score, logger_l2_error
    logger_place_order_score, logger_l2_error, logger_profile, logger_debug
# TODO l2数据管理
from trade.trade_data_manager import CodeActualPriceProcessor
@@ -32,7 +34,7 @@
import dask
from trade.trade_manager import TradeTargetCodeModeManager
from trade.trade_manager import TradeTargetCodeModeManager, AccountAvailableMoneyManager
class L2DataManager:
@@ -57,38 +59,79 @@
# m值大单处理
class L2BigNumForMProcessor:
    _db = 1
    _redis_manager = redis_manager.RedisManager(1)
    m_big_money_begin_cache = {}
    m_big_money_process_index_cache = {}
    __instance = None
    def __init__(self):
        self._redis_manager = redis_manager.RedisManager(1)
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(L2BigNumForMProcessor, cls).__new__(cls, *args, **kwargs)
            cls.__load_datas()
        return cls.__instance
    def __get_redis(self):
        return self._redis_manager.getRedis()
    @classmethod
    def __get_redis(cls):
        return cls._redis_manager.getRedis()
    @classmethod
    def __load_datas(cls):
        _redis = cls._redis_manager.getRedis()
        try:
            keys = RedisUtils.keys(_redis, "m_big_money_begin-*")
            for k in keys:
                code = k.split("-")[-1]
                val = RedisUtils.get(_redis, k)
                tool.CodeDataCacheUtil.set_cache(cls.m_big_money_begin_cache, code, int(val))
            keys = RedisUtils.keys(_redis, "m_big_money_process_index-*")
            for k in keys:
                code = k.split("-")[-1]
                val = RedisUtils.get(_redis, k)
                tool.CodeDataCacheUtil.set_cache(cls.m_big_money_process_index_cache, code, int(val))
        finally:
            RedisUtils.realse(_redis)
    # 保存计算开始位置
    def set_begin_pos(self, code, index):
        if self.__get_begin_pos(code) is None:
        if self.__get_begin_pos_cache(code) is None:
            tool.CodeDataCacheUtil.set_cache(self.m_big_money_begin_cache, code, index)
            # 保存位置
            key = "m_big_money_begin-{}".format(code)
            RedisUtils.setex(self.__get_redis(), key, tool.get_expire(), index)
            RedisUtils.setex_async(self._db, key, tool.get_expire(), index)
    # 获取计算开始位置
    def __get_begin_pos(self, code):
        key = "m_big_money_begin-{}".format(code)
        val = RedisUtils.get(self.__get_redis(),key)
        val = RedisUtils.get(self.__get_redis(), key)
        if val is None:
            return None
        return int(val)
    def __get_begin_pos_cache(self, code):
        cache_result = tool.CodeDataCacheUtil.get_cache(self.m_big_money_begin_cache, code)
        if cache_result[0]:
            return cache_result[1]
        return None
    # 清除已经处理的数据
    def clear_processed_end_index(self, code):
        tool.CodeDataCacheUtil.clear_cache(self.m_big_money_process_index_cache, code)
        key = "m_big_money_process_index-{}".format(code)
        RedisUtils.delete(self.__get_redis(), key)
        RedisUtils.delete_async(self._db, key)
    # 添加已经处理过的单
    def __set_processed_end_index(self, code, index):
        tool.CodeDataCacheUtil.set_cache(self.m_big_money_process_index_cache, code, index)
        key = "m_big_money_process_index-{}".format(code)
        RedisUtils.setex(self.__get_redis(), key, tool.get_expire(), index)
        RedisUtils.setex_async(self._db, key, tool.get_expire(), index)
    # 是否已经处理过
    def __get_processed_end_index(self, code):
@@ -98,15 +141,21 @@
            return None
        return int(val)
    def __get_processed_end_index_cache(self, code):
        cache_result = tool.CodeDataCacheUtil.get_cache(self.m_big_money_process_index_cache, code)
        if cache_result[0]:
            return cache_result[1]
        return None
    # 处理大单
    def process(self, code, start_index, end_index, limit_up_price):
        begin_pos = self.__get_begin_pos(code)
        begin_pos = self.__get_begin_pos_cache(code)
        if begin_pos is None:
            # 没有获取到开始买入信号
            return
        # 上次处理到的坐标
        processed_index = self.__get_processed_end_index(code)
        processed_index = self.__get_processed_end_index_cache(code)
        if processed_index is None:
            processed_index = 0
        if processed_index >= end_index:
@@ -159,7 +208,6 @@
class L2TradeDataProcessor:
    unreal_buy_dict = {}
    volume_rate_info = {}
    l2BigNumForMProcessor = L2BigNumForMProcessor()
    __codeActualPriceProcessor = CodeActualPriceProcessor()
    __ths_l2_trade_queue_manager = trade_queue_manager.thsl2tradequeuemanager()
    __thsBuy1VolumnManager = trade_queue_manager.THSBuy1VolumnManager()
@@ -167,6 +215,27 @@
    __l2PlaceOrderParamsManagerDict = {}
    __last_buy_single_dict = {}
    __TradeBuyQueue = transaction_progress.TradeBuyQueue()
    __latest_process_order_unique_keys = {}
    __latest_process_not_order_unique_keys = {}
    # 初始化
    __TradePointManager = l2_data_manager.TradePointManager()
    __SecondCancelBigNumComputer = SecondCancelBigNumComputer()
    __HourCancelBigNumComputer = HourCancelBigNumComputer()
    __LCancelBigNumComputer = LCancelBigNumComputer()
    __DCancelBigNumComputer = DCancelBigNumComputer()
    __TradeStateManager = trade_manager.TradeStateManager()
    __CodesTradeStateManager = trade_manager.CodesTradeStateManager()
    __PauseBuyCodesManager = gpcode_manager.PauseBuyCodesManager()
    __Buy1PriceManager = code_price_manager.Buy1PriceManager()
    __AccountAvailableMoneyManager = AccountAvailableMoneyManager()
    __TradeBuyDataManager = trade_data_manager.TradeBuyDataManager()
    __LimitUpTimeManager = limit_up_time_manager.LimitUpTimeManager()
    __BlackListCodeManager = l2_trade_util.BlackListCodeManager()
    __WhiteListCodeManager = l2_trade_util.WhiteListCodeManager()
    __WantBuyCodesManager = gpcode_manager.WantBuyCodesManager()
    __TradeTargetCodeModeManager = TradeTargetCodeModeManager()
    __DealComputeProgressManager = DealComputeProgressManager()
    __TradeOrderIdManager = trade_huaxin.TradeOrderIdManager()
    # 获取代码评分
    @classmethod
@@ -212,9 +281,9 @@
                    # 保存数据
                    __start_time = round(t.time() * 1000)
                    l2.l2_data_util.save_l2_data(code, datas, add_datas)
                    __start_time = l2_data_log.l2_time(code,
                                                       round(t.time() * 1000) - __start_time,
                                                       "保存数据时间({})".format(len(add_datas)))
                    # __start_time = l2_data_log.l2_time(code,
                    #                                    round(t.time() * 1000) - __start_time,
                    #                                    "保存数据时间({})".format(len(add_datas)))
        finally:
            if code in cls.unreal_buy_dict:
                cls.unreal_buy_dict.pop(code)
@@ -223,8 +292,8 @@
    @classmethod
    def process_huaxin(cls, code, origin_datas):
        print("process_huaxin", code, len(origin_datas))
        origin_start_time = round(t.time() * 1000)
        datas = None
        origin_start_time = round(t.time() * 1000)
        try:
            # 加载历史的L2数据
            is_normal = l2.l2_data_util.load_l2_data(code, load_latest=False)
@@ -232,6 +301,7 @@
                print("历史数据异常:", code)
                # 数据不正常需要禁止交易
                l2_trade_util.forbidden_trade(code)
            origin_start_time = round(t.time() * 1000)
            # 转换数据格式
            _start_index = 0
            total_datas = local_today_datas.get(code)
@@ -242,8 +312,9 @@
            # 获取下单位置
            place_order_index = huaxin_delegate_postion_manager.get_l2_place_order_position(code, datas)
            if place_order_index:
                logger_l2_process.info("code:{} 获取到下单真实位置:{}", code, place_order_index)
                DCancelBigNumComputer.set_real_order_index(code, place_order_index)
                cls.__DCancelBigNumComputer.set_real_order_index(code, place_order_index)
                cls.__SecondCancelBigNumComputer.set_real_place_order_index(code, place_order_index)
                async_log_util.info(logger_l2_process, "code:{} 获取到下单真实位置:{}", code, place_order_index)
            __start_time = round(t.time() * 1000)
            if len(datas) > 0:
                cls.process_add_datas(code, datas, 0, __start_time)
@@ -262,11 +333,13 @@
        except Exception as e:
            print("huaxin L2数据处理异常", code, str(e))
            logging.exception(e)
            logger_l2_error.exception(f"code:{code}")
            logger_l2_error.exception(e)
        finally:
            l2_data_log.l2_time(code, round(t.time() * 1000) - origin_start_time,
                                "l2数据处理总耗时",
                                True)
            # l2_data_log.l2_time(code, round(t.time() * 1000) - origin_start_time,
            #                     "l2数据处理总耗时",
            #                     True)
            pass
            if datas:
                l2.l2_data_util.save_l2_data(code, None, datas)
@@ -287,11 +360,11 @@
                        # 当前涨停价,设置涨停时间
                        logger_l2_process.info("开盘涨停:{}", code)
                        # 保存涨停时间
                        limit_up_time_manager.save_limit_up_time(code, "09:30:00")
                        cls.__LimitUpTimeManager.save_limit_up_time(code, "09:30:00")
        total_datas = local_today_datas[code]
        __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
                                           "l2数据预处理时间")
        # __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
        #                                    "l2数据预处理时间")
        if len(add_datas) > 0:
            # 是否为首板代码
@@ -300,11 +373,11 @@
            volume_rate = code_volumn_manager.get_volume_rate(code)
            volume_rate_index = code_volumn_manager.get_volume_rate_index(volume_rate)
            # 计算分值
            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
            limit_up_time = cls.__LimitUpTimeManager.get_limit_up_time_cache(code)
            if limit_up_time is None:
                limit_up_time = tool.get_now_time_str()
            score = first_code_score_manager.get_score(code, volume_rate, limit_up_time, True)
            # score = first_code_score_manager.get_score(code, volume_rate, limit_up_time, True)
            score = None
            cls.__l2PlaceOrderParamsManagerDict[code] = l2_trade_factor.L2PlaceOrderParamsManager(code, is_first_code,
                                                                                                  volume_rate,
                                                                                                  volume_rate_index,
@@ -315,12 +388,12 @@
            latest_time = add_datas[len(add_datas) - 1]["val"]["time"]
            __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
                                               "l2数据准备时间")
            # __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
            #                                    "l2数据准备时间")
            # 时间差不能太大才能处理
            if not l2_trade_util.is_in_forbidden_trade_codes(code):
                # 判断是否已经挂单
                state = trade_manager.get_trade_state(code)
                state = cls.__CodesTradeStateManager.get_trade_state_cache(code)
                start_index = len(total_datas) - len(add_datas)
                end_index = len(total_datas) - 1
                if state == trade_manager.TRADE_STATE_BUY_DELEGATED or state == trade_manager.TRADE_STATE_BUY_PLACE_ORDER or state == trade_manager.TRADE_STATE_BUY_SUCCESS:
@@ -345,11 +418,12 @@
                    if l2.l2_data_util.L2DataUtil.is_same_time(now_time_str, latest_time):
                        cls.__process_not_order(code, start_index, end_index, capture_timestamp, is_first_code)
            logger_l2_process.info("code:{} 处理数据范围: {}-{} 处理时间:{} 截图时间戳:{}", code, add_datas[0]["index"],
                                   add_datas[-1]["index"], round(t.time() * 1000) - __start_time,
                                   capture_timestamp)
            __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
                                               "l2数据处理时间")
            async_log_util.info(logger_l2_process, "code:{} 处理数据范围: {}-{} 处理时间:{} 截图时间戳:{}", code,
                                add_datas[0]["index"],
                                add_datas[-1]["index"], round(t.time() * 1000) - __start_time,
                                capture_timestamp)
            # __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
            #                                    "l2数据处理时间")
    # 处理未挂单
    @classmethod
@@ -357,24 +431,21 @@
        __start_time = round(t.time() * 1000)
        # 获取阈值
        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值数据耗时")
        # if round(t.time() * 1000) - __start_time > 10:
        #     __start_time = l2_data_log.l2_time(code, round(t.time() * 1000) - __start_time,
        #                                        "获取m值数据耗时")
        if True:  # end_index - start_index < 10:
            cls.__start_compute_buy(code, start_index, end_index, threshold_money, capture_time, is_first_code)
        else:
            pass
            # lp = LineProfiler()
            # lp.enable()
            # lp_wrap = lp(cls.__start_compute_buy)
            # lp_wrap(code, start_index, end_index, threshold_money, capture_time, is_first_code)
            # output = io.StringIO()
            # lp.print_stats(stream=output)
            # lp.disable()
            # with open(
            #         f"/home/logs/profile/{code}_start_compute_buy_{start_index}_{end_index}.txt",
            #         'w') as f:
            #     f.write(output.getvalue())
            # pass
            lp = LineProfiler()
            lp.enable()
            lp_wrap = lp(cls.__start_compute_buy)
            lp_wrap(code, start_index, end_index, threshold_money, capture_time, is_first_code)
            output = io.StringIO()
            lp.print_stats(stream=output)
            lp.disable()
            logger_profile.info(output.getvalue())
    # 测试专用
    @classmethod
@@ -384,133 +455,80 @@
    # 处理已挂单
    @classmethod
    def __process_order(cls, code, start_index, end_index, capture_time, is_first_code, new_add=True):
        # 计算安全笔数
        @dask.delayed
        def compute_safe_count():
            _start_time = round(t.time() * 1000)
            # 处理安全笔数
            cls.__buyL2SafeCountManager.compute_left_rate(code, start_index, end_index, total_data,
                                                          local_today_num_operate_map.get(code))
            l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time,
                                "已下单-获取买入信息耗时")
            return None, ""
        @dask.delayed
        # m值大单计算
        def compute_m_big_num():
            _start_time = round(t.time() * 1000)
            # 计算m值大单
            cls.l2BigNumForMProcessor.process(code, max(buy_single_index, start_index), end_index,
                                              gpcode_manager.get_limit_up_price(code))
            l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time,
                                "已下单-m值大单计算")
            return None, ""
        # 买1撤计算
        @dask.delayed
        def buy_1_cancel():
            _start_time = round(t.time() * 1000)
            # 撤单计算,只看买1
            cancel_data, cancel_msg = L2LimitUpMoneyStatisticUtil.process_data(code, start_index,
                                                                               end_index,
                                                                               buy_single_index, buy_exec_index)
            l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time,
                                "已下单-买1统计耗时")
            # 买1不会触发撤单
            return None, ""
            # return cancel_data, cancel_msg
        # 增加推出机制
        unique_key = f"{start_index}-{end_index}"
        if cls.__latest_process_order_unique_keys.get(code) == unique_key:
            logger_l2_error.error(f"重复处理数据:code-{code} start_index-{start_index} end_index-{end_index}")
            return
        cls.__latest_process_order_unique_keys[code] = unique_key
        # S撤
        @dask.delayed
        def s_cancel():
        def s_cancel(_buy_single_index, _buy_exec_index):
            _start_time = round(t.time() * 1000)
            # S撤单计算,看秒级大单撤单
            try:
                b_need_cancel, b_cancel_data = SecondCancelBigNumComputer.need_cancel(code, buy_single_index,
                                                                                      buy_exec_index, start_index,
                                                                                      end_index, total_data,
                                                                                      code_volumn_manager.get_volume_rate_index(
                                                                                          buy_volume_rate),
                                                                                      cls.volume_rate_info[code][1],
                                                                                      is_first_code)
                b_need_cancel, b_cancel_data = cls.__SecondCancelBigNumComputer.need_cancel(code, _buy_single_index,
                                                                                            _buy_exec_index,
                                                                                            start_index,
                                                                                            end_index, total_data,
                                                                                            code_volumn_manager.get_volume_rate_index(
                                                                                                buy_volume_rate),
                                                                                            cls.volume_rate_info[code][
                                                                                                1],
                                                                                            is_first_code)
                if b_need_cancel:
                    return b_cancel_data, "S大单撤销比例触发阈值"
            except Exception as e:
                logging.exception(e)
                logger_l2_error.error(f"参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index}")
                logger_l2_error.exception(e)
            finally:
                l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time,
                                    "已下单-s级大单估算")
                # l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time,
                #                     "已下单-s级大单估算")
                pass
            return None, ""
        # H撤
        @dask.delayed
        def h_cancel():
        def h_cancel(_buy_single_index, _buy_exec_index):
            _start_time = round(t.time() * 1000)
            try:
                b_need_cancel, b_cancel_data = HourCancelBigNumComputer.need_cancel(code, buy_single_index,
                                                                                    buy_exec_index, start_index,
                                                                                    end_index, total_data,
                                                                                    local_today_num_operate_map.get(
                                                                                        code),
                                                                                    code_volumn_manager.get_volume_rate_index(
                                                                                        buy_volume_rate),
                                                                                    cls.volume_rate_info[code][1],
                                                                                    is_first_code)
                b_need_cancel, b_cancel_data = cls.__HourCancelBigNumComputer.need_cancel(code, _buy_single_index,
                                                                                          _buy_exec_index, start_index,
                                                                                          end_index, total_data,
                                                                                          local_today_num_operate_map.get(
                                                                                              code),
                                                                                          code_volumn_manager.get_volume_rate_index(
                                                                                              buy_volume_rate),
                                                                                          cls.volume_rate_info[code][1],
                                                                                          is_first_code)
                if b_need_cancel and b_cancel_data:
                    return b_cancel_data, "H撤销比例触发阈值"
            except Exception as e:
                logging.exception(e)
                logger_l2_error.error(f"参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index}")
                logger_l2_error.exception(e)
            finally:
                l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "已下单-H撤大单计算")
                # l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "已下单-H撤大单计算")
                pass
            return None, ""
        # L撤
        @dask.delayed
        def l_cancel():
        def l_cancel(_buy_single_index, _buy_exec_index):
            _start_time = round(t.time() * 1000)
            try:
                b_need_cancel, b_cancel_data = LCancelBigNumComputer.need_cancel(code,
                                                                                 buy_exec_index, start_index,
                                                                                 end_index, total_data,
                                                                                 local_today_num_operate_map.get(
                                                                                     code), is_first_code)
                b_need_cancel, b_cancel_data = cls.__LCancelBigNumComputer.need_cancel(code,
                                                                                       _buy_exec_index, start_index,
                                                                                       end_index, total_data,
                                                                                       local_today_num_operate_map.get(
                                                                                           code), is_first_code)
                if b_need_cancel and b_cancel_data:
                    return b_cancel_data, "L撤销比例触发阈值"
            except Exception as e:
                logging.exception(e)
                logger_l2_error.error(f"参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index}")
                logger_l2_error.exception(e)
            finally:
                l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "已下单-L撤大单计算")
            return None, ""
        # 板上卖撤
        @dask.delayed
        def sell_cancel():
            _start_time = round(t.time() * 1000)
            # 统计板上卖
            try:
                cancel_data, cancel_msg = L2LimitUpSellStatisticUtil.process(code, start_index,
                                                                             end_index,
                                                                             buy_exec_index)
                return cancel_data, cancel_msg
            except Exception as e:
                logging.exception(e)
            finally:
                l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "已下单-板上卖耗时")
            return None, ""
        # 是否需要撤销
        @dask.delayed
        def is_need_cancel(*args):
            try:
                for i in range(0, len(args)):
                    _cancel_data, _cancel_msg = args[i]
                    if _cancel_data:
                        return _cancel_data, _cancel_msg
            except Exception as e:
                logging.exception(e)
            finally:
                # l2_data_log.l2_time(code, round(t.time() * 1000) - _start_time, "已下单-L撤大单计算")
                pass
            return None, ""
@@ -524,48 +542,32 @@
        # 获取买入信号起始点
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
            code)
        # 默认量为0.2
        if buy_volume_rate is None:
            buy_volume_rate = 0.2
        f1 = compute_safe_count()
        f2 = compute_m_big_num()
        f3 = s_cancel()
        f4 = h_cancel()
        f5 = buy_1_cancel()
        f6 = sell_cancel()
        f7 = l_cancel()
        dask_result = is_need_cancel(f1, f2, f3, f4, f5, f6, f7)
        if is_first_code:
            dask_result = is_need_cancel(f3, f4, f7)
        cancel_data, cancel_msg = dask_result.compute()
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                          "已下单-撤单 判断是否需要撤单")
        # 依次处理
        cancel_data, cancel_msg = s_cancel(buy_single_index, buy_exec_index)
        # if not cancel_data:
        #     cancel_data, cancel_msg = h_cancel(buy_single_index, buy_exec_index)
        if not cancel_data:
            cancel_data, cancel_msg = l_cancel(buy_single_index, buy_exec_index)
        # l2_log.debug(code, "撤单计算结束")
        # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
        #                                   "已下单-撤单 判断是否需要撤单")
        if cancel_data:
            l2_log.debug(code, "触发撤单,撤单位置:{} ,撤单原因:{}", cancel_data["index"], cancel_msg)
            l2_log.trade_record(code, "撤单", "'index':{} , 'msg':'{}'", cancel_data["index"], cancel_msg)
            # 撤单
            if cls.cancel_buy(code, cancel_msg):
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "已下单-撤单 耗时")
                # 撤单成功,继续计算下单
                cls.__process_not_order(code, cancel_data["index"] + 1, end_index, capture_time, is_first_code)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "处理剩余数据 耗时")
            else:
                # 撤单尚未成功
                pass
            cls.cancel_buy(code, cancel_msg)
            # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
            #                                   "已下单-撤单 耗时")
            # 撤单成功,继续计算下单
            cls.__process_not_order(code, cancel_data["index"] + 1, end_index, capture_time, is_first_code)
            # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
            #                                   "处理剩余数据 耗时")
        else:
            # 如果有虚拟下单需要真实下单
            unreal_buy_info = cls.unreal_buy_dict.get(code)
            if unreal_buy_info is not None:
                l2_log.debug(code, "有虚拟下单,无买撤信号,开始执行买入,执行位置:{},截图时间:{}", unreal_buy_info[0], capture_time)
                # unreal_buy_info 的内容格式为:(触法买操作下标,截图时间)
                # 真实下单
                cls.__buy(code, unreal_buy_info[1], local_today_datas[code][unreal_buy_info[0]],
                          unreal_buy_info[0], is_first_code)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "已虚拟下单-执行真实下单 外部耗时")
            pass
    @classmethod
    def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code):
@@ -576,7 +578,7 @@
        else:
            can, need_clear_data, reason = cls.__can_buy_first(code)
        __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True)
        # __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True)
        # 删除虚拟下单
        if code in cls.unreal_buy_dict:
            cls.unreal_buy_dict.pop(code)
@@ -588,7 +590,7 @@
            if need_clear_data:
                trade_result_manager.real_cancel_success(code, buy_single_index, buy_exec_index,
                                                         local_today_datas.get(code))
            return
            return False
        else:
            l2_log.debug(code, "可以下单,原因:{}", reason)
@@ -596,28 +598,31 @@
                l2_log.debug(code, "开始执行买入")
                trade_manager.start_buy(code, capture_timestamp, last_data,
                                        last_data_index)
                ################下单成功处理################
                trade_result_manager.real_buy_success(code)
                l2_log.debug(code, "执行买入成功")
                ################下单成功处理################
                trade_result_manager.real_buy_success(code, cls.__TradePointManager)
                l2_log.debug(code, "处理买入成功")
                params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc()
                l2_log.debug(code, params_desc)
                l2_log.trade_record(code, "下单",
                                    "'buy_start_index':{} ,'buy_exec_index':{},'volume_reate':{},'score':{},'desc':'{}'",
                                    "'buy_start_index':{} ,'buy_exec_index':{},'volume_reate':{},'desc':'{}'",
                                    buy_single_index, buy_exec_index, cls.volume_rate_info[code][0],
                                    cls.__l2PlaceOrderParamsManagerDict[code].score, params_desc)
                                    params_desc)
            except Exception as e:
                logger_l2_error.exception(e)
                l2_log.debug(code, "执行买入异常:{}", str(e))
                pass
            finally:
                l2_log.debug(code, "m值影响因子:{}", l2_trade_factor.L2TradeFactorUtil.factors_to_string(code))
                # l2_log.debug(code, "m值影响因子:{}", l2_trade_factor.L2TradeFactorUtil.factors_to_string(code))
                pass
            return True
    # 是否可以取消
    @classmethod
    def __can_cancel(cls, code):
        if constant.TEST:
            return True, ""
        if l2_trade_util.WhiteListCodeManager.is_in(code):
        if cls.__WhiteListCodeManager.is_in_cache(code):
            return False, "代码在白名单中"
        # 暂时注释掉
@@ -651,22 +656,22 @@
    @classmethod
    def __can_buy(cls, code):
        __start_time = t.time()
        if not trade_manager.TradeStateManager.is_can_buy():
        if not cls.__TradeStateManager.is_can_buy_cache():
            return False, True, f"今日已禁止交易"
        # 之前的代码
        # 首板代码且尚未涨停过的不能下单
        # is_limited_up = gpcode_manager.FirstCodeManager().is_limited_up(code)
        # if not is_limited_up:
        #     gpcode_manager.FirstCodeManager().add_limited_up_record([code])
        #     place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(
        #     place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(
        #         code)
        #     if place_order_count == 0:
        #         trade_data_manager.placeordercountmanager.place_order(code)
        #         trade_data_manager.PlaceOrderCountManager().place_order(code)
        #     return False, True, "首板代码,且尚未涨停过"
        try:
            # 买1价格必须为涨停价才能买
            # buy1_price = cls.buy1PriceManager.get_price(code)
            # buy1_price = cls.buy1PriceManager().get_price(code)
            # if buy1_price is None:
            #     return False, "买1价尚未获取到"
            # limit_up_price = gpcode_manager.get_limit_up_price(code)
@@ -706,7 +711,7 @@
            if volumn_rate >= 1.3:
                return False, False, "最大量比超过1.3不能买"
            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
            limit_up_time = cls.__LimitUpTimeManager.get_limit_up_time_cache(code)
            if limit_up_time is not None:
                limit_up_time_seconds = l2.l2_data_util.L2DataUtil.get_time_as_second(
                    limit_up_time)
@@ -774,27 +779,28 @@
            # 可以下单
            return True, False, None
        finally:
            l2_data_log.l2_time(code, round((t.time() - __start_time) * 1000), "是否可以下单计算")
            # l2_data_log.l2_time(code, round((t.time() - __start_time) * 1000), "是否可以下单计算")
            pass
    @classmethod
    def __can_buy_first(cls, code):
        if not trade_manager.TradeStateManager.is_can_buy():
        if not cls.__TradeStateManager.is_can_buy_cache():
            return False, True, f"今日已禁止交易"
        if gpcode_manager.PauseBuyCodesManager.is_in(code):
        if cls.__PauseBuyCodesManager.is_in_cache(code):
            return False, True, f"该代码被暂停交易"
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if float(limit_up_price) >= 40:
            return False, True, "股价大于40块"
        if float(limit_up_price) >= constant.MAX_CODE_PRICE:
            return False, True, f"股价大于{constant.MAX_CODE_PRICE}块"
        if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_HUAXIN:
            trade_price = current_price_process_manager.get_trade_price(code)
            if trade_price is None:
                return False, True, f"尚未获取到当前成交价"
            if float(limit_up_price) - float(trade_price) > 0.02001:
                return False, False, f"当前成交价({trade_price})尚未在2档及以内"
            if float(limit_up_price) - float(trade_price) > 0.04001:
                return False, False, f"当前成交价({trade_price})尚未在4档及以内"
            # 判断成交进度是否距离我们的位置很近
            total_data = local_today_datas.get(code)
@@ -805,7 +811,9 @@
                for i in range(trade_index + 1, total_data[-1]["index"] + 1):
                    if L2DataUtil.is_limit_up_price_buy(total_data[i]["val"]):
                        left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code,
                                                                                                              total_data[i]["index"],
                                                                                                              total_data[
                                                                                                                  i][
                                                                                                                  "index"],
                                                                                                              total_data,
                                                                                                              num_operate_map)
                        if left_count > 0:
@@ -821,7 +829,7 @@
                zyltgb = global_util.zyltgb_map.get(code)
            if zyltgb >= 200 * 100000000:
                buy1_price = code_price_manager.Buy1PriceManager.get_buy1_price(code)
                buy1_price = cls.__Buy1PriceManager.get_buy1_price(code)
                if buy1_price is None:
                    return False, True, f"尚未获取到买1价"
                dif = float(limit_up_price) - float(buy1_price)
@@ -829,106 +837,80 @@
                if dif > 0.10001:
                    return False, True, f"自由流通200亿以上,买1剩余档数大于10档,买一({buy1_price})涨停({limit_up_price})"
        open_limit_up_lowest_price = code_price_manager.Buy1PriceManager.get_open_limit_up_lowest_price(code)
        open_limit_up_lowest_price = cls.__Buy1PriceManager.get_open_limit_up_lowest_price(code)
        price_pre_close = gpcode_manager.CodePrePriceManager.get_price_pre_cache(code)
        if open_limit_up_lowest_price and (
                float(open_limit_up_lowest_price) - price_pre_close) / price_pre_close < 0.05:
            return False, True, f"炸板后最低价跌至5%以下"
        limit_up_info = code_price_manager.Buy1PriceManager.get_limit_up_info(code)
        if limit_up_info[0] is None and False:
            total_data = local_today_datas.get(code)
            buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
                code)
            # 之前没有涨停过
            # 统计买入信号位到当前位置没有撤的大单金额
            min_money_w = l2_data_util.get_big_money_val(float(total_data[buy_single_index]["val"]["price"])) // 10000
            left_big_num = l2.cancel_buy_strategy.SecondCancelBigNumComputer.compute_left_big_num(code,
                                                                                                  buy_single_index,
                                                                                                  buy_exec_index,
                                                                                                  total_data[-1][
                                                                                                      "index"],
                                                                                                  total_data,
                                                                                                  0, min_money_w)
            if left_big_num > 0:
                # 重新获取分数与分数索引
                limit_up_time = limit_up_time_manager.get_limit_up_time(code)
                if limit_up_time is None:
                    limit_up_time = tool.get_now_time_str()
                score = first_code_score_manager.get_score(code, cls.volume_rate_info[code][0], limit_up_time, True,
                                                           left_big_num)
                cls.__l2PlaceOrderParamsManagerDict[code].set_score(score)
        # limit_up_info = cls.__Buy1PriceManager.get_limit_up_info(code)
        # if limit_up_info[0] is None and False:
        #     total_data = local_today_datas.get(code)
        #     buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
        #         code)
        #     # 之前没有涨停过
        #     # 统计买入信号位到当前位置没有撤的大单金额
        #     min_money_w = l2_data_util.get_big_money_val(float(total_data[buy_single_index]["val"]["price"])) // 10000
        #     left_big_num = cls.__SecondCancelBigNumComputer.compute_left_big_num(code,
        #                                                                          buy_single_index,
        #                                                                          buy_exec_index,
        #                                                                          total_data[-1][
        #                                                                              "index"],
        #                                                                          total_data,
        #                                                                          0, min_money_w)
        #     if left_big_num > 0:
        #         # 重新获取分数与分数索引
        #         limit_up_time = cls.__LimitUpTimeManager.get_limit_up_time_cache(code)
        #         if limit_up_time is None:
        #             limit_up_time = tool.get_now_time_str()
        #         score = first_code_score_manager.get_score(code, cls.volume_rate_info[code][0], limit_up_time, True,
        #                                                    left_big_num)
        #         cls.__l2PlaceOrderParamsManagerDict[code].set_score(score)
        logger_place_order_score.info("code={},data='score_index':{},'score_info':{}", code,
                                      cls.__l2PlaceOrderParamsManagerDict[code].score_index,
                                      cls.__l2PlaceOrderParamsManagerDict[code].score_info)
        # logger_place_order_score.info("code={},data='score_index':{},'score_info':{}", code,
        #                               cls.__l2PlaceOrderParamsManagerDict[code].score_index,
        #                               cls.__l2PlaceOrderParamsManagerDict[code].score_info)
        if not gpcode_manager.WantBuyCodesManager().is_in_cache(code):
            if TradeTargetCodeModeManager.get_mode() == TradeTargetCodeModeManager.MODE_ONLY_BUY_WANT_CODES:
        if not cls.__WantBuyCodesManager.is_in_cache(code):
            if cls.__TradeTargetCodeModeManager.get_mode_cache() == TradeTargetCodeModeManager.MODE_ONLY_BUY_WANT_CODES:
                return False, True, f"只买想买单中的代码"
            score_index = cls.__l2PlaceOrderParamsManagerDict[code].score_index
            score = cls.__l2PlaceOrderParamsManagerDict[code].score
            score_info = cls.__l2PlaceOrderParamsManagerDict[code].score_info
            score_index = None  # cls.__l2PlaceOrderParamsManagerDict[code].score_index
            score = None  # cls.__l2PlaceOrderParamsManagerDict[code].score
            score_info = None  # cls.__l2PlaceOrderParamsManagerDict[code].score_info
            lp = LineProfiler()
            lp.enable()
            lp_wrap = lp(cls.can_buy_first)
            results = lp_wrap(code, limit_up_price, score_index, score, score_info, cls.volume_rate_info[code])
            output = io.StringIO()
            lp.print_stats(stream=output)
            lp.disable()
            with open(f"{constant.get_path_prefix()}/logs/profile/{code}_can_buy_first.txt", 'w') as f:
                f.write(output.getvalue())
            # return cls.can_buy_first(code, limit_up_price, score_index, score, score_info, cls.volume_rate_info[code])
            return results
            # lp = LineProfiler()
            # lp.enable()
            # lp_wrap = lp(cls.can_buy_first)
            # results = lp_wrap(code, limit_up_price, score_index, score, score_info, cls.volume_rate_info[code])
            # output = io.StringIO()
            # lp.print_stats(stream=output)
            # lp.disable()
            # with open(f"{constant.get_path_prefix()}/logs/profile/{code}_can_buy_first.txt", 'w') as f:
            #     f.write(output.getvalue())
            # return results
            return cls.can_buy_first(code, limit_up_price)
        else:
            return True, False, "在想买名单中"
    @classmethod
    def can_buy_first(cls, code, limit_up_price, score_index, score, score_info, volume_rate_info):
        def is_has_k_format(score_info):
            # (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V,是否有形态,天量大阳信息,是否具有辨识度)
            if score_info[1][3][6][0] and not score_info[1][3][3][0]:
                return True
            if score_info[1][3][7][0]:
                return True
            return False
        if float(limit_up_price) >= 40:
            return False, True, "股价大于40块"
        # 9:35之前买大市值(>=80亿)票
        if int(tool.get_now_date_str("%Y%m%d")) < int("093500"):
            zyltgb = global_util.zyltgb_map.get(code)
            if zyltgb is None:
                global_data_loader.load_zyltgb()
                zyltgb = global_util.zyltgb_map.get(code)
            if zyltgb >= 80 * 100000000:
                return True, False, "{9:30:00-9:35:00}自由市值≥80亿"
    def can_buy_first(cls, code, limit_up_price):
        # 判断板块
        yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes()
        plate_can_buy, msg = CodePlateKeyBuyManager.can_buy(code,
                                                            kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas,
                                                            kpl_data_manager.KPLLimitUpDataRecordManager.total_datas,
                                                            yesterday_codes,
                                                            block_info.get_before_blocks_dict())
        if not plate_can_buy:
            return False, True, msg
        return True, False, msg
        can_buy_result = CodePlateKeyBuyManager.can_buy(code)
        if can_buy_result is None:
            logger_debug.warning("没有获取到板块缓存,将获取板块")
            yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes()
            CodePlateKeyBuyManager.update_can_buy_blocks(code,
                                                         kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas,
                                                         kpl_data_manager.KPLLimitUpDataRecordManager.total_datas,
                                                         yesterday_codes,
                                                         block_info.get_before_blocks_dict())
            can_buy_result = CodePlateKeyBuyManager.can_buy(code)
        # if volume_rate_info[0] < 0.4:
        #     return False, True, f"量大于40%才下单,量比:{volume_rate_info[0]}"
        # 是否有K线形态(有K线形态或者天量大阳),10点后才需要判断是否有K线形态与分值
        if int(tool.get_now_time_str().replace(":", "")) > int("100000"):
            has_k_format = score_info[1][3][6][0] or score_info[1][3][7][0]
            if not has_k_format:
                return False, True, f"无K线形态"
            if score_index < 0:
                return False, True, f"分值:{score}未达到需要买入的分数线"
        return True, False, ""
        if can_buy_result is None:
            return False, True, "尚未获取到板块信息"
        if not can_buy_result[0]:
            return False, True, can_buy_result[1]
        return True, False, can_buy_result[1]
    @classmethod
    def __cancel_buy(cls, code):
@@ -984,11 +966,18 @@
                            new_add=True):
        if compute_end_index < compute_start_index:
            return
        unique_key = f"{compute_start_index}-{compute_end_index}"
        if cls.__latest_process_not_order_unique_keys.get(code) == unique_key:
            logger_l2_error.error(f"重复处理数据:code-{code} start_index-{compute_start_index} end_index-{compute_end_index}")
            return
        cls.__latest_process_not_order_unique_keys[code] = unique_key
        _start_time = tool.get_now_timestamp()
        total_datas = local_today_datas[code]
        # 处理安全笔数
        cls.__buyL2SafeCountManager.compute_left_rate(code, compute_start_index, compute_end_index, total_datas,
                                                      local_today_num_operate_map.get(code))
        # cls.__buyL2SafeCountManager.compute_left_rate(code, compute_start_index, compute_end_index, total_datas,
        #                                               local_today_num_operate_map.get(code))
        # 获取买入信号计算起始位置
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
@@ -1015,10 +1004,8 @@
                count = 0
                l2_log.debug(code, "获取到买入信号起始点:{} ,计算范围:{}-{} ,量比:{},数据:{}", buy_single_index, compute_start_index,
                             compute_end_index, cls.volume_rate_info[code], total_datas[buy_single_index])
                # 如果是今天第一次有下单开始信号,需要设置大单起始点
                cls.l2BigNumForMProcessor.set_begin_pos(code, buy_single_index)
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "下单信号计算时间")
        # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "下单信号计算时间")
        if buy_single_index is None:
            # 未获取到买入信号,终止程序
@@ -1029,16 +1016,11 @@
        if new_get_single:
            start_process_index = buy_single_index
        # 计算m值大单
        cls.l2BigNumForMProcessor.process(code, start_process_index,
                                          compute_end_index,
                                          gpcode_manager.get_limit_up_price(code))
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "计算m值大单")
        # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "计算m值大单")
        threshold_money, msg = cls.__get_threshmoney(code)
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "m值阈值计算")
        # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "m值阈值计算")
        # 买入纯买额统计
        compute_index, buy_nums, buy_count, rebegin_buy_pos, max_num_set_new = cls.__sum_buy_num_for_order_3(code,
@@ -1048,9 +1030,10 @@
                                                                                                             threshold_money,
                                                                                                             buy_single_index,
                                                                                                             max_num_set)
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "纯买额统计时间")
        # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "纯买额统计时间")
        l2_log.debug(code, "m值-{} 量比:{}", threshold_money, cls.volume_rate_info[code][0])
        l2_log.debug(code, "m值-{} 量比:{} rebegin_buy_pos:{}", threshold_money, cls.volume_rate_info[code][0],
                     rebegin_buy_pos)
        # 买入信号位与计算位置间隔2s及以上了
        if rebegin_buy_pos is not None:
@@ -1063,72 +1046,22 @@
            l2_log.debug(code, "获取到买入执行位置:{} m值:{} 纯买手数:{} 纯买单数:{} 数据:{} ,量比:{} ", compute_index, threshold_money,
                         buy_nums,
                         buy_count, total_datas[compute_index], cls.volume_rate_info[code])
            f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index,
                                                           buy_nums, buy_count, max_num_set_new,
                                                           cls.volume_rate_info[code][0])
            f2 = dask.delayed(limit_up_time_manager.save_limit_up_time)(code, total_datas[compute_index]["val"]["time"])
            f3 = dask.delayed(cls.__virtual_buy)(code, buy_single_index, compute_index, capture_time)
            f4 = dask.delayed(l2_data_manager.TradePointManager.delete_buy_cancel_point)(code)
            f5 = dask.delayed(L2LimitUpMoneyStatisticUtil.process_data)(code, buy_single_index,
                                                                        compute_index,
                                                                        buy_single_index,
                                                                        buy_exec_index, False)
            dask.compute(f1, f2, f3, f4, f5)
            # 已被并行处理
            # # 记录买入信号位置
            # cls.__save_order_begin_data(code, buy_single_index, compute_index, compute_index, buy_nums, buy_count,
            #                             max_num_set_new)
            # # 如果是今天第一次有下单执行信号,涨停时间(买入执行位时间)
            # limit_up_time_manager.save_limit_up_time(code, total_datas[compute_index]["val"]["time"])
            # # 虚拟下单
            # cls.__virtual_buy(code, buy_single_index, compute_index, capture_time)
            # # 删除之前的所有撤单信号
            # l2_data_manager.TradePointManager.delete_buy_cancel_point(code)
            #
            # # 涨停封单额计算
            # L2LimitUpMoneyStatisticUtil.process_data(cls.random_key[code], code, buy_single_index, compute_index,
            #                                          buy_single_index,
            #                                          buy_exec_index, False)
            _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                              "记录执行买入数据", force=True)
            cls.__save_order_begin_data(code, buy_single_index, compute_index, compute_index,
                                        buy_nums, buy_count, max_num_set_new,
                                        cls.volume_rate_info[code][0])
            cls.__LimitUpTimeManager.save_limit_up_time(code, total_datas[compute_index]["val"]["time"])
            cls.__TradePointManager.delete_buy_cancel_point(code)
            l2_log.debug(code, "delete_buy_cancel_point")
            # 直接下单
            ordered = cls.__buy(code, capture_time, total_datas[compute_index], compute_index, is_first_code)
            # 数据是否处理完毕
            if compute_index >= compute_end_index:
                need_cancel, cancel_data = SecondCancelBigNumComputer.need_cancel(code, buy_single_index,
                                                                                  compute_index,
                                                                                  buy_single_index, compute_index,
                                                                                  total_datas, is_first_code,
                                                                                  cls.volume_rate_info[code][1],
                                                                                  cls.volume_rate_info[code][1],
                                                                                  True)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "S级大单处理耗时", force=True)
                l2_log.debug(code, "数据处理完毕,下单, 数据截图时间-{}", capture_time)
                # 数据已经处理完毕,如果还没撤单就实际下单
                if need_cancel:
                    if cls.cancel_buy(code, "S级大单撤销"):
                        # 执行撤单成功
                        pass
            if compute_index < compute_end_index:
                if ordered:
                    cls.__process_order(code, compute_index + 1, compute_end_index, capture_time, is_first_code, False)
                else:
                    cls.__buy(code, capture_time, total_datas[compute_index], compute_index, is_first_code)
            else:
                SecondCancelBigNumComputer.need_cancel(code, buy_single_index, compute_index, buy_single_index,
                                                       compute_index, total_datas, is_first_code,
                                                       cls.volume_rate_info[code][1],
                                                       cls.volume_rate_info[code][1], False)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "S级大单处理耗时", force=True)
                # 数据尚未处理完毕,进行下一步处理
                l2_log.debug(code, "数据尚未处理完毕,进行下一步处理,处理进度:{}", compute_index)
                # 处理撤单步骤
                cls.__process_order(code, compute_index + 1, compute_end_index, capture_time, is_first_code, False)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  f"处理撤单步骤耗时,范围:{compute_index + 1}-{compute_end_index}", force=True)
                    cls.__start_compute_buy(code, compute_index + 1, compute_end_index, threshold_money, capture_time,
                                            is_first_code)
        else:
            # 未达到下单条件,保存纯买额,设置纯买额
            # 记录买入信号位置
@@ -1141,16 +1074,17 @@
    # 获取下单起始信号
    @classmethod
    def __get_order_begin_pos(cls, code):
        buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data_cache(
        buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate = cls.__TradePointManager.get_buy_compute_start_data_cache(
            code)
        return buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate
    # 保存下单起始信号
    @classmethod
    def __save_order_begin_data(self, code, buy_single_index, buy_exec_index, compute_index, num, count, max_num_set,
    def __save_order_begin_data(cls, code, buy_single_index, buy_exec_index, compute_index, num, count, max_num_set,
                                volume_rate):
        TradePointManager.set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, num, count,
                                                     max_num_set, volume_rate)
        cls.__TradePointManager.set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, num,
                                                           count,
                                                           max_num_set, volume_rate)
    # 计算下单起始信号
    # compute_data_count 用于计算的l2数据数量
@@ -1221,13 +1155,9 @@
    @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, max_num_set):
        def get_threshold_count():
            count = threshold_count
            return count
        _start_time = t.time()
        total_datas = local_today_datas[code]
        is_first_code = gpcode_manager.FirstCodeManager().is_in_first_record_cache(code)
        # is_first_code = gpcode_manager.FirstCodeManager().is_in_first_record_cache(code)
        buy_nums = origin_num
        buy_count = origin_count
@@ -1237,7 +1167,7 @@
        # 目标手数
        threshold_num = round(threshold_money / (limit_up_price * 100))
        # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        # place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code)
        # 目标订单数量
        threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count()
@@ -1264,7 +1194,7 @@
            trigger_buy = False
            # 必须为连续2秒内的数据
            if L2DataUtil.get_time_as_second(_val["time"]) - buy_single_time_seconds + 1 > max_space_time:
                TradePointManager.delete_buy_point(code)
                cls.__TradePointManager.delete_buy_point(code)
                if i == compute_end_index:
                    # 数据处理完毕
                    return None, buy_nums, buy_count, None, max_buy_num_set
@@ -1282,9 +1212,9 @@
                    # 只统计59万以上的金额
                    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 >= get_threshold_count():
                        logger_l2_trade_buy.info(
                            f"{code}获取到买入执行点:{i} 统计纯买手数:{buy_nums} 目标纯买手数:{threshold_num} 统计纯买单数:{buy_count} 目标纯买单数:{get_threshold_count()}, 大单数量:{len(max_buy_num_set)}")
                    if buy_nums >= threshold_num and buy_count >= threshold_count:
                        async_log_util.info(logger_l2_trade_buy,
                                            f"{code}获取到买入执行点:{i} 统计纯买手数:{buy_nums} 目标纯买手数:{threshold_num} 统计纯买单数:{buy_count} 目标纯买单数:{threshold_count}, 大单数量:{len(max_buy_num_set)}")
            elif L2DataUtil.is_limit_up_price_buy_cancel(_val):
                if _val["num"] >= bigger_num:
                    # 只统计59万以上的金额
@@ -1323,13 +1253,13 @@
            for i in max_buy_num_set:
                max_buy_num_set_count += total_datas[i]["re"]
            # 有撤单信号,且小于阈值
            if buy_nums >= threshold_num and buy_count >= get_threshold_count() and trigger_buy and max_buy_num_set_count >= big_num_count:
            if buy_nums >= threshold_num and buy_count >= threshold_count and trigger_buy and max_buy_num_set_count >= big_num_count:
                return i, buy_nums, buy_count, None, max_buy_num_set
        l2_log.buy_debug(code, "尚未获取到买入执行点,起始计算位置:{} 统计纯买手数:{} 目标纯买手数:{}  统计纯买单数:{} 目标纯买单数:{} 大单数量:{} 目标大单数量:{}",
                         compute_start_index,
                         buy_nums,
                         threshold_num, buy_count, get_threshold_count(), max_buy_num_set_count, big_num_count)
                         threshold_num, buy_count, threshold_count, max_buy_num_set_count, big_num_count)
        return None, buy_nums, buy_count, None, max_buy_num_set