Administrator
2024-07-16 cf551c3d66c1410bfdfd9f808e98cba77dec5cd1
上证S重砸优化/逼近成交时L后囊括范围修改
2个文件已修改
112 ■■■■■ 已修改文件
cancel_strategy/s_l_h_cancel_strategy.py 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_processor.py 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cancel_strategy/s_l_h_cancel_strategy.py
@@ -57,12 +57,6 @@
            elif half_must_buy:
                return round((constant.S_FAST_RATE + constant.S_FAST_BIG_RATE_WITH_MUST_BUY) / 2, 2), "半红"
            else:
                # 上证 如果没有大单成交,不需要看比例
                if tool.is_sh_code(code):
                    # 获取大单成交
                    deal_big_order_count = BigOrderDealManager().get_total_buy_count(code)
                    if deal_big_order_count < 1:
                        return 0, "常规(无大单成交)"
                return constant.S_FAST_RATE, "常规"
        elif cancel_type == cls.TYPE_S_SLOW:
            if must_buy:
@@ -350,6 +344,7 @@
        total_datas = local_today_datas.get(code)
        real_order_index_info = self.__get_real_place_order_index_info_cache(code)
        real_order_time_ms = None
        real_order_index = None
        if real_order_index_info and not real_order_index_info[1]:
            real_order_index = real_order_index_info[0]
            real_order_time_ms = total_datas[real_order_index]["val"]["time"] + ".{0:0>3}".format(
@@ -374,10 +369,20 @@
        if total_deal_money >= threshold_big_deal:
            # S重砸必撤的金额满足以后,以前是无脑撤。现在优化一下,看成交进度位---真实下单位的区间额≤重砸金额*3.3倍,就撤。
            try:
                # 上证如果重砸额大于阈值的1.5倍直接撤单
                if tool.is_sh_code(code) and total_deal_money >= threshold_big_deal * 1.5:
                    if not gpcode_manager.MustBuyCodesManager().is_in_cache(code):
                        return True, f"1s内成交({threshold_big_deal}) 大于大卖单({total_deal_money})的1.5倍"
                # 上证,下单3分钟内
                try:
                    if tool.is_sh_code(code) and real_order_index is not None and tool.trade_time_sub(
                            total_datas[-1]["val"]["time"], total_datas[real_order_index]["val"]["time"]) < 3 * 60:
                        # 上证如果重砸额大于阈值的1.5倍直接撤单
                        if not gpcode_manager.MustBuyCodesManager().is_in_cache(code):
                            if total_deal_money >= threshold_big_deal * 1.5:
                                return True, f"1s内成交({total_deal_money}) 大于大卖单({threshold_big_deal})的1.5倍"
                            # 如果没有大单成交也直接撤单
                            deal_big_order_count = BigOrderDealManager().get_total_buy_count(code)
                            if deal_big_order_count < 1:
                                return True, f"1s内成交({total_deal_money}) 大于大卖单({threshold_big_deal})且无大单成交"
                except Exception as e:
                    l2_log.s_cancel_debug(code, "S重砸出错了:{}", str(e))
                need_compute = False
                trade_index, is_default = TradeBuyQueue().get_traded_index(code)
@@ -652,6 +657,8 @@
    __last_l_up_compute_info = {}
    __l_down_after_by_big_order_dict = {}
    __instance = None
    def __new__(cls, *args, **kwargs):
@@ -764,6 +771,8 @@
    def clear(self, code=None):
        if code:
            self.del_watch_index(code)
            if code in self.__l_down_after_by_big_order_dict:
                self.__l_down_after_by_big_order_dict.pop(code)
            if code in self.__real_place_order_index_dict:
                self.__real_place_order_index_dict.pop(code)
                RedisUtils.delete_async(self.__db, f"l_cancel_real_place_order_index-{code}")
@@ -787,6 +796,7 @@
            keys = RedisUtils.keys(self.__get_redis(), f"l_cancel_down_after_place_order_index-*")
            for k in keys:
                RedisUtils.delete(self.__get_redis(), k)
            self.__l_down_after_by_big_order_dict.clear()
        # 重新计算L上
@@ -1048,6 +1058,55 @@
            pass
        return watch_indexes
    def __compute_l_down_watch_index_after_by(self, code):
        """
        计算L后后半段大单备用
        @param code:
        @return:
        """
        if self.__l_down_after_by_big_order_dict.get(code):
            # 不用重复计算
            return
        real_place_order_info = self.__real_place_order_index_dict.get(code)
        if not real_place_order_info or real_place_order_info[1]:
            return
        real_place_order_index = real_place_order_info[0]
        total_datas = local_today_datas.get(code)
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        limit_up_price = round(float(limit_up_price), 2)
        bigger_num = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) // (limit_up_price * 100)
        min_num = 500000 // (limit_up_price * 100)
        count = -1
        watch_indexes = set()
        for i in range(real_place_order_index + 1, total_datas[-1]["index"]):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            if val["num"] < min_num:
                continue
            if val["num"] < bigger_num:
                continue
            left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i,
                                                                                                     total_datas,
                                                                                                     local_today_canceled_buyno_map.get(
                                                                                                         code))
            if left_count > 0:
                if val["num"] >= bigger_num:
                    if count < 0:
                        # 开始计数
                        count = 0
                    # 加入大单监听
                    watch_indexes.add(i)
                if count >= 0:
                    count += 1
                    if count > 10:
                        break
        self.__l_down_after_by_big_order_dict[code] = watch_indexes
        l2_log.l_cancel_debug(code, f"L后后半段大单备用囊括范围:{watch_indexes}")
    # 设置真实下单位置
    def set_real_place_order_index(self, code, index, buy_single_index=None, is_default=False):
        l2_log.l_cancel_debug(code, f"设置真实下单位-{index},buy_single_index-{buy_single_index}")
