Administrator
2023-03-17 8b848e8a9fa242b39f92f3a28faf89be10a6e456
l2/cancel_buy_strategy.py
@@ -25,6 +25,7 @@
class SecondCancelBigNumComputer:
    __redis_manager = redis_manager.RedisManager(0)
    __sCancelParamsManager = l2_trade_factor.SCancelParamsManager
    @classmethod
    def __getRedis(cls):
@@ -61,20 +62,16 @@
    # 计算净大单
    @classmethod
    def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, place_order_count):
    def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, volume_rate_index):
        # 获取大单的最小手数
        left_big_num = 0
        # 点火大单数量
        fire_count = 5
        if place_order_count <= 4:
            fire_count = 6 - place_order_count
        else:
            fire_count = 2
        fire_count = cls.__sCancelParamsManager.get_max_exclude_count(volume_rate_index)
        for i in range(start_index, end_index + 1):
            data = total_data[i]
            val = data["val"]
            # 去除非大单
            if not l2_data_util.is_big_money(val):
            if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                continue
            if L2DataUtil.is_limit_up_price_buy(val):
@@ -108,12 +105,15 @@
    @classmethod
    def need_cancel(cls, code, buy_single_index, buy_exec_index, start_index, end_index, total_data, is_first_code,
                    buy_volume_rate_index,
                    volume_rate_index,
                    need_cancel=True):
        if start_index >= 217:
            print("进入调试")
        # 只守护30s
        buy_exec_time = total_data[buy_exec_index]["val"]["time"]
        if tool.trade_time_sub(total_data[start_index]["val"]["time"],
                               total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME:
                               buy_exec_time) > constant.S_CANCEL_EXPIRE_TIME:
            return False, None
        l2_log.cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index)
        logger_l2_s_cancel.debug(f"code-{code} S级是否需要撤单,数据范围:{start_index}-{end_index}")
@@ -157,7 +157,8 @@
            #         if buy_index is not None and a_start_index <= buy_index <= a_end_index:
            #             # 在买入信号之后
            #             cls.__save_cancel_data(code, i)
        range_seconds = cls.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index)
        cancel_rate_threshold = cls.__sCancelParamsManager.get_cancel_rate(volume_rate_index)
        try:
            for i in range(start_index, end_index + 1):
                data = total_data[i]
@@ -166,18 +167,23 @@
                if process_index_old >= i:
                    # 已经处理过的数据不需要处理
                    continue
                if not l2_data_util.is_big_money(val):
                if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                    continue
                if L2DataUtil.is_limit_up_price_buy(val):
                    buy_num += data["re"] * int(val["num"])
                    # 如果在囊括时间范围内就可以计算买
                    if tool.trade_time_sub(val["time"], buy_exec_time) <= range_seconds:
                        buy_num += data["re"] * int(val["num"])
                elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                    # 查询买入位置
                    buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data,
                                                                                                     local_today_num_operate_map.get(
                                                                                                         code))
                    if buy_index is not None and buy_single_index <= buy_index:
                        cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"])
                        # 买入时间在囊括范围内
                        if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds),
                                               total_data[buy_index]["val"]["time"]) >= 0:
                            cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"])
                    elif buy_index is None:
                        # 有部分撤销从而导致的无法溯源,这时就需要判断预估买入时间是否在a_start_index到a_end_index的时间区间
                        min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"],
@@ -187,28 +193,21 @@
                            buy_time = tool.trade_time_add_second(val["time"], 0 - min_space)
                            if int(total_data[buy_single_index]["val"]["time"].replace(":", "")) <= int(
                                    buy_time.replace(":", "")):
                                cancel_num += data["re"] * int(val["num"])
                                # 买入时间在囊括范围内
                                if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds),
                                                       total_data[buy_index]["val"]["time"]) >= 0:
                                    cancel_num += data["re"] * int(val["num"])
                    # 保存数据
                    if need_cancel:
                        cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE
                        if place_order_count <= 1:
                            cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE
                        elif place_order_count <= 2:
                            cancel_rate_threshold = constant.S_CANCEL_SECOND_RATE
                        else:
                            cancel_rate_threshold = constant.S_CANCEL_THIRD_RATE
                        if is_first_code:
                            cancel_rate_threshold += 0.1
                            cancel_rate_threshold = round(cancel_rate_threshold, 2)
                        if cancel_num / max(buy_num, 1) > cancel_rate_threshold:
                            return True, total_data[i]
        finally:
            l2_log.cancel_debug(code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{}", start_index, end_index, cancel_num,
                                buy_num, round(cancel_num / max(buy_num, 1), 2))
            l2_log.cancel_debug(code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{} 目标比例:{} 计算时间范围:{}", start_index, end_index, cancel_num,
                                buy_num, round(cancel_num / max(buy_num, 1), 2), cancel_rate_threshold,range_seconds)
            # 保存处理进度与数据
            cls.__save_compute_data(code, process_index, buy_num, cancel_num)
