Administrator
26 分钟以前 cb4589db74aac2822f2aeb97eb3c28d2b7d59338
l2/cancel_buy_strategy.py
@@ -11,6 +11,7 @@
import constant
from cancel_strategy import s_l_h_cancel_strategy
from cancel_strategy.s_l_h_cancel_strategy import CancelRateHumanSettingManager
from code_attribute import big_money_num_manager, gpcode_manager, code_volumn_manager
import l2_data_util
from db import redis_manager_delegate as redis_manager
@@ -41,6 +42,7 @@
    FCancelBigNumComputer().set_real_order_index(code, index, is_default)
    JCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index, is_default)
    NBCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index, is_default)
    RDCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index, is_default)
class BaseCancel:
@@ -150,6 +152,31 @@
                    max_info = (i, val["num"])
        return total_datas[max_info[0]]
    @classmethod
    def is_canceled(cls, code, index, total_datas, canceled_buyno_map, trade_index, deal_order_nos):
        """
        是否已经撤单
        @param deal_order_nos: 成交大单集合
        @param trade_index: 成交进度位
        @param index: 索引
        @param code: 代码
        @param total_datas:
        @param canceled_buyno_map:撤单的订单号
        @return:
        """
        cancel_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, index,
                                                                                              total_datas,
                                                                                              canceled_buyno_map)
        if cancel_data:
            # 已经撤单
            return True
        else:
            if trade_index and trade_index > index:
                # 成交进度大于索引位置,且还没成交
                if total_datas[index]["val"]["orderNo"] not in deal_order_nos:
                    return True
            return False
