Administrator
2024-11-22 746d76e4320913a5b1dcf41b6234fa58b3726de7
扫入增加大单撤
13个文件已修改
416 ■■■■■ 已修改文件
code_attribute/code_volumn_manager.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
db/redis_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client_test.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/cancel_buy_strategy.py 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_manager.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_processor.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
servers/huaxin_trade_server.py 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/buy_radical/block_special_codes_manager.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/buy_radical/radical_buy_data_manager.py 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/buy_radical/radical_buy_strategy.py 108 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_constant.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_data_manager.py 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_attribute/code_volumn_manager.py
@@ -79,9 +79,10 @@
    def get_max_volume_in_5days(self, code):
        return self.__max_volume_in_5days.get(code)
    def get_volume_rate_refer_in_5days(self, code):
    def get_volume_rate_refer_in_5days(self, code, total_sell_volume=0):
        """
        获取今日量与5日最大量的参考值
        @param total_sell_volume: 当前总卖量
        @param code:
        @return:
        """
@@ -89,7 +90,7 @@
        if not max_volume:
            return 0
        today_volume = self.get_today_volumn(code)
        return round(today_volume / max_volume, 2)
        return round((today_volume + total_sell_volume) / max_volume, 2)
    # 获取历史量
    def get_histry_volumn(self, code):
db/redis_manager.py
@@ -166,7 +166,7 @@
            except Exception as e1:
                logging.exception(e1)
                pass
                time.sleep(1)
if __name__ == "__main__":
huaxin_client/l2_client_test.py
@@ -32,7 +32,7 @@
g_SubBondMarketData = False
g_SubBondTransaction = False
g_SubBondOrderDetail = False
set_codes_data_queue = queue.Queue()
set_codes_data_queue = queue.Queue(maxsize=10240)
market_code_dict = {}
ENABLE_NGST = True
@@ -45,8 +45,8 @@
        self.__big_buy_orders = []
        self.__latest_sell_order = None
        self.__big_sell_orders = []
        self.big_buy_order_queue = queue.Queue()
        self.big_sell_order_queue = queue.Queue()
        self.big_buy_order_queue = queue.Queue(maxsize=10240)
        self.big_sell_order_queue = queue.Queue(maxsize=10240)
    def get_big_buy_orders(self):
        return self.__big_buy_orders
l2/cancel_buy_strategy.py
@@ -215,6 +215,80 @@
        self.__clear_data(code)
# ---------------------------------RD撤-------------------------------
# 扫入下单大单撤
class RDCancelBigNumComputer:
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __instance = None
    # 下单位之后的封单中的大单
    __watch_indexes_cache = {}
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(RDCancelBigNumComputer, cls).__new__(cls, *args, **kwargs)
            cls.__load_datas()
        return cls.__instance
    @classmethod
    def __get_redis(cls):
        return cls.__redis_manager.getRedis()
    @classmethod
    def __load_datas(cls):
        keys = RedisUtils.keys(cls.__get_redis(), "radical_big_order_watch-*")
        for k in keys:
            code = k.split("-")[1]
            val = RedisUtils.get(cls.__get_redis(), k)
            val = json.loads(val)
            cls.__watch_indexes_cache[code] = set(val)
    def set_watch_indexes(self, code, indexes):
        l2_log.d_cancel_debug(code, f"扫入大单监听:{indexes}")
        self.__watch_indexes_cache[code] = set(indexes)
        RedisUtils.setex_async(self.__db, f"radical_big_order_watch-{code}", tool.get_expire(),
                               json.dumps(list(indexes)))
    def need_cancel(self, code, start_index, end_index):
        """
        是否需要撤单
        @param code:
        @param start_index:
        @param end_index:
        @return: 是否需要撤单,撤单索引, 消息
        """
        watch_indexes = self.__watch_indexes_cache.get(code)
        if not watch_indexes:
            return False,None,  "无大单监听"
        total_datas = local_today_datas.get(code)
        for i in range(start_index, end_index + 1):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy_cancel(val):
                continue
            if val["num"] * float(val["price"]) < 5000:
                continue
            buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data,
                                                                                                local_today_buyno_map.get(
                                                                                                    code))
            if buy_index is None:
                continue
            if buy_index in watch_indexes:
                return True, data, f"大单撤单({buy_index})"
        return False,None, "无大单撤单"
    def __clear_data(self, code):
        if code in self.__watch_indexes_cache:
            self.__watch_indexes_cache.pop(code)
            RedisUtils.delete_async(self.__db, f"radical_big_order_watch-{code}")
    def clear_data(self, code):
        self.__clear_data(code)
