Administrator
2024-03-19 8e8a2a2767e2784a6548cd07a2bf7dd6558e3f43
l2/cancel_buy_strategy.py
@@ -19,7 +19,7 @@
from l2.huaxin import l2_huaxin_util
from l2.l2_data_manager import OrderBeginPosInfo
from l2.l2_sell_manager import L2LimitUpSellManager
from l2.l2_transaction_data_manager import HuaXinTransactionDataManager
from l2.l2_transaction_data_manager import HuaXinBuyOrderManager
from log_module import async_log_util
from trade.deal_big_money_manager import DealOrderNoManager
from trade.sell.sell_rule_manager import TradeRuleManager
@@ -36,7 +36,7 @@
def set_real_place_position(code, index, buy_single_index=None, is_default=True):
    # DCancelBigNumComputer().set_real_order_index(code, index)
    SecondCancelBigNumComputer().set_real_place_order_index(code, index)
    SCancelBigNumComputer().set_real_place_order_index(code, index)
    LCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index=buy_single_index,
                                                       is_default=is_default)
    HourCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index)
@@ -44,22 +44,18 @@
    FCancelBigNumComputer().set_real_order_index(code, index, is_default)
class SecondCancelBigNumComputer:
class SCancelBigNumComputer:
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __sCancelParamsManager = l2_trade_factor.SCancelParamsManager
    __s_big_num_cancel_compute_data_cache = {}
    __s_cancel_real_place_order_index_cache = {}
    # 成交位置
    __s_cancel_transaction_index_cache = {}
    # H撤是否初始化数据,当真实下单位置与成交位到来时才进行赋值
    __s_cancel_inited_data = {}
    __s_down_watch_indexes_dict = {}
    __instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(SecondCancelBigNumComputer, cls).__new__(cls, *args, **kwargs)
            cls.__instance = super(SCancelBigNumComputer, cls).__new__(cls, *args, **kwargs)
            cls.__load_datas()
        return cls.__instance
@@ -71,13 +67,6 @@
    def __load_datas(cls):
        __redis = cls.__get_redis()
        try:
            keys = RedisUtils.keys(__redis, "s_big_num_cancel_compute_data-*")
            for k in keys:
                code = k.split("-")[-1]
                val = RedisUtils.get(__redis, k)
                val = json.loads(val)
                tool.CodeDataCacheUtil.set_cache(cls.__s_big_num_cancel_compute_data_cache, code, val)
            keys = RedisUtils.keys(__redis, "s_cancel_real_place_order_index-*")
            for k in keys:
                code = k.split("-")[-1]
@@ -86,33 +75,6 @@
                tool.CodeDataCacheUtil.set_cache(cls.__s_cancel_real_place_order_index_cache, code, val)
        finally:
            RedisUtils.realse(__redis)
    # 保存结束位置
    def __save_compute_data(self, code, process_index, buy_num, cancel_num):
        CodeDataCacheUtil.set_cache(self.__s_big_num_cancel_compute_data_cache, code,
                                    (process_index, buy_num, cancel_num))
        key = "s_big_num_cancel_compute_data-{}".format(code)
        RedisUtils.setex_async(self.__db, key, tool.get_expire(),
                               json.dumps((process_index, buy_num, cancel_num)))
    def __get_compute_data(self, code):
        key = "s_big_num_cancel_compute_data-{}".format(code)
        val = RedisUtils.get(self.__get_redis(), key)
        if val is None:
            return -1, 0, 0
        val = json.loads(val)
        return val[0], val[1], val[2]
    def __get_compute_data_cache(self, code):
        cache_result = CodeDataCacheUtil.get_cache(self.__s_big_num_cancel_compute_data_cache, code)
        if cache_result[0]:
            return cache_result[1]
        return -1, 0, 0
    def __del_compute_data_cache(self, code):
        CodeDataCacheUtil.clear_cache(self.__s_big_num_cancel_compute_data_cache, code)
        key = "s_big_num_cancel_compute_data-{}".format(code)
        RedisUtils.delete_async(self.__db, key)
    # 设置真实下单位置
    def __save_real_place_order_index(self, code, index):
