Administrator
2024-03-19 8e8a2a2767e2784a6548cd07a2bf7dd6558e3f43
S撤实现
10个文件已修改
689 ■■■■ 已修改文件
inited_data.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/cancel_buy_strategy.py 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_manager.py 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_processor.py 71 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
log_module/log.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/l2_trade_test.py 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_server.py 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_result_manager.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/tool.py 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inited_data.py
@@ -12,7 +12,7 @@
from code_attribute.code_nature_analyse import LatestMaxVolumeManager, HighIncreaseCodeManager, CodeNatureRecordManager
from db.redis_manager_delegate import RedisUtils
from l2.l2_sell_manager import L2MarketSellManager
from l2.l2_transaction_data_manager import HuaXinTransactionDataManager
from l2.l2_transaction_data_manager import HuaXinBuyOrderManager
from ths import client_manager
import constant
from trade.deal_big_money_manager import DealOrderNoManager
@@ -213,7 +213,7 @@
# 保存运行时数据
def save_running_data():
    HuaXinTransactionDataManager().sync_dealing_data_to_db()
    HuaXinBuyOrderManager().sync_dealing_data_to_db()
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
l2/l2_data_manager_new.py
@@ -22,7 +22,7 @@
    trade_result_manager, current_price_process_manager, trade_data_manager, trade_huaxin, trade_record_log_util
from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \
    transaction_progress, cancel_buy_strategy, l2_data_log
from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \
from l2.cancel_buy_strategy import SCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \
    LCancelBigNumComputer, LatestCancelIndexManager, LCancelRateManager, GCancelBigNumComputer
from l2.l2_data_manager import L2DataException, OrderBeginPosInfo
from l2.l2_data_util import local_today_datas, L2DataUtil, local_today_num_operate_map, local_today_buyno_map, \
@@ -222,7 +222,7 @@
    __trade_log_placr_order_info_dict = {}  # 下单信息保存
    # 初始化
    __TradePointManager = l2_data_manager.TradePointManager()
    __SecondCancelBigNumComputer = SecondCancelBigNumComputer()
    __SCancelBigNumComputer = SCancelBigNumComputer()
    __HourCancelBigNumComputer = HourCancelBigNumComputer()
    __LCancelBigNumComputer = LCancelBigNumComputer()
    __GCancelBigNumComputer = GCancelBigNumComputer()