# 新F撤,根据成交数据来撤
class FCancelBigNumComputer:
    __db = 0
l2/l2_data_manager_new.py
@@ -30,7 +30,7 @@
    transaction_progress, cancel_buy_strategy, place_order_single_data_manager
from l2.cancel_buy_strategy import DCancelBigNumComputer, \
    LatestCancelIndexManager, \
    NewGCancelBigNumComputer, JCancelBigNumComputer, L2DataComputeUtil
    NewGCancelBigNumComputer, JCancelBigNumComputer, L2DataComputeUtil, RDCancelBigNumComputer
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, \
    local_latest_datas, local_today_canceled_buyno_map, local_today_sellno_map
@@ -703,6 +703,18 @@
                                     f"J撤出错 参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} 错误原因:{str(e)}")
            return None, ""
        # RD撤
        def rd_cancel(_buy_single_index, _buy_exec_index):
            try:
                b_need_cancel, b_cancel_data, extra_msg = RDCancelBigNumComputer().need_cancel(code, start_index,
                                                                                               end_index)
                if b_need_cancel and b_cancel_data:
                    return b_cancel_data, f"RD撤({extra_msg})", trade_constant.CANCEL_TYPE_RD
            except Exception as e:
                async_log_util.error(logger_l2_error,
                                     f"RD撤出错 参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} 错误原因:{str(e)}")
            return None, "", trade_constant.CANCEL_TYPE_RD
        if start_index < 0:
            start_index = 0
@@ -717,24 +729,35 @@
        if order_begin_pos.buy_volume_rate is None:
            order_begin_pos.buy_volume_rate = 0.2
        cancel_data, cancel_msg, cancel_type = None, "", None
        if not cancel_data:
            cancel_data, cancel_msg = g_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
            cancel_type = trade_constant.CANCEL_TYPE_G
        # 依次处理
        if not cancel_data:
            cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index,
                                                            order_begin_pos.buy_exec_index)
        # B撤
        if not cancel_data:
            cancel_data, cancel_msg = b_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
            cancel_type = trade_constant.CANCEL_TYPE_G
        if not cancel_data:
            cancel_data, cancel_msg = h_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
            cancel_type = trade_constant.CANCEL_TYPE_H
        # J撤
        if not cancel_data:
            cancel_data, cancel_msg = j_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
            cancel_type = trade_constant.CANCEL_TYPE_J
        if order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL:
            if not cancel_data:
                cancel_data, cancel_msg, cancel_type = rd_cancel(order_begin_pos.buy_single_index,
                                                                 order_begin_pos.buy_exec_index)
            # 扫入下单只有L撤
            if not cancel_data:
                cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index,
                                                                order_begin_pos.buy_exec_index)
        else:
            if not cancel_data:
                cancel_data, cancel_msg = g_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
                cancel_type = trade_constant.CANCEL_TYPE_G
            # 依次处理
            if not cancel_data:
                cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index,
                                                                order_begin_pos.buy_exec_index)
            # B撤
            if not cancel_data:
                cancel_data, cancel_msg = b_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
                cancel_type = trade_constant.CANCEL_TYPE_G
            if not cancel_data:
                cancel_data, cancel_msg = h_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
                cancel_type = trade_constant.CANCEL_TYPE_H
            # J撤
            if not cancel_data:
                cancel_data, cancel_msg = j_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
                cancel_type = trade_constant.CANCEL_TYPE_J
        if cancel_data and not DCancelBigNumComputer().has_auto_cancel_rules(code):
            l2_log.debug(code, "触发撤单,撤单位置:{} ,撤单原因:{}", cancel_data["index"], cancel_msg)