@@ -140,10 +102,9 @@
        return None
    def __clear_data(self, code):
        CodeDataCacheUtil.clear_cache(self.__s_big_num_cancel_compute_data_cache, code)
        CodeDataCacheUtil.clear_cache(self.__s_cancel_real_place_order_index_cache, code)
        CodeDataCacheUtil.clear_cache(self.__s_cancel_transaction_index_cache, code)
        CodeDataCacheUtil.clear_cache(self.__s_cancel_inited_data, code)
        CodeDataCacheUtil.clear_cache(self.__s_down_watch_indexes_dict, code)
        ks = ["s_big_num_cancel_compute_data-{}".format(code), "s_cancel_real_place_order_index-{}".format(code)]
        for key in ks:
            RedisUtils.delete_async(self.__db, key)
@@ -151,10 +112,6 @@
    # 设置真实下单位置
    def set_real_place_order_index(self, code, index):
        self.__save_real_place_order_index(code, index)
    # 设置成交进度位
    def set_transaction_index(self, code, index):
        self.__s_cancel_transaction_index_cache[code] = index
    def clear_data(self):
        ks = ["s_big_num_cancel_compute_data-*", "s_cancel_real_place_order_index-*"]
@@ -164,215 +121,6 @@
                code = k.split("-")[1]
                self.__clear_data(code)
    # 计算净大单
    def __compute_left_big_num(self, code, buy_single_index, start_index, end_index, total_data, volume_rate_index):
        # 点火大单数量
        fire_count = self.__sCancelParamsManager.get_max_exclude_count(volume_rate_index)
        return self.compute_left_big_num(code, buy_single_index, start_index, end_index, total_data, fire_count,
                                         constant.S_CANCEL_MIN_MONEY)
    # 计算未撤的总手数
    def compute_left_big_num(self, code, buy_single_index, start_index, end_index, total_data, fire_count, min_money_w):
        # 获取大单的最小手数
        left_big_num = 0
        for i in range(start_index, end_index + 1):
            data = total_data[i]
            val = data["val"]
            # 去除非大单
            if val["num"] * float(val["price"]) <= min_money_w * 100:
                continue
            if L2DataUtil.is_limit_up_price_buy(val):
                if i - buy_single_index < fire_count:
                    # 点火大单不算
                    left_big_num += 0
                else:
                    left_big_num += val["num"] * data["re"]
            elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                # 查询买入位置
                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 not None and start_index <= buy_index <= end_index:
                    if buy_index - buy_single_index < fire_count:
                        left_big_num -= 0
                    else:
                        left_big_num -= val["num"] * data["re"]
                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"],
                                                                                     val["cancelTimeUnit"])
                    # 只判断S级撤销,只有s级撤销才有可能相等
                    if max_space - min_space <= 1:
                        buy_time = tool.trade_time_add_second(val["time"], 0 - min_space)
                        if int(total_data[start_index]["val"]["time"].replace(":", "")) <= int(
                                buy_time.replace(":", "")) <= int(
                            total_data[end_index]["val"]["time"].replace(":", "")):
                            left_big_num -= val["num"] * data["re"]
        return left_big_num
    def need_cancel(self, 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 buy_single_index is None or buy_exec_index is None:
            return False, "尚未找到下单位置"
        # 只守护30s
        buy_exec_time = total_data[buy_exec_index]["val"]["time"]
        if tool.trade_time_sub(total_data[start_index]["val"]["time"],
                               buy_exec_time) > constant.S_CANCEL_EXPIRE_TIME:
            return False, None
        l2_log.cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index)
        l2_log.s_cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index)
        real_place_order_index = self.__s_cancel_real_place_order_index_cache.get(code)
        transaction_index = self.__s_cancel_transaction_index_cache.get(code)
        if real_place_order_index and transaction_index:
            # S撤计算范围:成交位-真实下单位
            if not self.__s_cancel_inited_data.get(code):
                l2_log.s_cancel_debug(code, "S撤初始化,成交位:{} 下单位:{}", transaction_index, real_place_order_index)
                # 清除之前的计算数据
                self.__s_cancel_inited_data[code] = True
                self.__del_compute_data_cache(code)
                # 计算未撤单的订单手数
                left_big_num = 0
                for i in range(transaction_index + 1, real_place_order_index):
                    data = total_data[i]
                    val = data["val"]
                    if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                        continue
                    # 获取
                    if L2DataUtil.is_limit_up_price_buy(val):
                        left_big_num += val["num"] * data["re"]
                    elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                        # 查询买入位置
                        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 not None and transaction_index + 1 <= buy_index <= real_place_order_index and i < start_index:
                            left_big_num -= val["num"] * data["re"]
                l2_log.s_cancel_debug(code, "S撤初始化结果,left_big_num:{}", left_big_num)
                self.__save_compute_data(code, real_place_order_index, left_big_num, 0)
                # 保存信息
            process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code)
            process_index = process_index_old
            cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index)
            try:
                for i in range(start_index, end_index + 1):
                    data = total_data[i]
                    val = data["val"]
                    process_index = i
                    if process_index_old >= i:
                        # 已经处理过的数据不需要处理
                        continue
                    if L2DataUtil.is_limit_up_price_buy_cancel(val):
                        if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                            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 not None and transaction_index < buy_index < real_place_order_index:
                            cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"])
                            if need_cancel:
                                rate__ = round(cancel_num / max(buy_num, 1), 2)
                                if rate__ > cancel_rate_threshold:
                                    return True, total_data[i]
            finally:
                # 保存处理进度与数据
                self.__save_compute_data(code, process_index, buy_num, cancel_num)
        else:
            # S测计算位置为信号起始位置执行位1s之后
            if tool.trade_time_sub(total_data[end_index]["val"]["time"],
                                   total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME:
                # 结束位置超过了执行位置60s,需要重新确认结束位置
                for i in range(end_index, start_index - 1, -1):
                    if total_data[end_index]["val"]["time"] != total_data[i]["val"]["time"]:
                        end_index = i
                        break
            # 获取处理进度
            process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code)
            # 如果start_index与buy_single_index相同,即是下单后的第一次计算
            # 需要查询买入信号之前的同1s是否有涨停撤的数据
            process_index = process_index_old
            if process_index_old == -1:
                # 第1次计算需要计算买入信号-执行位的净值
                left_big_num = self.__compute_left_big_num(code, buy_single_index, buy_single_index, buy_exec_index,
                                                           total_data, volume_rate_index)
                buy_num += left_big_num
                # 设置买入信号-买入执行位的数据不需要处理
                process_index = buy_exec_index
            # 强制固定为1s
            range_seconds = 1  # self.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index)
            # 获取真实下单位置
            place_order_index = self.__get_real_place_order_index_cache(code)
            cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index)
            try:
                for i in range(start_index, end_index + 1):
                    data = total_data[i]
                    val = data["val"]
                    process_index = i
                    if process_index_old >= i:
                        # 已经处理过的数据不需要处理
                        continue
                    if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                        continue
                    if L2DataUtil.is_limit_up_price_buy(val):
                        if place_order_index is not None and place_order_index < data["index"]:
                            # 不能比下单位置后
                            continue
                        # 如果在囊括时间范围内就可以计算买
                        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_v2(data,
                                                                                                            local_today_buyno_map.get(
                                                                                                                code))
                        if buy_index is not None and buy_single_index <= buy_index:
                            if place_order_index and place_order_index >= buy_index:
                                cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"])
                            # 买入时间在囊括范围内
                            elif 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"],
                                                                                             val["cancelTimeUnit"])
                            # 只判断S级撤销,只有s级撤销才有可能相等
                            if max_space - min_space <= 1:
                                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(":", "")):
                                    # 买入时间在囊括范围内
                                    if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds),
                                                           buy_time) >= 0:
                                        cancel_num += data["re"] * int(val["num"])
                        # 保存数据
                        if need_cancel:
                            rate__ = round(cancel_num / max(buy_num, 1), 2)
                            if rate__ > 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), cancel_rate_threshold,
                                    range_seconds)
                # 保存处理进度与数据
                self.__save_compute_data(code, process_index, buy_num, cancel_num)
        return False, None
    # 撤单成功
    def cancel_success(self, code):
        self.__clear_data(code)
