Administrator
2025-07-18 e0062b65da7f3ff34f4c831cc2ef3635b0f44437
加倍控制中心接口内容优化
3个文件已修改
229 ■■■■ 已修改文件
api/outside_api_command_callback.py 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cancel_strategy/s_l_h_cancel_strategy.py 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/buy_radical/radical_buy_data_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/outside_api_command_callback.py
@@ -881,9 +881,10 @@
                account_available_money = trade_data_manager.AccountMoneyManager().get_available_money_cache()
                # 获取委托中的代码
                # current_delegates = huaxin_trade_record_manager.DelegateRecordManager().list_current_delegates()
                # TODO 测试
                current_delegates, update_time = huaxin_trade_record_manager.DelegateRecordManager.list_by_day(
                    tool.get_now_date_str("%Y%m%d"), None,
                    [huaxin_util.TORA_TSTP_OST_Accepted, huaxin_util.TORA_TSTP_OST_PartTraded])
                    [huaxin_util.TORA_TSTP_OST_Accepted, huaxin_util.TORA_TSTP_OST_PartTraded, huaxin_util.TORA_TSTP_OST_AllCanceled ])
                fdatas = []
                if current_delegates:
                    codes_set = set()
@@ -912,22 +913,7 @@
                            place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                            if place_order_index is None:
                                place_order_index = 0
                            # 计算信号位置到真实下单位置的总买(不管是否已撤)
                            total_nums = 0
                            for i in range(order_begin_pos.buy_single_index, place_order_index):
                                data = total_datas[i]
                                val = data["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                total_nums += val["num"]
                            # 计算已成交/已撤单的数量
                            deal_or_cancel_num = 0
                            for i in range(order_begin_pos.buy_single_index, trade_index + 1):
                                data = total_datas[i]
                                val = data["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                deal_or_cancel_num += val["num"]
                            # 获取剩下的笔数
                            total_left_count = 0
                            total_left_num = 0
@@ -952,69 +938,10 @@
                            if dealing_info:
                                if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]):
                                    total_left_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100)
                            limit_up_price = gpcode_manager.get_limit_up_price(code)
                            limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
                            buy1_money = Buy1PriceManager().get_latest_buy1_money(code)
                            if buy1_money is None:
                                buy1_money = 1
                            # 获取已经成交的大单数量
                            total_big_num = 0
                            total_big_count = 0
                            is_ge_code = tool.is_ge_code(code)
                            for i in range(0, trade_index):
                                val = total_datas[i]["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                # 是不是大单
                                if not l2_data_util_old.is_big_money(val, is_ge_code):
                                    continue
                                canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(
                                    code,
                                    i,
                                    total_datas,
                                    l2_data_util.local_today_canceled_buyno_map.get(
                                        code))
                                if not canceled_data:
                                    total_big_count += 1
                                else:
                                    total_big_num -= canceled_data["val"]["num"]
                                total_big_num += val["num"]
                            not_deal_total_big_num_pre = 0
                            not_deal_total_big_count_pre = 0
                            not_deal_total_big_num_after = 0
                            not_deal_total_big_count_after = 0
                            is_ge_code = tool.is_ge_code(code)
                            for i in range(trade_index, total_datas[-1]["index"] + 1):
                                val = total_datas[i]["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                # 是不是大单
                                if not l2_data_util_old.is_big_money(val, is_ge_code):
                                    continue
                                canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(
                                    code,
                                    i,
                                    total_datas,
                                    l2_data_util.local_today_canceled_buyno_map.get(
                                        code))
                                if not canceled_data:
                                    if i < place_order_index:
                                        not_deal_total_big_count_pre += 1
                                    else:
                                        not_deal_total_big_count_after += 1
                                else:
                                    if i < place_order_index:
                                        not_deal_total_big_num_pre -= canceled_data["val"]["num"]
                                    else:
                                        not_deal_total_big_num_after -= canceled_data["val"]["num"]
                                if i < place_order_index:
                                    not_deal_total_big_num_pre += val["num"]
                                else:
                                    not_deal_total_big_num_after += val["num"]
                            real_place_order_after_count = 0
                            real_place_order_after_num = 0
                            is_ge_code = tool.is_ge_code(code)
@@ -1037,89 +964,26 @@
                                    real_place_order_after_count += 1
                                    real_place_order_after_num += val["num"]
                            # 获取当日的量比
                            volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code)
                            # 是否需要注意
                            need_pay_attention = (total_left_count <= 10 or total_left_num * float(
                                limit_up_price) * 100 < 1500 * 10000) and (
                                                         real_place_order_after_count <= 10 or real_place_order_after_num * float(
                                                     limit_up_price) * 100 < 1500 * 10000)
                            # 统计真实下单位是否距离大单位置过近
                            is_near_big_order = False
                            try:
                                count = 0
                                for i in range(place_order_index - 1, -1, -1):
                                    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 < 50 * 100:
                                        continue
                                    left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(
                                        code,
                                        i,
                                        total_datas,
                                        l2_data_util.local_today_canceled_buyno_map.get(
                                            code))
                                    if left_count <= 0:
                                        continue
                                    if money >= 299 * 100:
                                        if count < 1:
                                            is_near_big_order = True
                                    else:
                                        count += 1
                                        if count >= 1:
                                            break
                            except:
                                pass
                                                         real_place_order_after_count <= 10 or real_place_order_after_num * limit_up_price * 100 < 1500 * 10000)
                            # L撤比例
                            l_down_cancel_rate, must_buy, cancel_rate_info = LCancelRateManager.get_cancel_rate(code,
                                                                                                                buy_mode=OrderBeginPosInfo.MODE_RADICAL)
                            # 在挂的距离成交进度位金额/(远近期参考量-单当日实时成交量)*100%
                            expire_rate = "未知"
                            try:
                                referer_volume = code_volumn_manager.CodeVolumeManager().get_radical_buy_refer_volume(
                                    code, float(limit_up_price))
                                today_volumn = code_volumn_manager.CodeVolumeManager().get_today_volumn_cache(code)
                                if referer_volume == today_volumn:
                                    expire_rate = "100%"
                                else:
                                    expire_rate = f"{100 - round(100 * total_left_num * 100 / (referer_volume - today_volumn), 2)}%"
                            except Exception as e:
                                logger_debug.exception(e)
                            fdata = {"id": orderSysID, "code_info": (code, code_name), "total_num": total_nums,
                                     "finish_num": deal_or_cancel_num,
                            fdata = {"id": orderSysID, "code_info": (code, code_name),
                                     "buy1_money": output_util.money_desc(buy1_money),
                                     "big_num_count": total_big_count,
                                     "big_num_money": output_util.money_desc(
                                         total_big_num * float(limit_up_price) * 100),
                                     "not_deal_big_num_count": (
                                         not_deal_total_big_count_pre, not_deal_total_big_count_after),
                                     "not_deal_big_num_money": (output_util.money_desc(
                                         not_deal_total_big_num_pre * float(limit_up_price) * 100),
                                                                output_util.money_desc(
                                                                    not_deal_total_big_num_after * float(
                                                                        limit_up_price) * 100)),
                                     "left_count": total_left_count,
                                     "volume_rate": volume_rate,
                                     "left_money": output_util.money_desc(total_left_num * float(limit_up_price) * 100),
                                     "pay_attention": need_pay_attention,
                                     "trade_progress_percent": round(
                                         total_left_num * float(limit_up_price) * 100 * 100 / buy1_money, 2),  # 成交进度比例
                                     "limit_up_price": gpcode_manager.get_limit_up_price_as_num(code),
                                     "is_near_big_order": is_near_big_order,
                                     "limit_up_price": limit_up_price,
                                     "block": '',
                                     "trade_queue": [],
                                     "l_down_cancel_rate": l_down_cancel_rate,
                                     "l_down_cancel_rate_info": cancel_rate_info,
                                     "expire_rate": expire_rate
                                     }
                            limit_up_data = kpl_data_manager.KPLLimitUpDataRecordManager.record_code_dict.get(code)
                            # 获取当前板块
@@ -1156,23 +1020,12 @@
                                    fdata['zyltgb'] = output_util.money_desc(zyltgb)
                            except:
                                pass
                            try:
                                if order_begin_pos:
                                    fdata['mode'] = order_begin_pos.mode
                                else:
                                    fdata['mode'] = -1
                            except:
                                pass
                            # L后囊括快照
                            try:
                                current_info = LCancelBigNumComputer().statistic_l_down_watch_indexes_info(code)
                                last_info = LDownCancelWatchIndexStatisticManager().get_statistic_info(code)
                                fdata['l_down_watch_indexes_info'] = {}
                                if current_info:
                                    fdata['l_down_watch_indexes_info']['current'] = current_info
                                if last_info:
                                    fdata['l_down_watch_indexes_info']['last'] = last_info
                            except:
                                pass
                            fdatas.append(fdata)
@@ -1543,14 +1396,11 @@
                    return
                rate = round(rate, 2)
                old_rate = LCancelRateManager().get_cancel_rate(0)[0]
                # L后数据快照
                last_info = LCancelBigNumComputer().statistic_l_down_watch_indexes_info(code)
                LDownCancelWatchIndexStatisticManager().set_statistic_info(code, last_info)
                CancelRateHumanSettingManager().set_l_down(code, rate)
                # L后重新囊括
                if rate < old_rate:
                    # 改小才能重新囊括
                    LCancelBigNumComputer().re_compute_l_down_watch_indexes(code)
                    LCancelBigNumComputer().re_compute_l_down_watch_indexes(code, is_force=True)
                self.send_response({"code": 0, "data": {}},
                                   client_id,
                                   request_id)
cancel_strategy/s_l_h_cancel_strategy.py
@@ -954,8 +954,9 @@
        # 重新计算L上
    # big_sell_info卖单信息,格式:[最近成交索引,最近成交时间(带毫秒)]
    def re_compute_l_down_watch_indexes(self, code, big_sell_info=None):
    def re_compute_l_down_watch_indexes(self, code, big_sell_info=None, is_force=False):
        watch_index_info = self.__cancel_watch_index_info_cache.get(code)
        if not is_force:
        if not watch_index_info or watch_index_info[1] > 0:
            return
        # 获取成交进度位与真实下单位置
@@ -972,17 +973,18 @@
        self.compute_watch_index(code, watch_index_info[0], last_trade_progress_index + 1,
                                 real_place_order_index_info[0],
                                 re_compute=1, min_cancel_time_with_ms=min_cancel_time_with_ms,
                                 msg=f"大单卖: 成交进度-{big_sell_info}" if big_sell_info is not None else '')
                                 msg=f"大单卖: 成交进度-{big_sell_info}" if big_sell_info is not None else '',
                                 is_force=is_force)
    # 计算观察索引,倒序计算
    # re_compute:是否是重新计算的
    # min_cancel_time_with_ms:最小撤单时间,大于等于此时间的撤单需要囊括进去
    def compute_watch_index(self, code, buy_single_index, start_index, end_index, re_compute=0,
                            min_cancel_time_with_ms=None, msg=""):
                            min_cancel_time_with_ms=None, msg="", is_force=False):
        try:
            l2_log.l_cancel_debug(code, f"计算L后囊括范围:{start_index}-{end_index}")
            total_datas = local_today_datas.get(code)
            if re_compute > 0 and tool.trade_time_sub(total_datas[-1]["val"]["time"],
            if not is_force and re_compute > 0 and tool.trade_time_sub(total_datas[-1]["val"]["time"],
                                                      total_datas[buy_single_index]["val"][
                                                          "time"]) < 2 * 60 and min_cancel_time_with_ms is None:
                # 封单额稳了以后,间隔超过2分钟才能重新计算
@@ -1523,7 +1525,7 @@
        """
        计算L后的已经撤单的比例
        @param code:
        @return: 比例, 已经撤单的索引
        @return: 比例, 已经撤单的索引, (前半段囊括的信息(索引, 手数), 前半段已撤的信息(索引,手数))
        """
        watch_indexes_info = self.__get_watch_indexes_cache(code)
        if not watch_indexes_info:
@@ -1582,7 +1584,7 @@
        watch_indexes_list.sort()
        canceled_num = 0
        # 记录撤单索引
        canceled_indexes = []
        canceled_data_indexes = []
        deal_order_nos = HuaXinBuyOrderManager().get_deal_buy_order_nos(code)
        if deal_order_nos is None:
@@ -1591,22 +1593,31 @@
        if is_default:
            trade_index = None
        canceled_buyno_map = local_today_canceled_buyno_map.get(code)
        # 真实下单位之前的手数
        before_nums_info = []
        before_canceled_nums_info = []
        for wi in watch_indexes:
            data = total_data[wi]
            val = data["val"]
            cancel_data = L2DataComputeUtil.is_canceled(code, wi, total_data, canceled_buyno_map, trade_index,
                                                        deal_order_nos)
            if cancel_data:
                if str(wi) in after_place_order_index_dict:
                    # 真实下单位置之后的按照权重比例来计算
                if cancel_data:
                    canceled_num += total_data[wi]["val"]["num"] * (
                            10 - after_place_order_index_dict[str(wi)]) // 10
                elif str(wi) in after_place_order_index_by_dict:
                if cancel_data:
                    canceled_num += total_data[wi]["val"]["num"] * (
                            10 - after_place_order_index_by_dict[str(wi)]) // 10
                else:
                before_nums_info.append((wi, val["num"]))
                if cancel_data:
                    before_canceled_nums_info.append((wi, val['num']))
                    canceled_num += total_data[wi]["val"]["num"]
                canceled_indexes.append(cancel_data["index"])
            canceled_data_indexes.append(cancel_data["index"])
        rate = round(canceled_num / total_num, 3)
        return rate, canceled_indexes
        return rate, canceled_data_indexes, (before_nums_info, before_canceled_nums_info)
    def __compute_need_cancel(self, code, buy_exec_index, start_index, end_index, total_data, is_first_code):
        """
@@ -2025,7 +2036,7 @@
        """
        统计L后监听数据信息
        @param code:
        @return:((总笔数, 总金额), (已撤笔数,已撤金额), (已成交笔数,已成交金额), 综合撤单比例, 撤单比例阈值)
        @return:((总笔数, 总金额), (已撤笔数,已撤金额), (已成交笔数,已成交金额), 综合撤单比例, 撤单比例阈值, (200w以下撤单百分数, 200-300W撤单百分数, 300w以上撤单百分数))
        """
        watch_indexes_info = self.__get_watch_indexes_cache(code)
        if not watch_indexes_info:
@@ -2073,8 +2084,38 @@
            fresults.append(100.00)
        else:
            rate_info = self.__compute_l_down_canceled_rate(code, total_datas)
            # 已撤比例
            fresults.append(round(rate_info[0]*100, 2))
            # 撤单比例阈值
        fresults.append(LCancelRateManager.get_cancel_rate(code)[0] * 100)
            before_watch_indexed_info, before_canceled_watch_indexes_info = rate_info[2][0], rate_info[2][1]
            canceled_indexes = set([x[0] for x in before_canceled_watch_indexes_info])
            # [累计手数,累计撤单手数]
            watch_index_info_less_of_200 = [0, 0]
            watch_index_info_200_to_300 = [0, 0]
            watch_index_info_more_than_300 = [0, 0]
            for x in before_watch_indexed_info:
                money = limit_up_price * x[1]
                if money >= 300 * 100:
                    watch_index_info_more_than_300[0] += x[1]
                    if x[0] in canceled_indexes:
                        watch_index_info_more_than_300[1] += x[1]
                elif money >= 200 * 100:
                    watch_index_info_200_to_300[0] += x[1]
                    if x[0] in canceled_indexes:
                        watch_index_info_200_to_300[1] += x[1]
                else:
                    watch_index_info_less_of_200[0] += x[1]
                    if x[0] in canceled_indexes:
                        watch_index_info_less_of_200[1] += x[1]
            fresults.append((
                round(watch_index_info_less_of_200[1] * 100 / max(watch_index_info_less_of_200[0], 1)),
                round(watch_index_info_200_to_300[1] * 100 / max(watch_index_info_200_to_300[0], 1)),
                round(watch_index_info_more_than_300[1] * 100 / max(watch_index_info_more_than_300[0], 1)),
            ))
        return fresults
trade/buy_radical/radical_buy_data_manager.py
@@ -2246,7 +2246,7 @@
    if result:
        try:
            buy_datas, sell_datas = result[0], result[1]
            # 获取原始均大单
            # 获取原始均大单,要求的累计大单成交额只和均大单有关
            THRESHOLD_MONEY, is_temp_threshold_money = BeforeSubDealBigOrderManager().get_big_order_threshold_info(
                code_)
            BeforeSubDealBigOrderManager().set_big_deal_order_list(code_, buy_datas, sell_datas,