# ---------------------------------D撤-------------------------------
# 计算 成交位->真实下单位置 总共还剩下多少手没有撤单
@@ -251,6 +278,36 @@
        RedisUtils.setex_async(self.__db, f"radical_big_order_watch-{code}", tool.get_expire(),
                               json.dumps(list(indexes)))
    def set_real_place_order_index(self, code, index, buy_single_index, is_default):
        if is_default:
            return
        if code in self.__watch_indexes_cache and len(self.__watch_indexes_cache[code]) > 1:
            # 囊括的单大于1个
            return
        # 从买入信号位开始囊括
        limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
        min_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code))
        min_num = int(round(min_money / limit_up_price / 100))
        total_datas = local_today_datas.get(code)
        watch_indexes = set()
        for i in range(buy_single_index, index):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            if val["num"] < min_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:
                watch_indexes.add(i)
        if watch_indexes:
            l2_log.d_cancel_debug(code, f"更新扫入大单监听:{watch_indexes}")
            self.__watch_indexes_cache[code] = watch_indexes
    def need_cancel(self, code, start_index, end_index):
        """
        是否需要撤单
@@ -263,39 +320,38 @@
        if not watch_indexes:
            return False, None, "无大单监听"
        total_datas = local_today_datas.get(code)
        need_compute = False
        for i in range(start_index, end_index + 1):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy_cancel(val):
                continue
            if val["num"] * float(val["price"]) < 5000:
                continue
            buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data,
                                                                                                local_today_buyno_map.get(
                                                                                                    code))
            if buy_index is None:
                continue
            if buy_index in watch_indexes:
                need_compute = True
                break
        if tool.trade_time_sub(total_datas[start_index]["val"]["time"],
                               total_datas[list(watch_indexes)[0]]["val"]["time"]) > 60:
            return False, None, "只有前60s生效"
        if need_compute:
        cancel_indexes = set()
        canceled_buyno_map = local_today_canceled_buyno_map.get(code)
        if True:
            cancel_count = 0
            cancel_data = None
            # 成交买单号
            deal_order_nos = HuaXinBuyOrderManager().get_deal_buy_order_nos(code)
            if deal_order_nos is None:
                deal_order_nos = set()
            trade_index, is_default = TradeBuyQueue().get_traded_index(code)
            if is_default:
                trade_index = None
            for index in watch_indexes:
                cancel_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, index,
                                                                                                      total_datas,
                                                                                                      local_today_canceled_buyno_map.get(
                                                                                                          code))
                if cancel_data:
                if L2DataComputeUtil.is_canceled(code, index, total_datas, canceled_buyno_map, trade_index,
                                                 deal_order_nos):
                    # 买单已撤单
                    cancel_count += 1
            if cancel_count >= len(watch_indexes):
                return True, cancel_data, f"大单撤单({watch_indexes})"
                    cancel_indexes.add(index)
            if cancel_indexes:
                l2_log.d_cancel_debug(code, f"已撤单:{cancel_indexes}")
            rate = round(cancel_count / len(watch_indexes), 2)
            if rate >= 0.8:
                return True, cancel_data, f"撤单比例-{rate},大单撤单({cancel_indexes})"
        return False, None, "无大单撤单"
    def __clear_data(self, code):
        if code in self.__watch_indexes_cache:
            l2_log.d_cancel_debug(code, f"清除大单监听")
            self.__watch_indexes_cache.pop(code)
            RedisUtils.delete_async(self.__db, f"radical_big_order_watch-{code}")
@@ -418,6 +474,11 @@
    # 下单3分钟内距离下单位置不足3笔(包含正在成交)且不到300w就需要撤单
    def need_cancel_for_deal_fast(self, code, trade_index=None):
        # 人为改了撤单比例之后不能生效
        human_rate = CancelRateHumanSettingManager().get_l_down(code)
        if human_rate:
            return False, "人为修改了撤单比例"
        if trade_index is None:
            trade_info = TradeBuyQueue().get_traded_index(code)
            if trade_info and not trade_info[1] and trade_info[0] is not None:
@@ -440,27 +501,26 @@
        # 是否是下单1分钟内
        if tool.trade_time_sub(tool.get_now_time_str(), total_datas[real_order_index]['val']['time']) > 1 * 60:
            return False, "下单超过60s"
        try:
            if code in self.__max_buy_order_num_cache:
                max_num = self.__max_buy_order_num_cache[code]
                if max_num and tool.is_ge_code(code):
                    max_num = max_num * 6.6
                details = HuaXinSellOrderStatisticManager.get_latest_3s_continue_deal_volumes(code)
                threshold_num = int(max_num * 0.5 * 100)
                count = 0
                for d in details:
                    if d[1] > threshold_num:
                        count += 1
                if count >= 2:
                    return True, f"连续3秒有2s抛压过大:{details} 最大值:{max_num}"
        except Exception as e:
            l2_log.f_cancel_debug(code, f"大抛压撤单计算出错:{str(e)}")
        # try:
        #     if code in self.__max_buy_order_num_cache:
        #         max_num = self.__max_buy_order_num_cache[code]
        #         if max_num and tool.is_ge_code(code):
        #             max_num = max_num * 6.6
        #         details = HuaXinSellOrderStatisticManager.get_latest_3s_continue_deal_volumes(code)
        #         threshold_num = int(max_num * 0.5 * 100)
        #         count = 0
        #         for d in details:
        #             if d[1] > threshold_num:
        #                 count += 1
        #         if count >= 2:
        #             return True, f"连续3秒有2s抛压过大:{details} 最大值:{max_num}"
        # except Exception as e:
        #     l2_log.f_cancel_debug(code, f"大抛压撤单计算出错:{str(e)}")
        # 查询最近2秒成交是否超过阈值
        THRESHOLD_MONEY_W, THRESHOLD_COUNT = self.__get_fast_deal_threshold_value(code,
                                                                                  total_datas[real_order_index]['val'][
                                                                                      'time'])
        THRESHOLD_MONEY_W, THRESHOLD_COUNT = 1200, 3  # self.__get_fast_deal_threshold_value(code,
        #                                     total_datas[real_order_index]['val'][
        #                                         'time'])
        total_left_count = 0
        total_left_num = 0
@@ -487,13 +547,20 @@
                if dealing_info and str(dealing_info[0]) == str(val["orderNo"]):
                    total_left_num -= dealing_info[1] // 100
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if total_left_count <= 1 or (total_left_count <= THRESHOLD_COUNT and limit_up_price and total_left_num * float(
        total_left_money = total_left_num * float(limit_up_price) * 100
        if total_left_money < 1e8:
            if total_left_count <= 1 or (
                    total_left_count <= THRESHOLD_COUNT and limit_up_price and total_left_num * float(
                limit_up_price) < THRESHOLD_MONEY_W * 100):
            return True, f"剩余笔数({total_left_count})/金额({round(total_left_num * float(limit_up_price) * 100)})不足,成交进度:{trade_index},真实下单位置:{real_order_index} 阈值:({THRESHOLD_MONEY_W},{THRESHOLD_COUNT}) "
                return True, f"剩余笔数({total_left_count})/金额({round(total_left_num * float(limit_up_price) * 100)})不足,成交进度:{trade_index},真实下单位置:{real_order_index} 阈值:({THRESHOLD_MONEY_W},{THRESHOLD_COUNT}) "
        return False, f"不满足撤单条件: 成交进度-{trade_index} 真实下单位置-{real_order_index} total_left_count-{total_left_count} total_left_num-{total_left_num}"
    # 距离太近,封单不足
    def need_cancel_for_p(self, code, order_begin_pos):
        if True:
            return False, ""
        if gpcode_manager.MustBuyCodesManager().is_in_cache(code):
            return False, "已加红"
@@ -535,9 +602,9 @@
        #     if buy1_money:
        #         if total_num_ * limit_up_price * 100 > buy1_money * 0.65:
        #             return True, f"P撤:成交位置距离下单位置太远 成交位-{trade_index} 下单位-{real_order_index} 买1-{buy1_money}"
        min_time_s, max_time_s = 2, 30
        if total_num * limit_up_price >= 299 * 100:
            min_time_s, max_time_s = 30, 60
        min_time_s, max_time_s = 2, 60
        # if total_num * limit_up_price >= 299 * 100:
        #     min_time_s, max_time_s = 30, 60
        if sub_time <= min_time_s:
            return False, f"下单在{min_time_s}s内"
@@ -548,27 +615,27 @@
        # 计算我们后面的大单与涨停纯买额
        total_left_num = 0
        total_big_num_count = 0
        canceled_buyno_map = local_today_canceled_buyno_map.get(code)
        for i in range(real_order_index + 1, len(total_datas)):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            money = val["num"] * float(val["price"])
            if money < 5000:
            money = val["num"] * float(val["price"]) * 100
            if money < 500000:
                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))
                                                                                                     canceled_buyno_map)
            if left_count > 0:
                if money > 299 * 100:
                if money >= min_money:
                    total_big_num_count += 1
                total_left_num += val["num"]
        left_money = total_left_num * float(limit_up_price)
        if left_money < 1000 * 100:
        if left_money < 1000 * 100 or total_big_num_count < 2:
            # 实际下单位后方所有涨停纯买额≤1000万
            return True, f"P撤:封单纯买额-{round(left_money / 100, 1)}万 大单数量-{total_big_num_count} 下单位-{real_order_index}"
            return True, f"P撤:封单纯买额-{round(left_money / 100, 1)}万 剩余大单数量-{total_big_num_count} 下单位-{real_order_index}"
        return False, "不满足撤单条件"
    # w撤