@@ -381,13 +129,130 @@
    def place_order_success(self, code):
        self.__clear_data(code)
    # S前撤实现
    def __need_cancel_for_up(self, code, big_sell_order_info, total_datas):
        trade_index, is_default = TradeBuyQueue().get_traded_index(code)
        real_order_index = self.__get_real_place_order_index_cache(code)
        if real_order_index is None and big_sell_order_info[0] < 500000:
            return True, "没找到真实下单位置就有大卖单"
        start_order_no = big_sell_order_info[1][0][3][1]
        total_num = 0
        for i in range(trade_index, real_order_index):
            data = total_datas[i]
            val = data['val']
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            if int(val['orderNo']) < start_order_no:
                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:
                total_num += val["num"]
        total_money = total_num * 100 * big_sell_order_info[1][-1][2]
        total_deal_money = sum([x[1] * x[2] for x in big_sell_order_info[1]])
        deal_rate = round(total_deal_money / total_money, 4)
        if deal_rate >= 0.3:
            return True, f"成交比例:{deal_rate}({total_deal_money}/{total_money})"
    # 计算S后撤监听的数据范围
    def __compute_down_cancel_watch_index(self, code, big_sell_order_info, total_datas):
        trade_index, is_default = TradeBuyQueue().get_traded_index(code)
        real_order_index = self.__get_real_place_order_index_cache(code)
        start_order_no = big_sell_order_info[1][-1][4][1]
        latest_deal_time = l2_huaxin_util.convert_time(big_sell_order_info[1][-1][4][0], with_ms=True)
        if code in self.__s_down_watch_indexes_dict:
            # 更新囊括范围后1s内不能再次更新
            if tool.trade_time_sub_with_ms(latest_deal_time, self.__s_down_watch_indexes_dict[code][0]) <= 1000:
                return
        watch_index_info = []
        for i in range(trade_index, real_order_index):
            data = total_datas[i]
            val = data['val']
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            if int(val['orderNo']) < start_order_no:
                continue
            if val['num'] * float(val['price']) < 5000:
                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_index_info.append((i, val['num']))
        watch_index_info.sort(key=lambda x: x[1], reverse=True)
        watch_indexes = set([x[0] for x in watch_index_info[:5]])
        l2_log.s_cancel_debug(code, f"S后计算那概括范围:{watch_indexes}  最近成交的卖单信息:{big_sell_order_info[1][-1]}")
        if watch_indexes:
            # 保存卖单信息
            self.__s_down_watch_indexes_dict[code] = (latest_deal_time, watch_indexes)
    #  big_sell_order_info格式:[总共的卖单金额, 大卖单详情列表]
    def set_big_sell_order_info_for_cancel(self, code,  big_sell_order_info,order_begin_pos: OrderBeginPosInfo):
        if order_begin_pos is None or order_begin_pos.buy_exec_index is None or order_begin_pos.buy_exec_index < 0:
            return False, "还未下单"
        if big_sell_order_info[0] < 500000 or not big_sell_order_info[1]:
            return False, "无大单卖"
        # 获取最新的成交时间
        total_datas = local_today_datas.get(code)
        latest_trade_time = l2_huaxin_util.convert_time(big_sell_order_info[1][-1][4][0])
        if tool.trade_time_sub(latest_trade_time, total_datas[order_begin_pos.buy_single_index]['val']['time']) < 180:
            return self.__need_cancel_for_up(code, big_sell_order_info, total_datas)
        else:
            self.__compute_down_cancel_watch_index(code, big_sell_order_info, total_datas)
            return False, "超过S前守护范围"
    def need_cancel_for_down(self, code, start_index, end_index):
        watch_index_info = self.__s_down_watch_indexes_dict.get(code)
        if not watch_index_info:
            return False, "没获取到囊括范围"
        total_datas = local_today_datas.get(code)
        if tool.trade_time_sub(total_datas[-1]["val"]["time"], watch_index_info[0].split(".")[0]) > 9:
            return False, "超过守护时间"
        watch_indexes = watch_index_info[1]
        watch_order_nos = set([total_datas[d]['val']['orderNo'] for d in watch_indexes])
        # 计算是否有撤单
        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['orderNo'] in watch_order_nos:
                need_compute = True
                break
        if not need_compute:
            return False, "没有监听范围内的单撤单"
        # 计算撤单比例
        total_num = 0
        cancel_num = 0
        for index in watch_indexes:
            total_num += total_datas[index]["val"]['num']
            left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, index,
                                                                                                     total_datas,
                                                                                                     local_today_canceled_buyno_map.get(
                                                                                                         code))
            if left_count <= 0:
                cancel_num += total_datas[index]["val"]['num']
        cancel_rate = round(cancel_num / total_num, 4)
        if cancel_rate >= 0.25:
            return True, f"达到撤单比例:{cancel_rate}  监听范围:{watch_index_info}"
        return False, "没达到撤单比例"