@@ -1184,7 +1243,13 @@
        if not self.__is_l_down_can_cancel(code, buy_single_index):
            # L后已经不能守护
            l2_log.l_cancel_debug(code, f"L后已经无法生效:buy_single_index-{buy_single_index}")
            HourCancelBigNumComputer().start_compute_watch_indexes(code, buy_single_index)
            try:
                # 计算L后后半段大单监控范围
                self.__compute_l_down_watch_index_after_by(code)
            except Exception as e:
                l2_log.l_cancel_debug(code, "__compute_l_down_watch_index_after_by出错")
        real_place_order_index_info = self.__real_place_order_index_dict.get(code)
        real_place_order_index = None
@@ -1257,6 +1322,7 @@
                        left_count_after += 1
                        if l2_data_util.is_big_money(val, is_ge_code) and j not in watch_indexes:
                            watch_indexes.add(j)
                            l2_log.l_cancel_debug(code, f"L后有成交后半段增加囊括:{j}")
                            self.__set_cancel_l_down_after_place_order_index(code, j, left_count_after - 1)
                            break
            except:
@@ -1280,6 +1346,20 @@
        if not watch_indexes_info:
            return False, None
        watch_indexes = set([int(i) for i in watch_indexes_info[2]])
        try:
            # 将备用订单加进去
            watch_indexes_by = self.__l_down_after_by_big_order_dict.get(code)
            if watch_indexes_by:
                # 是否是下单30分钟内
                real_place_order_info = self.__real_place_order_index_dict.get(code)
                if real_place_order_info and tool.trade_time_sub(total_data[-1]["val"]["time"] , total_data[real_place_order_info[0]]["val"]["time"]) < 30*60:
                    # 下单30分钟内有效
                    watch_indexes|=watch_indexes_by
                else:
                    # 清除备用大单
                    watch_indexes_by.clear()
        except Exception as e:
            l2_log.l_cancel_debug(code,"将L2后后半段备用大单加入计算出错:{}", str(e))
        # 计算监听的总条数
        total_num = 0
        max_num = 0
@@ -1464,11 +1544,18 @@
            trade_index = 0
        if trade_index is None:
            return True
        real_place_order_index_info = self.__real_place_order_index_dict.get(code)
        if not real_place_order_index_info:
            return True
        # 计算已经成交的比例
        total_datas = local_today_datas.get(code)
        total_deal_nums = 0
        total_nums = 1
        for index in watch_indexes_info[2]:
            # 不能计算L后后半段
            if index > real_place_order_index_info[0]:
                continue
            data = total_datas[index]
            val = data["val"]
            left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code,
l2/l2_transaction_data_processor.py
@@ -13,6 +13,7 @@
from l2.huaxin import l2_huaxin_util
from l2.l2_data_manager import OrderBeginPosInfo
from l2.l2_data_manager_new import L2TradeDataProcessor
from l2.l2_data_util import L2DataUtil
from l2.l2_transaction_data_manager import HuaXinBuyOrderManager, HuaXinSellOrderStatisticManager, BigOrderDealManager
from log_module import async_log_util
from log_module.log import hx_logger_l2_debug, logger_l2_trade_buy_queue, logger_debug, hx_logger_l2_upload
@@ -34,7 +35,9 @@
            d = datas[i]
            buy_no = f"{d[6]}"
            if buyno_map and buy_no in buyno_map:
                buy_progress_index = buyno_map[buy_no]["index"]
                # 成交进度位必须是涨停买
                if L2DataUtil.is_limit_up_price_buy(buyno_map[buy_no]["val"]):
                    buy_progress_index = buyno_map[buy_no]["index"]
                break
        return buy_progress_index