@@ -494,17 +494,11 @@
            _start_time = round(t.time() * 1000)
            # S撤单计算,看秒级大单撤单
            try:
                b_need_cancel, b_cancel_data = cls.__SecondCancelBigNumComputer.need_cancel(code, _buy_single_index,
                                                                                            _buy_exec_index,
                                                                                            start_index,
                                                                                            end_index, total_data,
                                                                                            code_volumn_manager.get_volume_rate_index(
                                                                                                buy_volume_rate),
                                                                                            cls.volume_rate_info[code][
                                                                                                1],
                                                                                            is_first_code)
                b_need_cancel, b_cancel_msg = cls.__SCancelBigNumComputer.need_cancel_for_down(code, start_index,end_index)
                if b_need_cancel:
                    return b_cancel_data, "S大单撤销比例触发阈值"
                    async_log_util.error(logger_debug, f"{code} S后撤单:{b_cancel_msg}")
                    # return total_data[end_index], f"S后撤({b_cancel_msg})"
                    return None, None
            except Exception as e:
                logging.exception(e)
                async_log_util.error(logger_l2_error,
l2/l2_transaction_data_manager.py
@@ -5,18 +5,20 @@
from db import redis_manager
from db.redis_manager_delegate import RedisUtils
from l2 import l2_log
from l2.huaxin import l2_huaxin_util
from log_module import async_log_util
from log_module.log import hx_logger_l2_transaction_desc
from log_module.log import hx_logger_l2_transaction_desc, hx_logger_l2_transaction_sell_order
from utils import tool
class HuaXinTransactionDataManager:
# 成交数据统计
class HuaXinBuyOrderManager:
    __db = 0
    __instance = None
    __redis_manager = redis_manager.RedisManager(0)
    # 正在成交的订单
    __dealing_order_info_dict = {}
@@ -25,7 +27,7 @@
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(HuaXinTransactionDataManager, cls).__new__(cls, *args, **kwargs)
            cls.__instance = super(HuaXinBuyOrderManager, cls).__new__(cls, *args, **kwargs)
            cls.__load_datas()
        return cls.__instance
@@ -82,3 +84,88 @@
        return None
# 卖单统计数据
class HuaXinSellOrderStatisticManager:
    # 最近的大卖单成交,格式:{code:[卖单信息,...]}
    __latest_sell_order_info_list_dict = {}
    # 大单卖单号的集合,格式:{code:{卖单号}}
    __big_sell_order_ids_dict = {}
    # 大卖单的卖单号->卖单信息映射
    __big_sell_order_info_dict = {}
    # 最近的卖单, 格式{code:[卖单号,总手数,价格,('开始时间',买单号),('结束时间',买单号)]}
    __latest_sell_order_dict = {}
    @classmethod
    def add_transaction_datas(cls, code, datas):
        # q.append((data['SecurityID'], data['TradePrice'], data['TradeVolume'],
        #           data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'],
        #           data['SellNo'], data['ExecType']))
        if code not in cls.__latest_sell_order_info_list_dict:
            cls.__latest_sell_order_info_list_dict[code] = []
        if code not in cls.__big_sell_order_ids_dict:
            cls.__big_sell_order_ids_dict[code] = set()
        if code not in cls.__big_sell_order_info_dict:
            cls.__big_sell_order_info_dict[code] = {}
        for d in datas:
            cls.__latest_sell_order_info_list_dict[code].append(d)
            if code not in cls.__latest_sell_order_dict:
                cls.__latest_sell_order_dict[code] = [d[7], d[2], d[1], (d[3], d[6]), (d[3], d[6])]
            else:
                if cls.__latest_sell_order_dict[code][0] == d[7]:
                    cls.__latest_sell_order_dict[code][1] += d[2]
                    cls.__latest_sell_order_dict[code][2] = d[1]
                    cls.__latest_sell_order_dict[code][4] = (d[3], d[6])
                else:
                    # 封存数据,计算新起点
                    l2_log.info(code, hx_logger_l2_transaction_sell_order, f"{cls.__latest_sell_order_dict[code]}")
                    # 大于50w加入卖单
                    info = cls.__latest_sell_order_dict[code]
                    if info[1] * info[2] >= 500000:
                        cls.__big_sell_order_ids_dict[code].add(info[0])
                        cls.__big_sell_order_info_dict[code][info[0]] = info
                    cls.__latest_sell_order_dict[code] = [d[7], d[2], d[1], (d[3], d[6]), (d[3], d[6])]
        latest_time = l2_huaxin_util.convert_time(datas[-1][3], with_ms=True)
        min_time = tool.trade_time_add_millionsecond(latest_time, -1000)
        min_time_int = int(min_time.replace(":", "").replace(".", ""))
        # 计算最近1s的大单成交
        total_datas = cls.__latest_sell_order_info_list_dict.get(code)
        start_index = 0
        total_sell_info = [0, None]  # 总资金,开始成交信息,结束成交信息
        latest_sell_order_info = cls.__latest_sell_order_dict[code]
        big_sell_order_ids = cls.__big_sell_order_ids_dict[code]
        # print("大卖单", big_sell_order_ids)
        big_sell_orders = []
        temp_sell_order_ids = set()
        for i in range(len(datas) - 1, -1, -1):
            d = datas[i]
            if d[7] != latest_sell_order_info[0]:
                # 不是最近的成交且不是大单直接过滤
                if d[7] not in big_sell_order_ids:
                    continue
                else:
                    if d[7] not in temp_sell_order_ids:
                        big_sell_orders.append(cls.__big_sell_order_info_dict[code].get(d[7]))
                        temp_sell_order_ids.add(d[7])
            else:
                # 是最近的但不是大单需要过滤
                if latest_sell_order_info[1] * latest_sell_order_info[2] < 500000:
                    continue
                else:
                    if latest_sell_order_info[0] not in temp_sell_order_ids:
                        big_sell_orders.append(latest_sell_order_info)
                        temp_sell_order_ids.add(latest_sell_order_info[0])
            if min_time_int > int(l2_huaxin_util.convert_time(d[3], with_ms=True).replace(":", "").replace(".", "")):
                start_index = i
                break
            # 统计最近1s的大卖单数据
            total_sell_info[0] += int(d[1] * d[2])
        big_sell_orders.reverse()
        total_sell_info[1] = big_sell_orders
        cls.__latest_sell_order_info_list_dict[code] = cls.__latest_sell_order_info_list_dict[code][start_index:]
        return total_sell_info
l2/l2_transaction_data_processor.py
@@ -1,19 +1,17 @@
import logging
import time
from code_attribute import gpcode_manager
from l2 import l2_data_util, l2_data_manager, l2_data_source_util, transaction_progress
from l2 import l2_data_util, l2_data_manager, transaction_progress
from l2.cancel_buy_strategy import FCancelBigNumComputer, LCancelBigNumComputer, LCancelRateManager, \
    GCancelBigNumComputer, SecondCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer
    GCancelBigNumComputer, SCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer
from l2.l2_data_manager_new import L2TradeDataProcessor
from l2.l2_data_util import L2DataUtil, local_today_canceled_buyno_map
from l2.l2_transaction_data_manager import HuaXinTransactionDataManager
from l2.l2_data_util import L2DataUtil
from l2.l2_transaction_data_manager import HuaXinBuyOrderManager, HuaXinSellOrderStatisticManager
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
from msg import push_msg_manager, buy_order_msg_manager
from msg import buy_order_msg_manager
from trade import current_price_process_manager, trade_manager
from trade.deal_big_money_manager import DealOrderNoManager
from utils import tool
class HuaXinTransactionDatasProcessor:
@@ -69,6 +67,18 @@
                        order_begin_pos = None
                except Exception as e:
                    async_log_util.error(hx_logger_l2_debug, str(e))
            try:
                # 统计卖单
                big_sell_order_info = HuaXinSellOrderStatisticManager.add_transaction_datas(code, datas)
                need_cancel, cancel_msg = SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code,
                                                                                                     big_sell_order_info,
                                                                                                     order_begin_pos)
                if need_cancel:
                    async_log_util.error(logger_debug, f"{code} S前撤单:{cancel_msg}")
                    # L2TradeDataProcessor.cancel_buy(code, f"S后撤:{cancel_msg}")
            except Exception as e:
                async_log_util.error(logger_debug, f"卖单统计异常:{str(e)}")
            # 计算已经成交的大单
            big_money_count = 0