@@ -830,6 +853,8 @@
        l2_log.debug(code, "处理买入成功2")
        params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc()
        l2_log.debug(code, params_desc)
        #################清除本次下单的大单数据###############
        EveryLimitupBigDealOrderManager.clear(code)
        ############记录下单时的数据############
        try:
            jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache(
@@ -891,7 +916,7 @@
                can, need_clear_data, reason, is_valid_exec_index = True, False, "扫入下单", True
            else:
                return False
                #can, need_clear_data, reason, is_valid_exec_index = cls.__can_buy_first(code)
                # can, need_clear_data, reason, is_valid_exec_index = cls.__can_buy_first(code)
            # 删除虚拟下单
            if code in cls.unreal_buy_dict:
@@ -1466,7 +1491,7 @@
            # 是否是交易队列触发
            # 扫入下单只有L撤能撤单
            if order_begin_pos and order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL and cancel_type not in {
                trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L}:
                trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD}:
                l2_log.cancel_debug(code, "撤单中断,原因:{}", "扫入下单不是L撤")
                return False
            # 加绿只有L撤/人撤生效
@@ -1620,9 +1645,12 @@
                                                         block_info=radical_result[3])
            if ordered:
                radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, radical_result[2])
                # 监听大单
                RDCancelBigNumComputer().set_watch_indexes(code, radical_result[4])
            return
        if RadicalBuyDealCodesManager.radical_buy_blocks_dict.get(code):
        if RadicalBuyDealCodesManager().get_code_blocks(code):
            # 已经扫入下过单
            return
        if not constant.CAN_COMMON_BUY:
