Administrator
2024-01-19 a00da3062c6c825b585f82275823ac45cdeb6502
l2/l2_data_manager_new.py
@@ -23,12 +23,13 @@
from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \
    transaction_progress, cancel_buy_strategy, l2_data_log
from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \
    LCancelBigNumComputer, LatestCancelIndexManager, FastCancelBigNumComputer, LCancelRateManager, GCancelBigNumComputer
    LCancelBigNumComputer, LatestCancelIndexManager, LCancelRateManager, GCancelBigNumComputer
from l2.l2_data_manager import L2DataException, OrderBeginPosInfo
from l2.l2_data_util import local_today_datas, L2DataUtil, local_today_num_operate_map, local_today_buyno_map, \
    local_latest_datas, local_today_canceled_buyno_map
import l2.l2_data_util
from log_module.log import logger_l2_trade_buy, logger_l2_process, logger_l2_error, logger_debug
from log_module.log import logger_l2_trade_buy, logger_l2_process, logger_l2_error, logger_debug, \
    logger_l2_not_buy_reasons
from trade.trade_data_manager import CodeActualPriceProcessor, PlaceOrderCountManager
@@ -296,12 +297,6 @@
    @classmethod
    def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo):
        trade_record_log_util.add_real_place_order_position_log(code, index, order_begin_pos.buy_single_index)
        if order_begin_pos.mode == OrderBeginPosInfo.MODE_FAST:
            need_cancel = FastCancelBigNumComputer().set_real_order_index(code, index)
            if need_cancel:
                l2_log.debug(code, "触发撤单,撤单位置:{} ,撤单原因:{}", index, "F撤不够2笔触发撤单")
                cls.cancel_buy(code, msg="F撤不够2笔触发撤单")
                return
        l2_log.debug(code, "设置真实下单位:{}", index)
        cancel_buy_strategy.set_real_place_position(code, index, order_begin_pos.buy_single_index)
@@ -524,21 +519,6 @@
                pass
            return None, ""
        # F撤
        def f_cancel(_buy_single_index, _buy_exec_index):
            try:
                b_need_cancel, b_cancel_data = FastCancelBigNumComputer().need_cancel(code, start_index, end_index,
                                                                                      order_begin_pos)
                if b_need_cancel and b_cancel_data:
                    return b_cancel_data, f"F撤"
            except Exception as e:
                if constant.TEST:
                    logging.exception(e)
                async_log_util.error(logger_l2_error,
                                     f"F撤出错 参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} 错误原因:{str(e)}")
                async_log_util.exception(logger_l2_error, e)
            return None, ""
        # L撤
        def l_cancel(_buy_single_index, _buy_exec_index):
            _start_time = round(t.time() * 1000)
@@ -593,9 +573,6 @@
        if order_begin_pos.buy_volume_rate is None:
            buy_volume_rate = 0.2
        cancel_data, cancel_msg = None, ""
        if order_begin_pos.mode == OrderBeginPosInfo.MODE_FAST:
            cancel_data, cancel_msg = f_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
        if not cancel_data:
            cancel_data, cancel_msg = g_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
@@ -968,13 +945,12 @@
        #             if not codes:
        #                 return False, True, f"13:15以后炸板之后下单,({limit_up_reason}) 为独苗"
        # 暂时注释想买单功能
        # if not cls.__WantBuyCodesManager.is_in_cache(code):
        # if cls.__TradeTargetCodeModeManager.get_mode_cache() == TradeTargetCodeModeManager.MODE_ONLY_BUY_WANT_CODES:
        #     return False, True, f"只买想买单中的代码"
        return cls.can_buy_first(code, limit_up_price)
        # else:
        #     return True, False, "在想买名单中"
        if not cls.__WantBuyCodesManager.is_in_cache(code):
            # if cls.__TradeTargetCodeModeManager.get_mode_cache() == TradeTargetCodeModeManager.MODE_ONLY_BUY_WANT_CODES:
            #     return False, True, f"只买想买单中的代码"
            return cls.can_buy_first(code, limit_up_price)
        else:
            return True, False, "在想买单中"
    # 获取可以买的板块
    @classmethod
