Administrator
2023-09-18 c7d7e415bf6698e2b6a013cfe317d0bd8ccb43b9
L撤增加成交位临近L撤
1个文件已修改
127 ■■■■■ 已修改文件
l2/cancel_buy_strategy.py 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/cancel_buy_strategy.py
@@ -643,7 +643,8 @@
            left_num += val['num'] * left_count
        # 剩下的不足动态M值的1/2
        rate = round(float(limit_up_price) * left_num * 100 / m_base_value, 3)
        l2_log.d_cancel_debug(code, f"成交进度({index})到下单位置({real_order_index})的剩余笔数:{left_num},撤单比例:{rate},m值:{m_base_value}")
        l2_log.d_cancel_debug(code,
                              f"成交进度({index})到下单位置({real_order_index})的剩余笔数:{left_num},撤单比例:{rate},m值:{m_base_value}")
        if rate < constant.D_CANCEL_RATE:
            l2_log.cancel_debug(code, "D撤撤单,比例为:{},目标比例{}", rate, constant.D_CANCEL_RATE)
            return True, f"D撤比例为:{rate}"
@@ -670,7 +671,7 @@
    __real_place_order_index_dict = {}
    __cancel_watch_index_cache = {}
    # 成交位附近临近大单索引
    __near_by_trade_progress_big_num_index_cache = {}
    __near_by_trade_progress_index_cache = {}
    __SecondCancelBigNumComputer = SecondCancelBigNumComputer()
@@ -691,12 +692,15 @@
                code = k.split("-")[-1]
                val = RedisUtils.smembers(__redis, k)
                CodeDataCacheUtil.set_cache(cls.__cancel_watch_index_cache, code, val)
            keys = RedisUtils.keys(__redis, "l_cancel_near_by_big_num_index-*")
            keys = RedisUtils.keys(__redis, "l_cancel_near_by_index-*")
            for k in keys:
                code = k.split("-")[-1]
                val = RedisUtils.get(__redis, k)
                val = int(val)
                CodeDataCacheUtil.set_cache(cls.__near_by_trade_progress_big_num_index_cache, code, val)
                try:
                    val = set(json.loads(val))
                    CodeDataCacheUtil.set_cache(cls.__near_by_trade_progress_index_cache, code, val)
                except:
                    pass
        finally:
            RedisUtils.realse(__redis)
@@ -737,18 +741,19 @@
            return cache_result[1]
        return set()
    def __set_near_by_big_num_index(self, code, index):
        self.__near_by_trade_progress_big_num_index_cache[code] = index
        RedisUtils.setex_async(self.__db, f"l_cancel_near_by_big_num_index-{code}", tool.get_expire(), index)
    def __set_near_by_trade_progress_indexes(self, code, indexes):
        self.__near_by_trade_progress_index_cache[code] = indexes
        RedisUtils.setex_async(self.__db, f"l_cancel_near_by_index-{code}", tool.get_expire(),
                               json.dumps(list(indexes)))
    def __get_near_by_big_num_index(self, code):
        val = RedisUtils.get(self.__get_redis(), f"l_cancel_near_by_big_num_index-{code}")
    def __get_near_by_trade_progress_indexes(self, code):
        val = RedisUtils.get(self.__get_redis(), f"l_cancel_near_by_index-{code}")
        if val is None:
            return None
        return int(val)
        return set(json.loads(val))
    def __get_near_by_big_num_index_cache(self, code):
        cache_result = CodeDataCacheUtil.get_cache(self.__near_by_trade_progress_big_num_index_cache, code)
    def __get_near_by_trade_progress_indexes_cache(self, code):
        cache_result = CodeDataCacheUtil.get_cache(self.__near_by_trade_progress_index_cache, code)
        if cache_result[0]:
            return cache_result[1]
        return None