@@ -2034,7 +2062,7 @@
        @param code:
        @param start_index:
        @param end_index:
        @return: (是否获取到信号, 信号位置, 扫入板块/消息, 扫入板块大单流入信息)
        @return: (是否获取到信号, 信号位置, 扫入板块/消息, 扫入板块大单流入信息, 需要监听的大单)
        """
        # 激进买信号的时间
@@ -2042,7 +2070,7 @@
        def __can_order():
            # 判断是否是板上放量
            if cls.__is_at_limit_up_buy(code, start_index):
                return False, None, "板上放量"
                return False, None, "板上放量", None
            total_datas = local_today_datas[code]
            limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
            bigger_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code))
@@ -2051,7 +2079,14 @@
            if constant.CAN_RADICAL_BUY_NEED_BIG_ORDER_EVERYTIME:
                # 每次下单都需要大单
                total_deal_money = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money(code)
                current_big_order_deal_money_info = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money_info(
                    code)
                if current_big_order_deal_money_info:
                    total_deal_money = current_big_order_deal_money_info[0]
                if current_big_order_deal_money_info and tool.trade_time_sub(tool.get_now_time_str(),
                                                                             current_big_order_deal_money_info[1]) > 60:
                    # 60s以上的大单不看
                    total_deal_money = 0
            else:
                # 只需要总成交的大单
                total_deal_money = BigOrderDealManager().get_total_buy_money(code)
@@ -2067,7 +2102,8 @@
                THRESHOLD_MONEY = 2990000
            if total_deal_money >= THRESHOLD_MONEY:
                min_num = int(5000 / limit_up_price)
            # 需要监听的大单
            watch_indexes = set()
            # 总委托大单金额
            total_delegating_big_money = 0
            single_index = None
@@ -2086,6 +2122,7 @@
                        order_money = dealing_active_order_info[2] + round(val["price"], 2) * val["num"] * 100
                        if order_money >= bigger_money:
                            total_delegating_big_money += order_money
                            watch_indexes.add(i)
                            if total_delegating_big_money + total_deal_money >= THRESHOLD_MONEY:
                                single_index = i
                                break
@@ -2093,14 +2130,14 @@
                if int(val["orderNo"]) <= radical_data[1]:
                    # 主动买单后的数据不算
                    continue
                watch_indexes.add(i)
                total_delegating_big_money += round(val["price"], 2) * val["num"] * 100
                if total_delegating_big_money + total_deal_money >= THRESHOLD_MONEY:
                    single_index = i
                    break
            if single_index is not None:
                return True, single_index, "有大单"
            return False, None, "无大单"
                return True, single_index, "有大单", watch_indexes
            return False, None, "无大单", watch_indexes
        radical_data = RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.get(code)
        record_codes = radical_buy_data_manager.BlockPlaceOrderRecordManager().get_codes()
@@ -2144,7 +2181,7 @@
            # 如果板上放量不可买入就需要删除信号
            if not constant.CAN_RADICAL_BUY_AT_LIMIT_UP and code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict:
                RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.pop(code)
            return True, result[1], radical_data[2], radical_data[3]
            return True, result[1], radical_data[2], radical_data[3], result[3]
        return result
    @classmethod
l2/l2_transaction_data_manager.py
@@ -202,8 +202,8 @@
            #                   data['SellNo'], data['ExecType']))
            if code not in cls.__dealing_order_info_dict:
                # 数据格式[订单号,总股数,成交金额,成交开始时间,成交结束时间, 最近的成交价格]
                cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], data[1]]
                # 数据格式[订单号,总股数,成交金额,成交开始时间,成交结束时间, 最近的成交价格, 最近的卖单号]
                cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], data[1], data[7]]
            else:
                if cls.__dealing_order_info_dict[code][0] == data[6]:
                    # 成交同一个订单号
@@ -211,6 +211,7 @@
                    cls.__dealing_order_info_dict[code][2] += data[2] * data[1]
                    cls.__dealing_order_info_dict[code][4] = data[3]
                    cls.__dealing_order_info_dict[code][5] = data[1]
                    cls.__dealing_order_info_dict[code][6] = data[7]
                else:
                    # 保存上一条数据
                    async_log_util.info(hx_logger_l2_transaction_desc, f"{code}#{cls.__dealing_order_info_dict[code]}")
@@ -227,7 +228,7 @@
                    # 初始化本条数据
                    cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3],
                                                           data[1]]
                                                           data[1], data[7]]
            # 统计主动买(买单号大于卖单号)
            try:
                if data[6] > data[7]:
l2/l2_transaction_data_processor.py
@@ -55,7 +55,13 @@
        buy_datas, bigger_buy_datas = HuaXinBuyOrderManager.statistic_big_buy_data(code, datas, limit_up_price)
        if buy_datas:
            BigOrderDealManager().add_buy_datas(code, buy_datas)
            EveryLimitupBigDealOrderManager.add_big_buy_order_deal(code, [(x[0], x[2]) for x in buy_datas])
            active_big_buy_orders = []
            if buy_datas:
                for x in buy_datas:
                    if x[0] > x[6]:
                        # (买单号, 成交金额, 最后成交时间)
                        active_big_buy_orders.append((x[0], x[2], x[4]))
            EveryLimitupBigDealOrderManager.add_big_buy_order_deal(code, active_big_buy_orders)
        try:
            is_placed_order = l2_data_manager.TradePointManager.is_placed_order(order_begin_pos)
            if is_placed_order:
servers/huaxin_trade_server.py
@@ -24,7 +24,7 @@
from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, transaction_progress, \
    l2_data_source_util, l2_data_log
from l2.cancel_buy_strategy import GCancelBigNumComputer, \
    DCancelBigNumComputer
    DCancelBigNumComputer, RDCancelBigNumComputer
from l2.code_price_manager import Buy1PriceManager
from l2.huaxin import huaxin_target_codes_manager, l2_huaxin_util
from l2.huaxin.huaxin_target_codes_manager import HuaXinL1TargetCodesManager
@@ -51,7 +51,8 @@
from api.outside_api_command_callback import OutsideApiCommandCallback
from trade.huaxin.huaxin_trade_record_manager import DelegateRecordManager
from trade.order_statistic import DealAndDelegateWithBuyModeDataManager
from trade.buy_radical.radical_buy_data_manager import RadicalBuyDataManager, RadicalBuyBlockManager
from trade.buy_radical.radical_buy_data_manager import RadicalBuyDataManager, RadicalBuyBlockManager, \
    EveryLimitupBigDealOrderManager
from trade.sell.sell_rule_manager import TradeRuleManager
from trade.trade_data_manager import RadicalBuyDealCodesManager
from trade.trade_manager import CodesTradeStateManager
@@ -691,17 +692,21 @@
        except Exception as e:
            logger_debug.exception(e)
    def OnLimitUpActiveBuy(self, code, transaction_datas):
    def __process_limit_up_active_buy(self, code, transaction_datas):
        """
        处理涨停主动买
        @param code:
        @param transaction_datas:
        @return: 是否清除本次上板数据
        """
        __start_time = time.time()
        try:
            # 判断是否处于可下单状态
            state = CodesTradeStateManager().get_trade_state_cache(code)
            if not trade_util.is_can_order_by_state(state):
                # 不处于可下单状态
                return
                return True
            # 判断最近60个交易日有无涨停
            # 判断昨日是否涨停过
            async_log_util.info(logger_l2_radical_buy, f"涨停主动买:{code}-{transaction_datas[-1]}")
            deal_codes = RadicalBuyDealCodesManager().get_deal_codes()
            # 判断今日扫入的代码数量是否大于阈值
@@ -709,10 +714,11 @@
            MAX_COUNT = 4 if radical_buy_setting is None else radical_buy_setting[0]
            if len(deal_codes) >= MAX_COUNT:
                async_log_util.info(logger_l2_radical_buy, f"扫入成交代码个数大于{MAX_COUNT}个:{code}-{deal_codes}")
                return
                return True
            if code in deal_codes:
                async_log_util.info(logger_l2_radical_buy, f"该代码已经成交:{code}")
                return
                return True
            # 单票是否可买
            can_buy_result = RadicalBuyDataManager.is_code_can_buy(code)
@@ -729,7 +735,7 @@
                    async_log_util.info(logger_l2_radical_buy, f"计算板块结果:{code}-{radical_result}")
                    result_cache = (time.time() + 3, radical_result)
                    self.__radical_buy_by_blocks_result_cache[code] = result_cache
                    RadicalBuyDealCodesManager.radical_buy_blocks_dict[code] = radical_result[0]
                    RadicalBuyDealCodesManager().set_code_blocks(code, radical_result[0])
                # 取缓存
                result = result_cache[1]
                if result[0]:
@@ -741,7 +747,7 @@
                        # ---------------判断板块是否还可以买入----------------
                        f_buy_blocks = radical_buy_data_manager.is_block_can_radical_buy(code, buy_blocks, deal_codes)
                        if not f_buy_blocks:
                            return
                            return True
                        buy_blocks = f_buy_blocks
                    except Exception as e:
                        logger_debug.exception(e)
@@ -755,7 +761,7 @@
                                                                        mode))
                    if not can_buy:
                        async_log_util.info(logger_l2_radical_buy, f"当前时间段已不能扫入:{code}-{msg}")
                        return
                        return True
                    # -----根据成交比例判断是否可买------
                    result_by_volume = radical_buy_strategy.process_limit_up_active_buy_deal(code, transaction_datas)
@@ -768,14 +774,14 @@
                            radical_buy_data_manager.ExcludeIndexComputeCodesManager.add_code(code)
                            async_log_util.info(logger_l2_radical_buy,
                                                f"09:32之前不交易:{code}")
                            return
                            return True
                        # 判断是否开得太高
                        open_price = L1DataManager.get_open_price(code)
                        if not radical_buy_strategy.is_can_buy_with_open_price(code, open_price):
                            async_log_util.info(logger_l2_radical_buy,
                                                f"开得太高:{code}")
                            radical_buy_data_manager.ExcludeIndexComputeCodesManager.add_code(code)
                            return
                            return True
                        radical_buy_data_manager.ExcludeIndexComputeCodesManager.remove_code(code)
                        if result_by_volume[0] == radical_buy_strategy.BUY_MODE_DIRECT and not tool.is_sh_code(code):
@@ -807,17 +813,23 @@
                                # 下单成功
                                radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, buy_blocks)
                                radical_buy_strategy.clear_latest_deal_active_buy_order(code)
                                RDCancelBigNumComputer().clear_data(code)
                            return True
                        else:
                            RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict[code] = (
                                time.time() + 30, transaction_datas[-1][6], buy_blocks,
                                l2_huaxin_util.convert_time(transaction_datas[-1][3]), buy_blocks_with_money)
                            return False
                    else:
                        async_log_util.info(logger_l2_radical_buy, f"不能下单:{code}-{result_by_volume}")
                        return False
                else:
                    volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code)
                    async_log_util.info(logger_l2_radical_buy, f"没有可扫入的板块:{code},量比:{volume_rate}")
                    return True
            else:
                async_log_util.info(logger_l2_radical_buy, f"目前代码不可交易:{code}-{can_buy_result[1]}")
                return True
        except Exception as e:
            async_log_util.info(logger_debug, f"激进买计算异常:{str(e)}")
            logger_debug.exception(e)
@@ -826,6 +838,14 @@
            if use_time > 0.005:
                async_log_util.info(logger_debug, f"扫入处理时长:{code}-{use_time}")
    def OnLimitUpActiveBuy(self, code, transaction_datas):
        can_clear_before_data = self.__process_limit_up_active_buy(code, transaction_datas)
        if can_clear_before_data:
            # 清除
            EveryLimitupBigDealOrderManager.clear(code)
# 回调
my_l2_data_callback = MyL2DataCallback()
trade/buy_radical/block_special_codes_manager.py
@@ -174,8 +174,8 @@
                    # 非正常票
                    continue
                if juejin_result_dict[code][2] < 3:
                    # 小于3块
                if juejin_result_dict[code][2] < 3 or juejin_result_dict[code][2] > 40:
                    # 小于3块/大于40块
                    continue
                index += 1
                fdatas.append(
trade/buy_radical/radical_buy_data_manager.py
@@ -12,6 +12,7 @@
from code_attribute.code_volumn_manager import CodeVolumeManager
from db import redis_manager_delegate as redis_manager
from db.redis_manager_delegate import RedisUtils
from l2.huaxin import l2_huaxin_util
from l2.l2_transaction_data_manager import BigOrderDealManager, HuaXinBuyOrderManager
from log_module import async_log_util
from log_module.log import logger_l2_radical_buy, logger_debug, logger_l2_radical_buy_data
@@ -660,6 +661,14 @@
            if volume_rate < 0.8:
                return False, f"处于首板老{history_index + 1},量比({volume_rate})<0.8"
        # 前排最多允许1个炸板
        limit_up_timestamp = cls.__get_limit_up_timestamp(code)
        # 获取当前的板块, 不要忽略开1的数据
        current_index, current_before_codes_info = cls.__get_current_index(code, block, set(),
                                                                           limit_up_time=limit_up_timestamp,
                                                                           ignore_open_limit_up=False)
        if history_index - current_index >1:
            return False, f"前排只允许一个炸板:炸板个数-{history_index - current_index}"
        return True, f"处于首板老{history_index + 1}"
    @classmethod
@@ -934,7 +943,14 @@
        else:
            return False, f"量比-{volume_rate}, 总大单成交金额({deal_big_order_money})<{threshold_money}", before_time
    else:
        current_big_order_deal_money = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money(code)
        current_big_order_deal_money = 0
        current_big_order_deal_money_info = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money_info(code)
        if current_big_order_deal_money_info:
            if tool.trade_time_sub(tool.get_now_time_str(), current_big_order_deal_money_info[1]) > 60:
                # 60s以上的大单不看
                current_big_order_deal_money = 0
            else:
                current_big_order_deal_money = current_big_order_deal_money_info[0]
        if current_big_order_deal_money + delegating_big_order_money >= threshold_money:
            return True, f"量比-{volume_rate}, 本次大单成交金额({current_big_order_deal_money})+委托大单金额({delegating_big_order_money})>={threshold_money}", before_time
        else:
@@ -956,11 +972,15 @@
            cls.__deal_big_order_infos_dict[code].clear()
    @classmethod
    def clear(cls, code):
        cls.open_limit_up(code)
    @classmethod
    def add_big_buy_order_deal(cls, code, order_infos: list):
        """
        加入大单成交
        @param code:
        @param order_infos:[(订单号,金额)]
        @param order_infos:[(订单号,金额, 最后成交时间)]
        @return:
        """
        if code not in cls.__deal_big_order_infos_dict:
@@ -986,6 +1006,13 @@
            return sum([x[1] for x in cls.__deal_big_order_infos_dict[code]])
        return 0
    @classmethod
    def get_big_buy_deal_order_money_info(cls, code):
        if cls.__deal_big_order_infos_dict.get(code):
            return sum([x[1] for x in cls.__deal_big_order_infos_dict[code]]), l2_huaxin_util.convert_time(
                cls.__deal_big_order_infos_dict[code][-1][2])
        return None
def __get_deal_reasons(code):
    """