@@ -1006,110 +982,165 @@
            1), buy_condition_util.get_volume_rate_by_level(2)
        k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
        # 是否有辨识度
        is_special = True if k_format and k_format[8][0] else False
        # 上5个交易日有炸板之后
        has_open_limit_up_in_5 = True if k_format and len(k_format) >= 11 and k_format[10] else False
        # 上5个交易日有跌停
        has_limit_down_in_5 = True if k_format and len(k_format) >= 13 and k_format[12] else False
        # 是否是强势10分钟
        is_in_strong_time = now_timestamp <= int("094000")
        # 是否是强势30分钟
        is_in_strong_time_30 = now_timestamp <= int("100000")
        # 量参考是否在最近30天
        # is_refer_volume_date_in_30_days = False
        # try:
        #     volume_refer_date, volume_refer_date_distance = code_volumn_manager.get_volume_refer_date(code)
        #     if volume_refer_date_distance < 30:
        #         is_refer_volume_date_in_30_days = True
        # except:
        #     pass
        # 获取市场行情
        situation = cls.__MarketSituationManager.get_situation_cache()
        zylt_threshold_as_yi = buy_condition_util.get_zyltgb_threshold(situation)
        zyltgb_as_yi = round(global_util.zyltgb_map.get(code) / 100000000, 2)
        if zyltgb_as_yi >= zylt_threshold_as_yi[1]:
            return False, True, f"{zylt_threshold_as_yi[1]}亿以上的都不买({zyltgb_as_yi})"
        if zyltgb_as_yi < zylt_threshold_as_yi[0]:
            return False, True, f"{zylt_threshold_as_yi[0]}亿以下的都不买({zyltgb_as_yi})"
        # 最优市值
        is_best_zylt = True if zylt_threshold_as_yi[4] <= zyltgb_as_yi <= zylt_threshold_as_yi[5] else False
        if is_special:
            # 具有辨识度,算作最优市值
            zyltgb_as_yi = zylt_threshold_as_yi[2] + 1
        # 是否是最优自由流通市值
        is_better_zylt = True if zylt_threshold_as_yi[2] <= zyltgb_as_yi <= zylt_threshold_as_yi[3] else False
        if is_in_strong_time_30 and is_best_zylt and can_buy_result[0]:
            # 强势30分钟,最优市值, 有可以下单的板块,不看量
            return True, False, can_buy_result[2]
        if k_format and (k_format[1][0] or k_format[3][0]) and len(k_format) >= 12 and k_format[11]:
            # 破前高/接近前高且30天内有涨停
            if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                return False, True, f"股价创新高或者逼近前高且30天内有涨停,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
        # 上5个交易日有炸板之后
        if k_format and len(k_format) >= 11 and k_format[10]:
            if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                return False, True, f"上5个交易日炸板,量未达到{volume_rate_thresholds[1]}({cls.volume_rate_info[code][0]})"
        # 上5个交易日有跌停
        if k_format and len(k_format) >= 13 and k_format[12]:
            if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.29:
                return False, True, f"上5个交易日跌停,量未达到{0.29}({cls.volume_rate_info[code][0]})"
        # 获取量的参考日期
        if code in global_util.max60_volumn:
            day = global_util.max60_volumn[code][1]
            if day in HistoryKDatasUtils.get_latest_trading_date_cache(5):
                if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                    return False, True, f"参考量在最近5天,量未达到{volume_rate_thresholds[1]}({cls.volume_rate_info[code][0]})"
        # 获取市场行情
        situation = cls.__MarketSituationManager.get_situation_cache()
        zylt_threshold = buy_condition_util.get_zyltgb_threshold(situation)
        zyltgb = global_util.zyltgb_map.get(code)
        if k_format and k_format[8][0]:
            # 具有辨识度
            zyltgb = zylt_threshold[1] + 1
        if zyltgb >= zylt_threshold[0]:
            return False, True, f"{zylt_threshold[0] // 100000000}亿以上的都不买({zyltgb})"
        if HighIncreaseCodeManager().is_in(code):
            if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.8:
                return False, True, f"5天内3次涨停,量未达到80%({cls.volume_rate_info[code][0]})"
        msg_list = []
        if now_timestamp <= int("094000"):
        if is_in_strong_time:
            msg_list.append("强势10分钟")
            # 上5个交易日有炸板之后
            if has_open_limit_up_in_5:
                if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.15:
                    return False, True, f"强势10分钟,上5个交易日炸板,量未达到{0.15}({cls.volume_rate_info[code][0]})"
            # 上5个交易日有跌停
            if has_limit_down_in_5:
                if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.15:
                    return False, True, f"强势10分钟,上5个交易日跌停,量未达到{0.15}({cls.volume_rate_info[code][0]})"
            # 获取量的参考日期
            if code in global_util.max60_volumn:
                day = global_util.max60_volumn[code][1]
                if day in HistoryKDatasUtils.get_latest_trading_date_cache(5):
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.15 and not is_special:
                        return False, True, f"强势10分钟,参考量在最近5天,无辨识度,量未达到0.15({cls.volume_rate_info[code][0]})"
            # 独苗
            if not can_buy_result[0] and can_buy_result[1]:
                msg_list.append("独苗")
                if zyltgb < zylt_threshold[1] or zyltgb > zylt_threshold[2]:
                if not is_best_zylt:
                    # 如果没有辨识度才不买
                    if k_format and k_format[8][0]:
                        # 有辨识度
                        pass
                    else:
                        return False, True, f"强势10分钟,独苗({can_buy_result[4]})不下单({can_buy_result[4]})自由流通市值({zyltgb})不满足条件"
                    if not is_special:
                        return False, True, f"强势10分钟,无辨识度, 独苗({can_buy_result[4]})不下单({can_buy_result[4]})自由流通市值({zyltgb_as_yi})不是特优市值"
                if k_format and (k_format[1][0] or k_format[3][0]):
                    msg_list.append("股价创新高或者逼近前高")
                    # 股价创新高或者逼近前高
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                        return False, True, f"强势10分钟,独苗({can_buy_result[4]}),股价创新高或者逼近前高,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
                else:
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[0]:
                        return False, True, f"强势10分钟,独苗({can_buy_result[4]}),当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[
                        0] and not is_special:
                        return False, True, f"强势10分钟,无辨识度,独苗({can_buy_result[4]}),当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
            else:
                msg_list.append("非独苗")
                if zyltgb < zylt_threshold[1] or zyltgb > zylt_threshold[2]:
                if not is_better_zylt:
                    msg_list.append("不满足自由流通")
                    if k_format and (k_format[1][0] or k_format[3][0]):
                        # 股价创新高或者逼近前高
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                            return False, True, f"强势10分钟,后排,不满足自由市值,股价创新高或者逼近前高,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
                    else:
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[0]:
                            return False, True, f"强势10分钟,后排,不满足自由市值,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[
                            0] and not is_special:
                            return False, True, f"强势10分钟,后排,无辨识度,不满足自由市值,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
                else:
                    msg_list.append("满足自由流通")
                    # 后排,满足自由流通市值需要下单
                    return True, False, can_buy_result[2]
            return True, False, can_buy_result[2]
        else:
            # 上5个交易日有炸板之后
            if has_open_limit_up_in_5:
                if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.29:
                    return False, True, f"强势10分钟,上5个交易日炸板,量未达到{0.29}({cls.volume_rate_info[code][0]})"
            # 上5个交易日有跌停
            if has_limit_down_in_5:
                if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.29:
                    return False, True, f"强势10分钟,上5个交易日跌停,量未达到{0.29}({cls.volume_rate_info[code][0]})"
            # 获取量的参考日期
            if code in global_util.max60_volumn:
                day = global_util.max60_volumn[code][1]
                if day in HistoryKDatasUtils.get_latest_trading_date_cache(5):
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.29 and not is_special:
                        return False, True, f"参考量在最近5天,无辨识度,量未达到0.29({cls.volume_rate_info[code][0]})"
            # 非强势10分钟只买主线
            if not can_buy_result[0] and can_buy_result[1]:
                return False, True, f"非强势10分钟,独苗({can_buy_result[4]})不下单"
                if not is_special and not is_best_zylt:
                    return False, True, f"非强势10分钟,无辨识度,非特优市值,独苗({can_buy_result[4]})不下单"
            if can_buy_result[3]:
                # 强势主线
                if zyltgb < zylt_threshold[1] or zyltgb > zylt_threshold[2]:
                if not is_better_zylt:
                    if k_format and (k_format[1][0] or k_format[3][0]):
                        # 股价创新高或者逼近前高
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                            return False, True, f"非强势10分钟,强势主线后排,不满足自由市值,股价创新高或者逼近前高,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
                    else:
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[0]:
                            return False, True, f"非强势10分钟,强势主线后排,不满足自由市值,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[
                            0] and not is_special:
                            return False, True, f"非强势10分钟,强势主线后排,不满足自由市值,无辨识度,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
                else:
                    if k_format and (k_format[1][0] or k_format[3][0]):
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[0]:
                            return False, True, f"非强势10分钟,强势主线后排,满足自由市值,股价创新高或者逼近前高, 当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
            else:
                # 非强势主线
                if zyltgb < zylt_threshold[1] or zyltgb > zylt_threshold[2]:
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                        return False, True, f"非强势10分钟,非强势主线后排【主线后排】,不满足自由市值, 当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
                if not is_better_zylt:
                    if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[
                        1] and not is_special:
                        return False, True, f"非强势10分钟,非强势主线后排【主线后排】,不满足自由市值,无辨识度, 当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
                else:
                    if k_format and (k_format[1][0] or k_format[3][0]):
                        # 股价创新高或者逼近前高
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[1]:
                            return False, True, f"非强势10分钟,非强势主线后排【主线后排】,满足自由市值,股价创新高或者逼近前高, 当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[1]}"
                    else:
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[0]:
                            return False, True, f"非强势10分钟,非强势主线后排【主线后排】, 满足自由市值,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
                        if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < volume_rate_thresholds[
                            0] and not is_special:
                            return False, True, f"非强势10分钟,非强势主线后排【主线后排】, 满足自由市值,无辨识度,当日量比({cls.volume_rate_info[code][0]})小于{volume_rate_thresholds[0]}"
            return True, False, can_buy_result[2]
    @classmethod