@@ -78,7 +88,7 @@
                if data:
                    buy_num = data["val"]["num"] * 100
                # 统计成交单
                deal_info = HuaXinTransactionDataManager.statistic_deal_desc(code, d, buy_num)
                deal_info = HuaXinBuyOrderManager.statistic_deal_desc(code, d, buy_num)
                if deal_info and deal_info[1]:
                    data = buyno_map.get(f"{deal_info[0]}")
                    print("已经成交索引:", data["index"])
@@ -104,9 +114,6 @@
                LCancelBigNumComputer().set_trade_progress(code, order_begin_pos.buy_single_index, buy_progress_index,
                                                           total_datas)
                SecondCancelBigNumComputer().set_transaction_index(
                    code,
                    buy_progress_index)
                if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1:
                    HourCancelBigNumComputer().set_transaction_index(code, order_begin_pos.buy_single_index,
                                                                     buy_progress_index)
@@ -114,36 +121,24 @@
                    # if cresult[0] and not DCancelBigNumComputer().has_auto_cancel_rules(code):
                    #     L2TradeDataProcessor.cancel_buy(code, f"下单30s内排单不足:{cresult[1]}")
                    cresult = FCancelBigNumComputer().need_cancel_for_deal_fast_with_total_sell(code, buy_progress_index, order_begin_pos)
                    cresult = FCancelBigNumComputer().need_cancel_for_deal_fast_with_total_sell(code,
                                                                                                buy_progress_index,
                                                                                                order_begin_pos)
                    if cresult[0] and not DCancelBigNumComputer().has_auto_cancel_rules(code):
                        L2TradeDataProcessor.cancel_buy(code, f"3s内成交太多:{cresult[1]}")
                    # ---------------------------------判断板块是否跟上来了-------------------------------
                    try:
                        pass
                        # order_begin_pos = l2_data_manager.TradePointManager().get_buy_compute_start_data_cache(code)
                        # volume_rate = 0
                        # volume_info = L2TradeDataProcessor.volume_rate_info.get(code)
                        # if volume_info:
                        #     volume_rate = volume_info[0]
                        # need_cancel, msg = UCancelBigNumComputer().need_cancel(code, buy_progress_index, order_begin_pos,
                        #                                                        kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reason_codes_dict(),
                        #                                                        volume_rate)
                        # if need_cancel:
                        #     L2TradeDataProcessor.cancel_buy(code, msg)
                    except Exception as e:
                        logger_debug.exception(e)
                    if buy_progress_index_changed:
                        # 交易进度变化,判断到真实下单位置的距离
                        real_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code)
                        if real_order_index and real_order_index >= buy_progress_index:
                            # 发送下单消息
                            try:
                                buy_order_msg_manager.almost_deal(code, real_order_index, buy_progress_index)
                                buy_order_msg_manager.follow_not_enough(code, order_begin_pos.buy_exec_index,
                                                                        real_order_index)
                            except Exception as e:
                                logger_debug.exception(e)
                    # ---------------------------------成交进度位变化-------------------------------
                    # if buy_progress_index_changed:
                    #     # 交易进度变化,判断到真实下单位置的距离
                    #     real_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                    #     if real_order_index and real_order_index >= buy_progress_index:
                    #         # 发送下单消息
                    #         try:
                    #             buy_order_msg_manager.almost_deal(code, real_order_index, buy_progress_index)
                    #             buy_order_msg_manager.follow_not_enough(code, order_begin_pos.buy_exec_index,
                    #                                                     real_order_index)
                    #         except Exception as e:
                    #             logger_debug.exception(e)
            else:
                pass
            if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1:
log_module/log.py
@@ -218,6 +218,11 @@
        logger.add(self.get_hx_path("l2", "transaction"),
                   filter=lambda record: record["extra"].get("name") == "hx_l2_transaction",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(self.get_hx_path("l2", "transaction_sell_order"),
                   filter=lambda record: record["extra"].get("name") == "hx_l2_transaction_sell_order",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(self.get_hx_path("l2", "transaction_desc"),
                   filter=lambda record: record["extra"].get("name") == "hx_l2_transaction_desc",
                   rotation="00:00", compression="zip", enqueue=True)
@@ -397,6 +402,7 @@
# -------------------------------华鑫日志---------------------------------
hx_logger_l2_orderdetail = __mylogger.get_logger("hx_l2_orderdetail")
hx_logger_l2_transaction = __mylogger.get_logger("hx_l2_transaction")
hx_logger_l2_transaction_sell_order = __mylogger.get_logger("hx_l2_transaction_sell_order")
hx_logger_l2_transaction_desc = __mylogger.get_logger("hx_l2_transaction_desc")
hx_logger_l2_market_data = __mylogger.get_logger("hx_l2_market_data")
hx_logger_l2_upload = __mylogger.get_logger("hx_l2_upload")
test/l2_trade_test.py
@@ -23,7 +23,7 @@
from third_data import kpl_util, kpl_data_manager, block_info
from third_data.code_plate_key_manager import LimitUpCodesPlateKeyManager, CodePlateKeyBuyManager
from third_data.kpl_data_manager import KPLDataManager
from trade import trade_data_manager, current_price_process_manager, l2_trade_util, trade_manager
from trade import trade_data_manager, current_price_process_manager, l2_trade_util, trade_manager, l2_trade_factor
import l2.l2_data_manager_new, l2.l2_data_manager, l2.l2_data_util, l2.cancel_buy_strategy
@@ -137,7 +137,7 @@
        # hook
        tool.get_now_time_str = mock.Mock(return_value="09:35:00")
        CodePlateKeyBuyManager.can_buy = mock.Mock(return_value=(["测试"], False, "",[]))
        CodePlateKeyBuyManager.can_buy = mock.Mock(return_value=(["测试"], False, "", []))
        # 获取交易进度
        trade_progress_list, buy_queues = log_export.get_trade_progress(code)
@@ -202,13 +202,24 @@
            l2.l2_data_manager_new.L2TradeDataProcessor.process_add_datas(code, total_datas[indexs[0]:indexs[1] + 1], 0,
                                                                          0)
    @unittest.skip("跳过此单元测试")
    def test_place_order(self):
        code = "002241"
    def test_s_cancel(self):
        code = "603363"
        l2.l2_data_util.load_l2_data(code)
        total_datas = deepcopy(l2.l2_data_util.local_today_datas[code])
        huaxin_delegate_postion_manager.place_order(code, 17.36, 100, total_datas[753])
        huaxin_delegate_postion_manager.get_l2_place_order_position(code, total_datas[755:1038])
        l2.l2_data_util.local_today_datas[code] = l2.l2_data_util.local_today_datas[code][:222]
        l2.cancel_buy_strategy.SCancelBigNumComputer().set_real_place_order_index(code, 153)
        TradeBuyQueue.get_traded_index = mock.Mock(return_value=(117, False))
        order_begin_pos = l2_data_manager.OrderBeginPosInfo(buy_single_index=117, buy_exec_index=122)
        sell_order_info = [1517999, [[2996226, 300000, 5.06, (10223471, 4876395), (10223471, 4876395)]]]
        l2.cancel_buy_strategy.SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, sell_order_info,
                                                                                          order_begin_pos)
        sell_order_info = [508507, [[5564445, 100100, 5.08, (10372994, 4876545), (10372994, 4876546)]]]
        l2.cancel_buy_strategy.SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, sell_order_info,
                                                                                          order_begin_pos)
        l2.cancel_buy_strategy.SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, sell_order_info,
                                                                                          order_begin_pos)
        l2.cancel_buy_strategy.SCancelBigNumComputer().need_cancel_for_down(code, 154, 222)
    @unittest.skip("跳过此单元测试")
    def test_h_cancel(self):