@@ -1003,7 +1030,7 @@
    if limit_up_reason:
        reasons.add(limit_up_reason)
    if not limit_up_reason:
        radical_buy_deal_blocks = RadicalBuyDealCodesManager.radical_buy_blocks_dict.get(code)
        radical_buy_deal_blocks = RadicalBuyDealCodesManager().get_code_blocks(code)
        if radical_buy_deal_blocks:
            reasons |= radical_buy_deal_blocks
    return reasons
trade/buy_radical/radical_buy_strategy.py
@@ -29,54 +29,6 @@
__latest_deal_active_buy_order = {}
def __get_deal_rate_by(code, huaxin_timestamp):
    """
    @param code: 代码
    @param huaxin_timestamp: 华鑫成交时间戳
    @return:买入方式, 消息
    """
    """
    获取备用成交比例
    @param code:
    @return:
    """
    refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, l2_huaxin_util.convert_time(
        huaxin_timestamp))
    async_log_util.info(logger_l2_radical_buy, f"参考总卖额(备用):{code}-{refer_sell_data}")
    if refer_sell_data:
        # 如果总卖额大于500w,成交到一半就直接扫
        if refer_sell_data[1] >= 500 * 1e4:
            THRESH_HOLD_VOLUME = refer_sell_data[2]
            if refer_sell_data[4] and len(refer_sell_data[4]) < 10:
                # 小于10挡,最后一档才是涨停价
                if refer_sell_data[4][-1][1] > 0:
                    THRESH_HOLD_VOLUME = refer_sell_data[4][-1][1]
            refer_sell_time = refer_sell_data[0]
            # 获取最近的主动买成交量
            limit_up_deal_infos = HuaXinSellOrderStatisticManager.get_latest_6s_active_buy_deal_volumes(
                code)
            async_log_util.info(logger_l2_radical_buy, f"最近涨停主动买成交(备用):{code}-{limit_up_deal_infos}")
            deal_volume = 0
            for i in range(0, len(limit_up_deal_infos)):
                # >=统计到的总卖
                if int(refer_sell_time.replace(":", "")) > int(
                        limit_up_deal_infos[i][0].replace(":", "")):
                    break
                deal_volume += limit_up_deal_infos[i][1]
            async_log_util.info(logger_l2_radical_buy, f"成交量(备用):{deal_volume}/{THRESH_HOLD_VOLUME}")
            deal_rate = round(deal_volume / THRESH_HOLD_VOLUME, 2)
            if deal_rate >= 0.5:
                return BUY_MODE_DIRECT, f"达到买入条件(备用):比例-{deal_rate}"
            else:
                return BUY_MODE_NONE, f"尚未达到买入比例(备用):{deal_rate}"
        else:
            return BUY_MODE_BY_L2, f"总卖额小于500w(备用)({refer_sell_data[1]})"
    else:
        return BUY_MODE_NONE, "尚未获取到总卖额(备用)"