@@ -1245,7 +1276,7 @@
                    trade_index, is_default = TradeBuyQueue().get_traded_index(code)
                    if trade_index and not is_default:
                        m_base_val = l2_trade_factor.L2PlaceOrderParamsManager.get_base_m_val(code)
                        thresh_hold_num = m_base_val * 3 // (float(gpcode_manager.get_limit_up_price(code)) * 100)
                        thresh_hold_num = m_base_val * 4 // (float(gpcode_manager.get_limit_up_price(code)) * 100)
                        # 真实下单位到成交位置的纯买额 * 3
                        total_num = 0
                        for i in range(trade_index + 1, buy_single_index):
@@ -1274,23 +1305,28 @@
                order_begin_pos.count = 0
                order_begin_pos.buy_single_index = buy_single_index
                if order_begin_pos.sell_info:
                    k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
                    if k_format and (k_format[1][0] or k_format[3][0]):
                        # 股价新高或者逼近前高
                        order_begin_pos.threshold_money = int(sell_info[1])
                    else:
                        if float(total_datas[buy_single_index]["val"]["price"]) >= 3 and cls.volume_rate_info[code][
                            0] > 0.3 and sell_info[1] > 2000 * 10000 and int(
                            tool.get_now_time_str().replace(":", "")) < int("100000"):
                            # 暂时打8折
                            # order_begin_pos.threshold_money = int(sell_info[1] * 0.8)
                            # 深证总卖大于1000万的票,m值打5折
                            if code.find('00') == 0:
                    # k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
                    # if k_format and (k_format[1][0] or k_format[3][0]):
                    #     # 股价新高或者逼近前高
                    #     order_begin_pos.threshold_money = int(sell_info[1])
                    # else:
                    if float(total_datas[buy_single_index]["val"]["price"]) >= 3 and cls.volume_rate_info[code][
                        0] > 0.3 and sell_info[1] > 2000 * 10000 and int(
                        tool.get_now_time_str().replace(":", "")) < int("100000"):
                        # 暂时打8折
                        # order_begin_pos.threshold_money = int(sell_info[1] * 0.8)
                        # 深证总卖大于1000万的票,m值打5折
                        if code.find('00') == 0:
                            # 深圳首次下单打折
                            place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code)
                            if place_order_count is not None and place_order_count == 0:
                                order_begin_pos.threshold_money = int(sell_info[1] * 0.6)
                            else:
                                order_begin_pos.threshold_money = int(sell_info[1] * 0.8)
                                order_begin_pos.threshold_money = int(sell_info[1])
                        else:
                            order_begin_pos.threshold_money = int(sell_info[1])
                            order_begin_pos.threshold_money = int(sell_info[1] * 0.8)
                    else:
                        order_begin_pos.threshold_money = int(sell_info[1])
                l2_log.debug(code, "获取到买入信号起始点:{} ,计算范围:{}-{} ,量比:{},是否板上买:{},数据:{} 模式:{}({})", buy_single_index,
                             compute_start_index,
                             compute_end_index, cls.volume_rate_info[code], order_begin_pos.at_limit_up,
@@ -1315,11 +1351,11 @@
        # _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "m值阈值计算")
        # 买入纯买额统计
        new_buy_exec_index, buy_nums, buy_count, rebegin_buy_pos, max_num_set_new = None, None, None, None, []
        new_buy_exec_index, buy_nums, buy_count, rebegin_buy_pos, max_num_set_new, not_buy_msg = None, None, None, None, [], ""
        if order_begin_pos.mode == OrderBeginPosInfo.MODE_FAST:
            threshold_money = order_begin_pos.threshold_money
            new_buy_exec_index, buy_nums, buy_count, rebegin_buy_pos, threshold_money_new = cls.__sum_buy_num_for_order_fast(
            new_buy_exec_index, buy_nums, buy_count, rebegin_buy_pos, threshold_money_new, not_buy_msg = cls.__sum_buy_num_for_order_fast(
                code,
                start_process_index,
                compute_end_index,
@@ -1330,7 +1366,7 @@
            threshold_money = threshold_money_new
            order_begin_pos.threshold_money = threshold_money
        else:
            new_buy_exec_index, buy_nums, buy_count, rebegin_buy_pos, max_num_set_new = cls.__sum_buy_num_for_order_3(
            new_buy_exec_index, buy_nums, buy_count, rebegin_buy_pos, max_num_set_new, not_buy_msg = cls.__sum_buy_num_for_order_3(
                code,
                start_process_index,
                compute_end_index,
@@ -1393,6 +1429,8 @@
                                                                max_num_set=max_num_set_new, mode=order_begin_pos.mode,
                                                                sell_info=order_begin_pos.sell_info,
                                                                threshold_money=threshold_money))
            # 记录没下单原因
            async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{not_buy_msg}")
            _start_time = t.time()
        l2_data_log.l2_time_log(code, "__start_compute_buy 结束")
@@ -1577,13 +1615,13 @@
        # 目标订单数量
        threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count()
        buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # 可以触发买,当有涨停买信号时才会触发买
        trigger_buy = True
        # 间隔最大时间依次为:3,9,27,81
        max_space_time = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range()
        # 最大间隔时间ms
        max_space_time_ms = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range() * 1000
        # 最大买量
        max_buy_num = 0
        max_buy_num_set = set(max_num_set)
@@ -1594,21 +1632,22 @@
        # 较大单的手数
        bigger_num = round(5000 / limit_up_price)
        not_buy_msg = ""
        for i in range(compute_start_index, compute_end_index + 1):
            data = total_datas[i]
            _val = total_datas[i]["val"]
            trigger_buy = False
            # 必须为连续2秒内的数据
            if L2DataUtil.get_time_as_second(_val["time"]) - buy_single_time_seconds + 1 > max_space_time:
            if L2DataUtil.time_sub_as_ms(_val, total_datas[buy_single_index]["val"]) > max_space_time_ms:
                cls.__TradePointManager.delete_buy_point(code)
                if i == compute_end_index:
                    # 数据处理完毕
                    return None, buy_nums, buy_count, None, max_buy_num_set
                    return None, buy_nums, buy_count, None, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
                else:
                    # 计算买入信号,不能同一时间开始计算
                    for ii in range(buy_single_index + 1, compute_end_index + 1):
                        if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]:
                            return None, buy_nums, buy_count, ii, max_buy_num_set
                            return None, buy_nums, buy_count, ii, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
            # 涨停买
            if L2DataUtil.is_limit_up_price_buy(_val):
                if l2_data_util.is_big_money(_val):
@@ -1657,22 +1696,37 @@
            max_buy_num_set_count = 0
            for i1 in max_buy_num_set:
                max_buy_num_set_count += total_datas[i1]["re"]
            # 有撤单信号,且小于阈值
            if buy_nums >= threshold_num and buy_count >= threshold_count and trigger_buy and max_buy_num_set_count >= big_num_count:
                try:
                    info = cls.__trade_log_placr_order_info_dict[code]
                    info.set_trade_factor(threshold_money, threshold_count, list(max_buy_num_set))
                except Exception as e:
                    async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}")
                return i, buy_nums, buy_count, None, max_buy_num_set
            if buy_nums < threshold_num:
                not_buy_msg = f"【{i}】纯买额不足,{buy_nums}/{threshold_num}"
                continue
            if buy_count < threshold_count:
                not_buy_msg = f"【{i}】安全笔数不够,{buy_count}/{threshold_count}"
                continue
            if not trigger_buy:
                not_buy_msg = f"【{i}】没有买单触发"
                continue
            if max_buy_num_set_count < big_num_count:
                not_buy_msg = f"【{i}】大单数量不足,{max_buy_num_set_count}/{big_num_count}"
                continue
            try:
                info = cls.__trade_log_placr_order_info_dict[code]
                info.set_trade_factor(threshold_money, threshold_count, list(max_buy_num_set))
            except Exception as e:
                async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}")
            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, threshold_count, max_buy_num_set_count, big_num_count)
        return None, buy_nums, buy_count, None, max_buy_num_set
        return None, buy_nums, buy_count, None, max_buy_num_set, not_buy_msg
    # 返回(买入执行点, 总手, 总笔数, 从新计算起点, 纯买额阈值)
    # 计算快速买入