trade/huaxin/huaxin_trade_server.py
@@ -31,7 +31,7 @@
from huaxin_client.trade_transform_protocol import TradeResponse
from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, l2_data_manager, transaction_progress, \
    l2_data_source_util, cancel_buy_strategy
from l2.cancel_buy_strategy import LCancelBigNumComputer, GCancelBigNumComputer, SecondCancelBigNumComputer, \
from l2.cancel_buy_strategy import LCancelBigNumComputer, GCancelBigNumComputer, SCancelBigNumComputer, \
    LCancelRateManager, DCancelBigNumComputer
from l2.code_price_manager import Buy1PriceManager
from l2.huaxin import huaxin_target_codes_manager
@@ -39,7 +39,7 @@
from l2.l2_data_manager import TradePointManager
from l2.l2_data_util import L2DataUtil
from l2.l2_sell_manager import L2MarketSellManager
from l2.l2_transaction_data_manager import HuaXinTransactionDataManager
from l2.l2_transaction_data_manager import HuaXinBuyOrderManager
from l2.l2_transaction_data_processor import HuaXinTransactionDatasProcessor
from log_module import async_log_util, log_export
from log_module.log import hx_logger_contact_debug, hx_logger_trade_callback, \
@@ -576,7 +576,7 @@
                    continue
                trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code)
                # 下单位置
                place_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code)
                place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                # 获取剩下的笔数
                total_left_num = 0
@@ -1130,7 +1130,7 @@
            trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code)
            trade_speed = transaction_progress.TradeBuyQueue().get_trade_speed(code)
            # 下单位置
            place_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code)
            place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
            fdata = {}
            if trade_index and place_order_index:
                # 有成交进度位与下单位
@@ -1386,7 +1386,7 @@
                            if trade_index is None:
                                trade_index = 0
                            # 下单位置
                            place_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code)
                            place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                            # 计算信号位置到真实下单位置的总买(不管是否已撤)
                            total_nums = 0
                            for i in range(order_begin_pos.buy_single_index, place_order_index):
@@ -1423,7 +1423,7 @@
                                    total_left_count += left_count
                                    total_left_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_left_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100)
trade/trade_result_manager.py
@@ -3,7 +3,7 @@
from code_attribute.gpcode_manager import MustBuyCodesManager
from l2 import l2_data_manager
from l2.cancel_buy_strategy import HourCancelBigNumComputer, SecondCancelBigNumComputer, \
from l2.cancel_buy_strategy import HourCancelBigNumComputer, SCancelBigNumComputer, \
    LCancelBigNumComputer, DCancelBigNumComputer, GCancelBigNumComputer, FCancelBigNumComputer