def clear_latest_deal_active_buy_order(code):
    """
    清除最近主动成交的订单信息
@@ -153,51 +105,35 @@
    if refer_sell_data:
        refer_sell_money = refer_sell_data[1]
    # 处于涨停卖的委托订单总手数
    selling_num = L2LimitUpSellDataManager.get_delegating_sell_num(code)
    if selling_num is None:
        selling_num = 0
    if selling_num is not None:
        # 总卖 = 涨停主动买成交的累计金额 + 处于委托状态的涨停卖金额
        total_sell = __deal_active_buy_total_money[code] + selling_num * price
        if total_sell == 0:
            total_sell = 1
        rate = round(__deal_active_buy_total_money[code] / total_sell, 2)
        # 获取当前的成交量比
        limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
        volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code, total_sell_volume=int(
            total_sell / limit_up_price),
                                                                              with_info=False)
        if volume_rate is None:
            volume_rate = 0.5
    # 总卖 = 涨停主动买成交的累计金额 + 处于委托状态的涨停卖金额
    total_sell = __deal_active_buy_total_money[code] + selling_num * price
    if total_sell == 0:
        total_sell = 1
    rate = round(__deal_active_buy_total_money[code] / total_sell, 2)
    # 获取当前的成交量比
    limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
    volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days(code,
                                                                                         total_sell_volume=int(
                                                                                             total_sell / limit_up_price))
    if volume_rate is None:
        volume_rate = 0.5
        THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate)
        if rate >= THRESHOLD_RATE:
            # 根据大单判断是否可以扫
            big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate, refer_sell_money)
            if big_order_deal_result[0]:
                return BUY_MODE_DIRECT, f"剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}"
            else:
                # 无大单成交就只能通过L2下单
                return BUY_MODE_BY_L2, f"无大单成交-{big_order_deal_result[1]},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE} "
        else:
            return BUY_MODE_NONE, f"被动卖成交比例未达到:剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}"
    else:
        # 根据量比与大单成交数量判断是否可扫
        volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code, with_info=False)
        if volume_rate is None:
            volume_rate = 0.5
    THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate)
    if rate >= THRESHOLD_RATE:
        # 根据大单判断是否可以扫
        big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate, refer_sell_money)
        result = __get_deal_rate_by(code, huaxin_timestamp)
        if result[0] == BUY_MODE_DIRECT:
            if big_order_deal_result[0]:
                return result
            else:
                return BUY_MODE_BY_L2, big_order_deal_result[1]
        big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate,
                                                                                  refer_sell_money)
        if big_order_deal_result[0]:
            return BUY_MODE_DIRECT, f"剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}, 大单信息-{big_order_deal_result}"
        else:
            return result
            # 无大单成交就只能通过L2下单
            return BUY_MODE_BY_L2, f"无大单成交-{big_order_deal_result},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE} "
    else:
        return BUY_MODE_NONE, f"被动卖成交比例未达到:剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}"
def is_can_buy_with_open_price(code, open_price):
trade/trade_constant.py
@@ -48,3 +48,6 @@
# D撤
CANCEL_TYPE_D = 11
# RD撤
CANCEL_TYPE_RD = 12
trade/trade_data_manager.py
@@ -468,25 +468,38 @@
    __redis_manager = redis_manager.RedisManager(2)
    __deal_codes_cache = set()
    __instance = None
    __mysqldb = Mysqldb()
    # 根据L2数据来激进买入的有效时间:{"code":(有效截至时间, 买单号, 扫入的板块, 最近成交时间)}
    buy_by_l2_delegate_expire_time_dict = {}
    # 仅仅买的板块
    radical_buy_blocks_dict = {}
    __radical_buy_blocks_dict = {}
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(RadicalBuyDealCodesManager, cls).__new__(cls, *args, **kwargs)
            cls.__instance.__load_data()
            cls.__load_data()
        return cls.__instance
    @classmethod
    def __load_data(cls):
        __redis = cls.__get_redis()
        result = RedisUtils.smembers(cls.__get_redis(), "radical_buy_deal_codes")
        if result:
            cls.__deal_codes_cache = set(result)
        keys = RedisUtils.keys(cls.__get_redis(), "radical_buy_blocks-*")
        if keys:
            for k in keys:
                code = k.split("-")[1]
                val = RedisUtils.get(cls.__get_redis(), k)
                val = json.loads(val)
                cls.__radical_buy_blocks_dict[code] = set(val)
            cls.__deal_codes_cache = set(result)
    def set_code_blocks(self, code, blocks):
        self.__radical_buy_blocks_dict[code] = set(blocks)
        RedisUtils.setex_async(self.__db, f"radical_buy_blocks-{code}", tool.get_expire(), json.dumps(list(blocks)))
    def get_code_blocks(self, code):
        return self.__radical_buy_blocks_dict.get(code)
    @classmethod
    def __get_redis(cls):
@@ -513,4 +526,4 @@
if __name__ == "__main__":
    print(AccountMoneyManager().get_deal_count())
    pass