@@ -1694,27 +1748,29 @@
        # 目标手数
        threshold_num = round(threshold_money / (limit_up_price * 100))
        buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # 可以触发买,当有涨停买信号时才会触发买
        trigger_buy = True
        # 间隔最大时间为3s
        max_space_time = 3
        max_space_time_ms = 3 * 1000
        # 不下单的信息
        not_buy_msg = ""
        for i in range(compute_start_index, compute_end_index + 1):
            data = total_datas[i]
            _val = total_datas[i]["val"]
            trigger_buy = False
            # 必须为连续2秒内的数据
            if L2DataUtil.get_time_as_second(_val["time"]) - buy_single_time_seconds + 1 > max_space_time:
            if L2DataUtil.time_sub_as_ms(_val, total_datas[buy_single_index]["val"]) > max_space_time_ms:
                cls.__TradePointManager.delete_buy_point(code)
                if i == compute_end_index:
                    # 数据处理完毕
                    return None, buy_nums, buy_count, None, threshold_money
                    return None, buy_nums, buy_count, None, threshold_money, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
                else:
                    # 计算买入信号,不能同一时间开始计算
                    for ii in range(buy_single_index + 1, compute_end_index + 1):
                        if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]:
                            return None, buy_nums, buy_count, ii, threshold_money
                            return None, buy_nums, buy_count, ii, threshold_money, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
            if L2DataUtil.is_sell(_val):
                threshold_money += _val["num"] * int(float(_val["price"]) * 100)
                threshold_num = round(threshold_money / (limit_up_price * 100))