from l2.l2_data_manager import OrderBeginPosInfo
from l2.l2_data_util import local_today_datas, local_today_num_operate_map, L2DataUtil
@@ -28,7 +28,7 @@
# 虚拟撤成功
def virtual_cancel_success(code, buy_single_index, buy_exec_index, total_datas):
    l2_data_manager.TradePointManager().delete_buy_point(code)
    SecondCancelBigNumComputer().cancel_success(code)
    SCancelBigNumComputer().cancel_success(code)
    LCancelBigNumComputer().cancel_success(code)
    GCancelBigNumComputer().cancel_success(code)
    # dask.compute(f1, f2, f5, f6, f7, f8)
@@ -57,7 +57,7 @@
    def s_cancel(code):
        try:
            SecondCancelBigNumComputer().place_order_success(code)
            SCancelBigNumComputer().place_order_success(code)
        except Exception as e:
            logging.exception(e)
            logger_l2_error.exception(e)
@@ -102,7 +102,7 @@
def real_cancel_success(code, buy_single_index, buy_exec_index, total_datas):
    # 取消买入标识
    l2_data_manager.TradePointManager().delete_buy_point(code)
    SecondCancelBigNumComputer().cancel_success(code)
    SCancelBigNumComputer().cancel_success(code)
    LCancelBigNumComputer().cancel_success(code)
    FCancelBigNumComputer().cancel_success(code)
    GCancelBigNumComputer().cancel_success(code)
utils/tool.py
@@ -156,12 +156,27 @@
    return int(ts[0]) * 3600 + int(ts[1]) * 60 + int(ts[2])
def get_time_as_millionsecond(time_str):
    s_str,ms_str = time_str.split(".")
    ts = s_str.split(":")
    return int(ts[0]) * 3600 + int(ts[1]) * 60 + int(ts[2])*1000 + int(ms_str)
# 将秒数格式化为时间
def time_seconds_format(seconds):
    h = seconds // 3600
    m = seconds % 3600 // 60
    s = seconds % 60
    return "{0:0>2}:{1:0>2}:{2:0>2}".format(h, m, s)
def time_millionseconds_format(millionseconds):
    ms = millionseconds % 1000
    seconds = millionseconds // 1000
    h = seconds // 3600
    m = seconds % 3600 // 60
    s = seconds % 60
    return "{0:0>2}:{1:0>2}:{2:0>2}.{3:0>3}".format(h, m, s, ms)
# 交易時間的差值
@@ -174,6 +189,17 @@
        time_2 = time_2 - 90 * 60
    elif time_2 < split_time < time_1:
        time_2 = time_2 + 90 * 60
    return time_1 - time_2
def trade_time_sub_with_ms(time_str_1, time_str_2):
    split_time = get_time_as_second("11:30:00")*1000
    time_1 = get_time_as_millionsecond(time_str_1)
    time_2 = get_time_as_millionsecond(time_str_2)
    if time_1 < split_time < time_2:
        time_2 = time_2 - 90 * 60*1000
    elif time_2 < split_time < time_1:
        time_2 = time_2 + 90 * 60*1000
    return time_1 - time_2
@@ -191,6 +217,19 @@
    if s >= 11 * 3600 + 30 * 60 > s_:
        s += 90 * 60
    return time_seconds_format(s)
def trade_time_add_millionsecond(time_str, millionsecond):
    s_str, ms_str = time_str.split(".")
    ts = s_str.split(":")
    s_ = int(ts[0]) * 3600 + int(ts[1]) * 60 + int(ts[2])
    ms_ = s_ * 1000
    ms_ += int(ms_str)
    ms = ms_ + millionsecond
    # 是否在11:30:00
    if ms >= 11 * 3600 * 1000 + 30 * 60 * 1000 > ms_:
        ms += 90 * 60 * 1000
    return time_millionseconds_format(ms)
def compute_buy1_real_time(time_):
@@ -282,3 +321,8 @@
    if count < 100:
        count = 100
    return count
if __name__ == "__main__":
    print(trade_time_add_millionsecond("10:36:00.123", 1000))
    print(trade_time_add_millionsecond("11:29:59.123", 1888))