Administrator
2024-10-09 deb26c8b90f9d67c340b3a757740085ac8dd5743
l2/l2_data_manager_new.py
@@ -331,10 +331,20 @@
            if cancel_result[0]:
                L2TradeDataProcessor.cancel_buy(code, f"F撤:{cancel_result[1]}",
                                                cancel_type=trade_constant.CANCEL_TYPE_F)
                return
            else:
                l2_log.f_cancel_debug(code, f"获取真实成交位的F撤未生效:{cancel_result[1]}")
        except Exception as e:
            logger_debug.exception(e)
        # 判断与执行位置的间隔时间
        if order_begin_pos.mode != OrderBeginPosInfo.MODE_RADICAL:
            # 非扫入下单要判断执行位置与真实下单位的间隔时间
            total_datas = local_today_datas.get(code)
            if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[index]["val"]), L2DataUtil.get_time_with_ms(total_datas[order_begin_pos.buy_exec_index]["val"])) > 2000:
                L2TradeDataProcessor.cancel_buy(code, f"真实下单位({index})与执行位({order_begin_pos.buy_exec_index})相差2s以上",
                                                cancel_type=trade_constant.CANCEL_TYPE_F)
                return
    # 处理华鑫L2数据
    @classmethod
@@ -1961,191 +1971,6 @@
                continue
            findexes.add(index)
        return findexes
    # 统计买入净买量,不计算在买入信号之前的买撤单
    @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, at_limit_up=False):
        _start_time = t.time()
        total_datas = local_today_datas[code]
        # is_first_code = gpcode_manager.FirstCodeManager().is_in_first_record_cache(code)
        buy_nums = origin_num
        buy_count = origin_count
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if limit_up_price is None:
            raise Exception("涨停价无法获取")
        limit_up_price = float(limit_up_price)
        threshold_num = None
        # 大目标手数(满足这个就不需要看安全笔数)
        threshold_max_num = None
        # 目标订单数量
        threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count()
        # 最大间隔时间ms
        max_space_time_ms = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range() * 1000
        # ----------------调整板上下单的m值与安全笔数----------------
        if at_limit_up:
            # 板上买,获取最近一次闪电下单的总卖额
            sell_data = cls.__latest_fast_place_order_info_dict.get(code)
            if sell_data:
                # 有过闪电下单
                # 总卖的一半作为m值
                threshold_num = int(sell_data[1] / (limit_up_price * 100)) // 2
                threshold_max_num = 1
            #  信号为之前有待成交的大单(不是正在成交)
            trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code)
            if not is_default and trade_index is not None:
                temp_big_num = int(30000 / limit_up_price)
                for i in range(trade_index + 1, buy_single_index):
                    data = total_datas[i]
                    val = data['val']
                    if not L2DataUtil.is_limit_up_price_buy(val):
                        continue
                        # 判断是否有大单未成交
                    if temp_big_num > val["num"]:
                        continue
                    left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code,
                                                                                                             data[
                                                                                                                 "index"],
                                                                                                             total_datas,
                                                                                                             local_today_canceled_buyno_map.get(
                                                                                                                 code))
                    if left_count > 0:
                        # 安全笔数与囊括时间范围修改
                        threshold_count = 3
                        max_space_time_ms = 9 * 1000
                        break
        if not threshold_num:
            # 目标手数
            threshold_num = round(threshold_money / (limit_up_price * 100))
        if not threshold_max_num:
            threshold_max_num = int(threshold_num * 1.2)
        # place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code)
        # buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # 可以触发买,当有涨停买信号时才会触发买
        trigger_buy = True
        # 如果大单含有率大于50%,则时间囊括范围提高到3s
        if max_num_set and origin_count:
            if len(max_num_set) / origin_count > 0.5:
                max_space_time_ms = 3 * 1000
        # 最大买量
        max_buy_num = 0
        max_buy_num_set = set(max_num_set)
        # 需要的最小大单笔数
        big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count()
        # 较大单的手数
        bigger_num = round(5000 / limit_up_price)
        not_buy_msg = ""
        is_ge_code = tool.is_ge_code(code)
        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.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, 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, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
            # 涨停买
            if L2DataUtil.is_limit_up_price_buy(_val):
                if l2_data_util.is_big_money(_val, is_ge_code):
                    max_buy_num_set.add(i)
                if _val["num"] >= bigger_num:
                    trigger_buy = True
                    # 只统计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 >= threshold_count) or buy_nums >= threshold_max_num:
                        l2_log.info(code, logger_l2_trade_buy,
                                    f"{code}获取到买入执行点:{i} 统计纯买手数:{buy_nums} 目标纯买手数:{threshold_num}/{threshold_max_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万以上的金额
                    # 涨停买撤
                    # 判断买入位置是否在买入信号之前
                    buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i],
                                                                                                        local_today_buyno_map.get(
                                                                                                            code))
                    if buy_index is not None:
                        # 找到买撤数据的买入点
                        if buy_index >= buy_single_index:
                            buy_nums -= int(_val["num"]) * int(data["re"])
                            buy_count -= int(data["re"])
                            # 大单撤销
                            max_buy_num_set.discard(buy_index)
                            l2_log.buy_debug(code, "{}数据在买入信号之后 撤买纯买手数:{} 目标手数:{}", i, buy_nums, threshold_num)
                        else:
                            l2_log.buy_debug(code, "{}数据在买入信号之前,买入位:{}", i, buy_index)
                            if total_datas[buy_single_index]["val"]["time"] == total_datas[buy_index]["val"]["time"]:
                                # 同一秒,当作买入信号之后处理
                                buy_nums -= int(_val["num"]) * int(data["re"])
                                buy_count -= int(data["re"])
                                # 大单撤销
                                max_buy_num_set.discard(buy_index)
                                l2_log.buy_debug(code, "{}数据买入位与预估买入位在同一秒", i)
                    else:
                        # 未找到买撤数据的买入点
                        l2_log.buy_debug(code, "未找到买撤数据的买入点: 位置-{} 数据-{}", i, data)
                        buy_nums -= int(_val["num"]) * int(total_datas[i]["re"])
                        buy_count -= int(total_datas[i]["re"])
            l2_log.buy_debug(code, "位置-{},总手数:{},目标手数:{}", i,
                             buy_nums, threshold_num)
            max_buy_num_set_count = 0
            max_buy_num_set = cls.__filter_not_deal_indexes(code, max_buy_num_set)
            for i1 in max_buy_num_set:
                max_buy_num_set_count += total_datas[i1]["re"]
            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, not_buy_msg
    # 返回(买入执行点, 总手, 总笔数, 从新计算起点, 纯买额阈值)
    # 计算快速买入