# --------------------------------H撤-------------------------------
class HourCancelBigNumComputer:
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __tradeBuyQueue = TradeBuyQueue()
    __SecondCancelBigNumComputer = SecondCancelBigNumComputer()
    __SCancelBigNumComputer = SCancelBigNumComputer()
    # 计算触发位置
    __start_compute_index_dict = {}
@@ -483,7 +348,7 @@
            return
        if self.__cancel_watch_indexs_cache.get(code):
            return
        real_place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code)
        real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code)
        if not real_place_order_index:
            l2_log.h_cancel_debug(code, "尚未找到真实下单位置")
            return
@@ -561,7 +426,7 @@
        start_compute_index = self.__start_compute_index_dict.get(code)
        if start_compute_index is None:
            return False
        real_place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code)
        real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code)
        total_datas = local_today_datas.get(code)
        if real_place_order_index and real_place_order_index > transaction_index:
            # 成交位置离我们真实下单的位置只有5笔没撤的大单就需要计算H撤的囊括范围了
@@ -874,7 +739,7 @@
    # 成交位附近临近大单索引
    __near_by_trade_progress_index_cache = {}
    __SecondCancelBigNumComputer = SecondCancelBigNumComputer()
    __SCancelBigNumComputer = SCancelBigNumComputer()
    # L后囊括范围未撤单/未成交的总手数
    __total_l_down_not_deal_num_dict = {}