@@ -813,57 +818,52 @@
        self.__real_place_order_index_dict[code] = index
        if self.__last_trade_progress_dict.get(code):
            self.compute_watch_index(code, self.__last_trade_progress_dict.get(code), index)
            self.__compute_trade_progress_near_by_indexes(code, self.__last_trade_progress_dict.get(code) + 1, index)
        else:
            if buy_single_index:
                self.compute_watch_index(code, buy_single_index, index)
                self.__compute_trade_progress_near_by_indexes(code, buy_single_index, index)
    # 计算范围内的成交位临近未撤大单
    def __compute_near_by_big_num_index(self, code, start_index, end_index, total_datas):
        MIN_MONEYS = [300, 200, 100, 50]
        for min_money in MIN_MONEYS:
            final_index = None
    def __compute_trade_progress_near_by_indexes(self, code, start_index, end_index):
        if start_index is None or end_index is None:
            return
        total_datas = local_today_datas.get(code)
        MIN_MONEY = 50 * 100
        MAX_COUNT = 10
        watch_indexes = set()
        total_num = 0
        thresh_hold_money = l2_trade_factor.L2PlaceOrderParamsManager.get_base_m_val(code)
        threshold_num = thresh_hold_money // (float(gpcode_manager.get_limit_up_price(code)) * 100)
            for i in range(start_index, end_index):
                data = total_datas[i]
                val = data['val']
                if not L2DataUtil.is_limit_up_price_buy(val):
                    continue
                # 小金额过滤
                if float(val['price']) * val['num'] < min_money * 100:
            if float(val['price']) * val['num'] < MIN_MONEY:
                    continue
                left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code, i,
                                                                                                      total_datas,
                                                                                                      local_today_num_operate_map.get(
                                                                                                          code))
                if left_count > 0:
                    final_index = i
                total_num += val['num'] * left_count
                watch_indexes.add(i)
                if len(watch_indexes) > MAX_COUNT or total_num >= threshold_num:
                    break
            if final_index:
                self.__near_by_trade_progress_big_num_index_cache[code] = final_index
                break
        # 保存数据
        l2_log.l_cancel_debug(code,f"设置成交位临近撤单监控范围:{watch_indexes} 计算范围:{start_index}-{end_index}")
        self.__set_near_by_trade_progress_indexes(code, watch_indexes)
    # 设置成交位置,成交位置变化之后相应的监听数据也会发生变化
    def set_trade_progress(self, code, index, total_datas):
        # 临近撤先撤单
        # 如果成交位置并未该改变且没有没有找到成交位置临近大单
        # need_compute_big = False
        # if self.__last_trade_progress_dict.get(
        #         code) == index and code not in self.__near_by_trade_progress_big_num_index_cache:
        #     need_compute_big = True
        # elif self.__last_trade_progress_dict.get(code) != index:
        #     need_compute_big = True
        #
        # # 设置成交位置临近大单监听
        # real_place_order = self.__real_place_order_index_dict.get(code)
        # # 真实下单位置
        # end_index = real_place_order
        # if not end_index:
        #     end_index = total_datas[-1]["index"]
        #
        # if need_compute_big:
        #     self.__compute_near_by_big_num_index(code, index+1, end_index, total_datas)
        if self.__last_trade_progress_dict.get(code) == index:
            return
        # 重新计算成交位置临近大单撤单
        self.__compute_trade_progress_near_by_indexes(code, index + 1, self.__real_place_order_index_dict.get(code))
        try:
            # 已经有计算的无法触发计算
            old_watch_indexes = self.__get_watch_indexes_cache(code)
@@ -922,6 +922,43 @@
        return False, None
    def __compute_near_by_trade_progress_need_cancel(self, code, buy_exec_index, start_index, end_index, total_data,
                                                     _local_today_num_operate_map, is_first_code):
        watch_indexes = self.__get_near_by_trade_progress_indexes_cache(code)
        if not watch_indexes:
            return False, None
        # 计算监听的总条数
        total_count = 0
        for wi in watch_indexes:
            total_count += total_data[wi]["re"]
        # 判断撤单中是否有监听中的索引
        need_compute = False
        for i in range(start_index, end_index + 1):
            data = total_data[i]
            val = data["val"]
            if 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)
                if buy_index is not None and buy_index in watch_indexes:
                    need_compute = True
                    break
        if need_compute:
            # 计算撤单比例
            canceled_count = 0
            for wi in watch_indexes:
                left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code,
                                                                                                      wi,
                                                                                                      total_data,
                                                                                                      _local_today_num_operate_map)
                canceled_count += total_data[wi]["re"] - left_count
            rate = round(canceled_count / total_count, 3)
            l2_log.l_cancel_debug(code, f"计算范围:{start_index}-{end_index},成交位临近已撤单比例:{rate}")
            if rate >= constant.L_CANCEL_RATE:
                return True, total_data[-1]
        return False, None
    def need_cancel(self, code, buy_exec_index, start_index, end_index, total_data, _local_today_num_operate_map,
                    is_first_code):
        if buy_exec_index is None:
@@ -931,8 +968,16 @@
        # 守护S撤以外的数据
        if time_space <= constant.L_CANCEL_START_TIME or int(tool.get_now_time_str().replace(":", "")) > int("145000"):
            return False, None
        # 下单位临近撤
        can_cancel, cancel_data = self.__compute_need_cancel(code, buy_exec_index, start_index, end_index, total_data,
                                                             _local_today_num_operate_map, is_first_code)
        if not can_cancel:
            # 成交位临近撤
            can_cancel, cancel_data = self.__compute_near_by_trade_progress_need_cancel(code, buy_exec_index,
                                                                                        start_index, end_index,
                                                                                        total_data,
                                                                                        _local_today_num_operate_map,
                                                                                        is_first_code)
        return can_cancel, cancel_data
    def place_order_success(self, code):