@@ -1757,21 +1813,29 @@
            l2_log.buy_debug(code, "位置-{},总手数:{},目标手数:{}", i,
                             buy_nums, threshold_num)
            # 纯买额足够,且笔数大于5笔
            if buy_nums >= threshold_num and trigger_buy and buy_count>=5:
                try:
                    info = cls.__trade_log_placr_order_info_dict[code]
                    info.set_trade_factor(threshold_money, 0, [])
                except Exception as e:
                    async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}")
            if buy_nums < threshold_num:
                not_buy_msg = f"【{i}】纯买额不够,{buy_nums}/{threshold_num}"
                continue
            if not trigger_buy:
                not_buy_msg = f"【{i}】没有买单触发"
                continue
            if buy_count < 5:
                not_buy_msg = f"【{i}】安全笔数不足,{buy_count}/{5}"
                continue
            try:
                info = cls.__trade_log_placr_order_info_dict[code]
                info.set_trade_factor(threshold_money, 0, [])
            except Exception as e:
                async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}")
                return i, buy_nums, buy_count, None, threshold_money
            return i, buy_nums, buy_count, None, threshold_money, "可以下单"
        l2_log.buy_debug(code, "尚未获取到买入执行点(快速买入),起始计算位置:{} 统计纯买手数:{} 目标纯买手数:{}  统计纯买单数:{}",
                         compute_start_index,
                         buy_nums,
                         threshold_num, buy_count)
        return None, buy_nums, buy_count, None, threshold_money
        return None, buy_nums, buy_count, None, threshold_money, not_buy_msg
def test_trade_record():