@@ -1131,7 +996,8 @@
        RedisUtils.setex_async(self.__db, f"l_cancel_real_place_order_index-{code}", tool.get_expire(), index)
        if buy_single_index is not None:
            if code in self.__last_trade_progress_dict:
                self.compute_watch_index(code, buy_single_index, max(buy_single_index, self.__last_trade_progress_dict[code] + 1), index)
                self.compute_watch_index(code, buy_single_index,
                                         max(buy_single_index, self.__last_trade_progress_dict[code] + 1), index)
            else:
                self.compute_watch_index(code, buy_single_index, buy_single_index, index)
@@ -1228,7 +1094,7 @@
                    fnum = val["num"]
                    if i == trade_progress:
                        # 需要减去已经成交的数据
                        dealing_info = HuaXinTransactionDataManager.get_dealing_order_info(code)
                        dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code)
                        if dealing_info:
                            if str(val["orderNo"]) == str(dealing_info[0]):
                                fnum -= dealing_info[1] // 100
@@ -1738,13 +1604,13 @@
                                                                                                             code))
                if left_count > 0:
                    total_deal_num += val["num"] * left_count
            dealing_info = HuaXinTransactionDataManager.get_dealing_order_info(code)
            dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code)
            if dealing_info:
                if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]):
                    total_deal_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100)
            limit_up_price = gpcode_manager.get_limit_up_price(code)
            deal_money = int(total_deal_num * float(limit_up_price) * 100)
            if deal_money >= order_position.sell_info[1] * 2 and order_position.sell_info[1] > 1000*10000:
            if deal_money >= order_position.sell_info[1] * 2 and order_position.sell_info[1] > 1000 * 10000:
                return True, f"成交金额:{deal_money}/{order_position.sell_info[1] * 2}"
            return False, "成交金额不满足"
        except Exception as e:
@@ -1939,7 +1805,7 @@
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __cancel_real_order_index_cache = {}
    __SecondCancelBigNumComputer = SecondCancelBigNumComputer()
    __SCancelBigNumComputer = SCancelBigNumComputer()
    __instance = None
@@ -1978,7 +1844,7 @@
        time_sub = tool.trade_time_sub(tool.get_now_time_str(),
                                       total_datas[order_begin_pos.buy_exec_index]["val"]["time"])
        if 2 < time_sub < 30 * 60:
            real_place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code)
            real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code)
            if not real_place_order_index:
                return False, "尚未找到真实下单位置"
            total_left_count = 0