@@ -225,6 +224,7 @@
    __redis_manager = redis_manager.RedisManager(0)
    __tradeBuyQueue = TradeBuyQueue()
    __buyL2SafeCountManager = BuyL2SafeCountManager()
    __hCancelParamsManager = l2_trade_factor.HCancelParamsManager()
    @classmethod
    def __getRedis(cls):
@@ -307,12 +307,14 @@
    @classmethod
    def need_cancel(cls, code, buy_exec_index, start_index, end_index, total_data, local_today_num_operate_map,
                    buy_volume_index, volume_index,
                    is_first_code):
        time_space = tool.trade_time_sub(total_data[start_index]["val"]["time"],
                                         total_data[buy_exec_index]["val"]["time"])
        if time_space >= constant.S_CANCEL_EXPIRE_TIME - 1:
            # 开始计算需要监控的单
            cls.__compute_watch_indexs_after_exec(code, buy_exec_index, total_data, local_today_num_operate_map)
            cls.__compute_watch_indexs_after_exec(code, buy_exec_index, total_data, local_today_num_operate_map,
                                                  buy_volume_index)
        # 守护30s以外的数据
        if time_space <= constant.S_CANCEL_EXPIRE_TIME:
@@ -346,16 +348,7 @@
        l2_log.cancel_debug(code, "H级是否需要撤单,数据范围:{}-{} ", start_index, end_index)
        # 获取下单次数
        place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        cancel_rate_threshold = constant.H_CANCEL_FIRST_RATE
        if place_order_count <= 1:
            cancel_rate_threshold = constant.H_CANCEL_FIRST_RATE
        elif place_order_count <= 2:
            cancel_rate_threshold = constant.H_CANCEL_SECOND_RATE
        else:
            cancel_rate_threshold = constant.H_CANCEL_THIRD_RATE
        if is_first_code:
            cancel_rate_threshold += 0.1
            cancel_rate_threshold = round(cancel_rate_threshold,2)
        cancel_rate_threshold = cls.__hCancelParamsManager.get_cancel_rate(volume_index)
        process_index = start_index
        try:
            for i in range(start_index, end_index + 1):
@@ -374,9 +367,9 @@
                        if cancel_num / total_nums > cancel_rate_threshold:
                            return True, data
        finally:
            l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{}", start_index, end_index,
            l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{} 目标撤单比例:{}", start_index, end_index,
                                process_index, cancel_num,
                                total_nums)
                                total_nums,cancel_rate_threshold)
            logger_l2_h_cancel.info(
                f"code-{code} H级撤单计算结果 范围:{start_index}-{end_index} 处理进度:{process_index} 目标比例:{cancel_rate_threshold} 取消计算结果:{cancel_num}/{total_nums}")
            # 保存处理进度与数据
@@ -475,7 +468,7 @@
            if left_count > 0:
                data = total_data[i]
                val = data["val"]
                if val["num"] * float(val["price"]) <= 9900:
                if val["num"] * float(val["price"]) <= constant.H_CANCEL_MIN_MONEY*100:
                    continue
                total_count += left_count
                watch_set.add((i, val["num"], left_count))
@@ -492,7 +485,8 @@
    # 计算执行位置之后的需要监听的数据
    @classmethod
    def __compute_watch_indexs_after_exec(cls, code, buy_exec_index, total_data, local_today_num_operate_map):
    def __compute_watch_indexs_after_exec(cls, code, buy_exec_index, total_data, local_today_num_operate_map,
                                          buy_volume_index):
        watch_list, process_index_old, total_count_old, big_num_count_old, finish = cls.__get_watch_index_set_after_exec(
            code)
        if watch_list and finish:
@@ -509,7 +503,7 @@
        big_num_count = big_num_count_old
        total_count = total_count_old
        # H撤单
        MIN_H_COUNT = l2_trade_factor.L2TradeFactorUtil.get_h_cancel_min_count(code)
        MIN_H_COUNT = cls.__hCancelParamsManager.get_max_watch_count(buy_volume_index)
        for i in range(buy_exec_index, total_data[-1]["index"] + 1):
            if i <= process_index_old:
@@ -523,7 +517,7 @@
            if left_count > 0:
                data = total_data[i]
                val = data["val"]
                if val["num"] * float(val["price"]) <= 9900:
                if val["num"] * float(val["price"]) <= constant.H_CANCEL_MIN_MONEY*100:
                    continue
                total_count += left_count
                watch_set.add((i, val["num"], left_count))
@@ -534,8 +528,8 @@
                # 判断是否达到阈值
                if total_count >= MIN_H_COUNT and big_num_count >= constant.H_CANCEL_MIN_BIG_NUM_COUNT:  # and total_num >= threshold_num
                    finished = True
                    l2_log.cancel_debug(code, "获取到H撤监听数据:{},计算截至位置:{}", json.dumps(list(watch_set)),
                                        total_data[-1]["index"])
                    l2_log.cancel_debug(code, "获取到H撤监听数据:{},计算截至位置:{},目标计算数量:{}", json.dumps(list(watch_set)),
                                        total_data[-1]["index"],MIN_H_COUNT)
                    break
        final_watch_list = list(watch_set)