Administrator
2024-10-09 deb26c8b90f9d67c340b3a757740085ac8dd5743
订阅特殊量/目标代码扫入板块修改/
14个文件已修改
1个文件已添加
493 ■■■■ 已修改文件
api/outside_api_command_callback.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_data_manager.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
servers/data_server.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
servers/huaxin_trade_server.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/code_plate_key_manager.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/third_blocks_manager.py 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/buy_money_count_setting.py 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/current_price_process_manager.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_data_update.py 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/order_statistic.py 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_manager.py 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/tool.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/outside_api_command_callback.py
@@ -285,6 +285,8 @@
            if code_list_type == outside_api_command_manager.CODE_LIST_WANT:
                if operate == outside_api_command_manager.OPERRATE_SET:
                    gpcode_manager.WantBuyCodesManager().add_code(code)
                    # 加想买单要从黑名单移除
                    l2_trade_util.remove_from_forbidden_trade_codes(code)
                    name = gpcode_manager.get_code_name(code)
                    if not name:
                        results = HistoryKDatasUtils.get_gp_codes_names([code])
@@ -1257,8 +1259,8 @@
                # 设置买入金额和数量
                normal = data["normal"]
                radical = data["radical"]
                BuyMoneyAndCountSetting().set_normal_buy_data(normal[0],json.loads( normal[1]))
                BuyMoneyAndCountSetting().set_radical_buy_data(radical[0],json.loads( radical[1]))
                BuyMoneyAndCountSetting().set_normal_buy_data(normal[0], json.loads(normal[1]))
                BuyMoneyAndCountSetting().set_radical_buy_data(radical[0], json.loads(radical[1]))
                data = {
                    "normal": BuyMoneyAndCountSetting().get_normal_buy_setting(),
                    "radical": BuyMoneyAndCountSetting().get_radical_buy_setting()
@@ -1270,7 +1272,8 @@
                # 设置买入金额和数量
                data = {
                    "normal": BuyMoneyAndCountSetting().get_normal_buy_setting(),
                    "radical": BuyMoneyAndCountSetting().get_radical_buy_setting()
                    "radical": BuyMoneyAndCountSetting().get_radical_buy_setting(),
                    "moneys":constant.AVAILABLE_BUY_MONEYS
                }
                self.send_response({"code": 0, "data": data, "msg": f""},
                                   client_id,
constant.py
@@ -194,3 +194,6 @@
# L2数据是否载入完成
L2_DATA_IS_LOADED = False
# 可买入的金额
AVAILABLE_BUY_MONEYS = [5000, 20000, 50000]
huaxin_client/l2_client.py
@@ -146,8 +146,8 @@
        for d in codes_data:
            code = d[0]
            codes.add(code)
            self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3], d[4])
            self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], round(float(d[2]), 2), d[3], d[4])
            self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3], d[4], d[5])
            self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], round(float(d[2]), 2), d[3], d[4], d[5])
        logger_l2_codes_subscript.info("华鑫L2订阅总数:{}", len(codes))
        add_codes = codes - self.subscripted_codes
        del_codes = self.subscripted_codes - codes
huaxin_client/l2_data_manager.py
@@ -47,10 +47,13 @@
    # 设置订单过滤条件
    # special_price:过滤的1手的价格
    def set_order_fileter_condition(self, code, min_volume, limit_up_price, shadow_price, buy_volume):
    def set_order_fileter_condition(self, code, min_volume, limit_up_price, shadow_price, buy_volume, special_volumes):
        if not special_volumes:
            special_volumes = set()
        if code not in self.filter_order_condition_dict:
            # (最小的量, 涨停价格, 影子单价格, 买的量, 废弃使用, 特殊的量集合)
            self.filter_order_condition_dict[code] = [(min_volume, limit_up_price, shadow_price, buy_volume,
                                                       min_volume // 50)]
                                                       min_volume // 50, set(special_volumes))]
            huaxin_l2_log.info(logger_local_huaxin_l2_subscript,
                               f"({code})常规过滤条件设置:{self.filter_order_condition_dict[code]}")
@@ -74,8 +77,12 @@
            # 所有的涨停卖
            if item[1] == filter_condition[0][1]:
                return item
                if item[3] != '1':
                    # 涨停卖
                    return item
                elif item[2] in filter_condition[0][5]:
                    # 涨停满足特殊的手数
                    return item
            return None
        return item
        # 过滤订单
l2/l2_data_manager_new.py
@@ -331,10 +331,20 @@
            if cancel_result[0]:
                L2TradeDataProcessor.cancel_buy(code, f"F撤:{cancel_result[1]}",
                                                cancel_type=trade_constant.CANCEL_TYPE_F)
                return
            else:
                l2_log.f_cancel_debug(code, f"获取真实成交位的F撤未生效:{cancel_result[1]}")
        except Exception as e:
            logger_debug.exception(e)
        # 判断与执行位置的间隔时间
        if order_begin_pos.mode != OrderBeginPosInfo.MODE_RADICAL:
            # 非扫入下单要判断执行位置与真实下单位的间隔时间
            total_datas = local_today_datas.get(code)
            if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[index]["val"]), L2DataUtil.get_time_with_ms(total_datas[order_begin_pos.buy_exec_index]["val"])) > 2000:
                L2TradeDataProcessor.cancel_buy(code, f"真实下单位({index})与执行位({order_begin_pos.buy_exec_index})相差2s以上",
                                                cancel_type=trade_constant.CANCEL_TYPE_F)
                return
    # 处理华鑫L2数据
    @classmethod
@@ -1961,191 +1971,6 @@
                continue
            findexes.add(index)
        return findexes
    # 统计买入净买量,不计算在买入信号之前的买撤单
    @classmethod
    def __sum_buy_num_for_order_3(cls, code, compute_start_index, compute_end_index, origin_num, origin_count,
                                  threshold_money, buy_single_index, max_num_set, at_limit_up=False):
        _start_time = t.time()
        total_datas = local_today_datas[code]
        # is_first_code = gpcode_manager.FirstCodeManager().is_in_first_record_cache(code)
        buy_nums = origin_num
        buy_count = origin_count
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if limit_up_price is None:
            raise Exception("涨停价无法获取")
        limit_up_price = float(limit_up_price)
        threshold_num = None
        # 大目标手数(满足这个就不需要看安全笔数)
        threshold_max_num = None
        # 目标订单数量
        threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count()
        # 最大间隔时间ms
        max_space_time_ms = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range() * 1000
        # ----------------调整板上下单的m值与安全笔数----------------
        if at_limit_up:
            # 板上买,获取最近一次闪电下单的总卖额
            sell_data = cls.__latest_fast_place_order_info_dict.get(code)
            if sell_data:
                # 有过闪电下单
                # 总卖的一半作为m值
                threshold_num = int(sell_data[1] / (limit_up_price * 100)) // 2
                threshold_max_num = 1
            #  信号为之前有待成交的大单(不是正在成交)
            trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code)
            if not is_default and trade_index is not None:
                temp_big_num = int(30000 / limit_up_price)
                for i in range(trade_index + 1, buy_single_index):
                    data = total_datas[i]
                    val = data['val']
                    if not L2DataUtil.is_limit_up_price_buy(val):
                        continue
                        # 判断是否有大单未成交
                    if temp_big_num > val["num"]:
                        continue
                    left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code,
                                                                                                             data[
                                                                                                                 "index"],
                                                                                                             total_datas,
                                                                                                             local_today_canceled_buyno_map.get(
                                                                                                                 code))
                    if left_count > 0:
                        # 安全笔数与囊括时间范围修改
                        threshold_count = 3
                        max_space_time_ms = 9 * 1000
                        break
        if not threshold_num:
            # 目标手数
            threshold_num = round(threshold_money / (limit_up_price * 100))
        if not threshold_max_num:
            threshold_max_num = int(threshold_num * 1.2)
        # place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code)
        # buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # 可以触发买,当有涨停买信号时才会触发买
        trigger_buy = True
        # 如果大单含有率大于50%,则时间囊括范围提高到3s
        if max_num_set and origin_count:
            if len(max_num_set) / origin_count > 0.5:
                max_space_time_ms = 3 * 1000
        # 最大买量
        max_buy_num = 0
        max_buy_num_set = set(max_num_set)
        # 需要的最小大单笔数
        big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count()
        # 较大单的手数
        bigger_num = round(5000 / limit_up_price)
        not_buy_msg = ""
        is_ge_code = tool.is_ge_code(code)
        for i in range(compute_start_index, compute_end_index + 1):
            data = total_datas[i]
            _val = total_datas[i]["val"]
            trigger_buy = False
            # 必须为连续2秒内的数据
            if L2DataUtil.time_sub_as_ms(_val, total_datas[buy_single_index]["val"]) > max_space_time_ms:
                cls.__TradePointManager.delete_buy_point(code)
                if i == compute_end_index:
                    # 数据处理完毕
                    return None, buy_nums, buy_count, None, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
                else:
                    # 计算买入信号,不能同一时间开始计算
                    for ii in range(buy_single_index + 1, compute_end_index + 1):
                        if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]:
                            return None, buy_nums, buy_count, ii, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
            # 涨停买
            if L2DataUtil.is_limit_up_price_buy(_val):
                if l2_data_util.is_big_money(_val, is_ge_code):
                    max_buy_num_set.add(i)
                if _val["num"] >= bigger_num:
                    trigger_buy = True
                    # 只统计59万以上的金额
                    buy_nums += int(_val["num"]) * int(total_datas[i]["re"])
                    buy_count += int(total_datas[i]["re"])
                    if (buy_nums >= threshold_num and buy_count >= threshold_count) or buy_nums >= threshold_max_num:
                        l2_log.info(code, logger_l2_trade_buy,
                                    f"{code}获取到买入执行点:{i} 统计纯买手数:{buy_nums} 目标纯买手数:{threshold_num}/{threshold_max_num} 统计纯买单数:{buy_count} 目标纯买单数:{threshold_count}, 大单数量:{len(max_buy_num_set)}")
            elif L2DataUtil.is_limit_up_price_buy_cancel(_val):
                if _val["num"] >= bigger_num:
                    # 只统计59万以上的金额
                    # 涨停买撤
                    # 判断买入位置是否在买入信号之前
                    buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i],
                                                                                                        local_today_buyno_map.get(
                                                                                                            code))
                    if buy_index is not None:
                        # 找到买撤数据的买入点
                        if buy_index >= buy_single_index:
                            buy_nums -= int(_val["num"]) * int(data["re"])
                            buy_count -= int(data["re"])
                            # 大单撤销
                            max_buy_num_set.discard(buy_index)
                            l2_log.buy_debug(code, "{}数据在买入信号之后 撤买纯买手数:{} 目标手数:{}", i, buy_nums, threshold_num)
                        else:
                            l2_log.buy_debug(code, "{}数据在买入信号之前,买入位:{}", i, buy_index)
                            if total_datas[buy_single_index]["val"]["time"] == total_datas[buy_index]["val"]["time"]:
                                # 同一秒,当作买入信号之后处理
                                buy_nums -= int(_val["num"]) * int(data["re"])
                                buy_count -= int(data["re"])
                                # 大单撤销
                                max_buy_num_set.discard(buy_index)
                                l2_log.buy_debug(code, "{}数据买入位与预估买入位在同一秒", i)
                    else:
                        # 未找到买撤数据的买入点
                        l2_log.buy_debug(code, "未找到买撤数据的买入点: 位置-{} 数据-{}", i, data)
                        buy_nums -= int(_val["num"]) * int(total_datas[i]["re"])
                        buy_count -= int(total_datas[i]["re"])
            l2_log.buy_debug(code, "位置-{},总手数:{},目标手数:{}", i,
                             buy_nums, threshold_num)
            max_buy_num_set_count = 0
            max_buy_num_set = cls.__filter_not_deal_indexes(code, max_buy_num_set)
            for i1 in max_buy_num_set:
                max_buy_num_set_count += total_datas[i1]["re"]
            if buy_nums < threshold_num:
                not_buy_msg = f"【{i}】纯买额不足,{buy_nums}/{threshold_num}"
                continue
            if buy_count < threshold_count:
                not_buy_msg = f"【{i}】安全笔数不够,{buy_count}/{threshold_count}"
                continue
            if not trigger_buy:
                not_buy_msg = f"【{i}】没有买单触发"
                continue
            if max_buy_num_set_count < big_num_count:
                not_buy_msg = f"【{i}】大单数量不足,{max_buy_num_set_count}/{big_num_count}"
                continue
            try:
                info = cls.__trade_log_placr_order_info_dict[code]
                info.set_trade_factor(threshold_money, threshold_count, list(max_buy_num_set))
            except Exception as e:
                async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}")
            return i, buy_nums, buy_count, None, max_buy_num_set, "可以下单"
        l2_log.buy_debug(code, "尚未获取到买入执行点,起始计算位置:{} 统计纯买手数:{} 目标纯买手数:{}  统计纯买单数:{} 目标纯买单数:{} 大单数量:{} 目标大单数量:{}",
                         compute_start_index,
                         buy_nums,
                         threshold_num, buy_count, threshold_count, max_buy_num_set_count, big_num_count)
        return None, buy_nums, buy_count, None, max_buy_num_set, not_buy_msg
    # 返回(买入执行点, 总手, 总笔数, 从新计算起点, 纯买额阈值)
    # 计算快速买入
servers/data_server.py
@@ -514,6 +514,8 @@
            for d in record_limit_up_datas:
                if kpl_util.filter_block(d[2]) != plate:
                    continue
                if not tool.is_can_buy_code(d[3]):
                    continue
                # 代码,名称,涨停时间,是否炸板,是否想买,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面
                codes_info.append(
                    [d[3], d[4], tool.to_time_str(int(d[5])), 1 if d[3] not in now_limit_up_codes else 0, 0, 0, d[12],
@@ -524,6 +526,8 @@
                    continue
                if plate not in [kpl_util.filter_block(k) for k in d[6].split("、")]:
                    continue
                if not tool.is_can_buy_code(d[3]):
                    continue
                # 代码,名称,涨停时间,是否炸板,是否想买,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面
                codes_info.append(
                    [d[3], d[4], tool.to_time_str(int(d[5])), 1 if d[3] not in now_limit_up_codes else 0, 0, 0, d[12],
servers/huaxin_trade_server.py
@@ -45,6 +45,7 @@
from third_data.history_k_data_util import JueJinApi
from trade import trade_manager, l2_trade_util, \
    trade_data_manager, trade_constant, radical_buy_strategy
from trade.buy_money_count_setting import BuyMoneyAndCountSetting
from trade.huaxin import huaxin_trade_api as trade_api, huaxin_trade_api, huaxin_trade_data_update, \
    huaxin_trade_record_manager, huaxin_sell_util
@@ -779,8 +780,10 @@
            # 判断昨日是否涨停过
            async_log_util.info(logger_l2_radical_buy, f"涨停主动买:{code}-{transaction_datas[-1]}")
            deal_codes = RadicalBuyDealCodesManager().get_deal_codes()
            if len(deal_codes) >= 4:
                async_log_util.info(logger_l2_radical_buy, f"扫入成交代码个数大于4个:{code}-{deal_codes}")
            radical_buy_setting = BuyMoneyAndCountSetting().get_radical_buy_setting()
            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
            if code in deal_codes:
                async_log_util.info(logger_l2_radical_buy, f"该代码已经成交:{code}")
third_data/code_plate_key_manager.py
@@ -1443,6 +1443,9 @@
        match_blocks, info = CodeThirdBlocksManager().get_intersection_blocks_info(code, blocks)
        match_blocks -= constant.KPL_INVALID_BLOCKS
        fblocks = match_blocks & RealTimeKplMarketData.get_top_market_jingxuan_blocks()
        if not fblocks:
            fblocks, info = CodeThirdBlocksManager().get_intersection_blocks_info(code, blocks, same_count=3)
            fblocks -= constant.KPL_INVALID_BLOCKS
        return fblocks, match_blocks
    @classmethod
third_data/third_blocks_manager.py
@@ -5,12 +5,14 @@
from db.mysql_data_delegate import Mysqldb
from utils import middle_api_protocol
from utils.kpl_data_db_util import KPLLimitUpDataUtil
from utils.ths_industry_util import ThsCodeIndustryManager
SOURCE_TYPE_KPL = 1  # 东方财富
SOURCE_TYPE_KPL = 1  # 开盘啦
SOURCE_TYPE_TDX = 2  # 通达信
SOURCE_TYPE_THS = 3  # 同花顺
SOURCE_TYPE_EASTMONEY = 4  # 东方财富
SOURCE_TYPE_KPL_RECORD = 5  # 开盘啦历史数据
class CodeThirdBlocksManager:
@@ -40,12 +42,30 @@
                cls.__code_source_blocks_dict_origin[result[0]] = {}
            blocks = set(result[2].split("、"))
            if result[1] == SOURCE_TYPE_THS:
                # 同花顺加入2级分类
                industry = cls.__ths_industry.get_industry(result[0])
                if industry:
                    blocks.add(industry)
            cls.__code_source_blocks_dict_origin[result[0]][result[1]] = blocks
            cls.__code_source_blocks_dict[result[0]][result[1]] = BlockMapManager().filter_blocks(blocks)
        # 加载开盘啦历史涨停原因
        kpl_results = KPLLimitUpDataUtil.get_latest_block_infos()
        code_blocks = {}
        for r in kpl_results:
            if r[0] not in code_blocks:
                code_blocks[r[0]] = set()
            code_blocks[r[0]].add(r[2])
            if r[3]:
                code_blocks[r[0]] |= set(r[3].split("、"))
        for code in code_blocks:
            if code not in cls.__code_source_blocks_dict:
                cls.__code_source_blocks_dict[code] = {}
                cls.__code_source_blocks_dict_origin[code] = {}
            blocks = code_blocks[code]
            cls.__code_source_blocks_dict_origin[code][SOURCE_TYPE_KPL_RECORD] = blocks
            cls.__code_source_blocks_dict[code][SOURCE_TYPE_KPL_RECORD] = BlockMapManager().filter_blocks(blocks)
    def get_source_blocks(self, code):
        """
@@ -63,7 +83,7 @@
        """
        return self.__code_source_blocks_dict_origin.get(code)
    def get_intersection_blocks_info(self, code, blocks):
    def get_intersection_blocks_info(self, code, blocks, same_count=2):
        # 获取交集
        bs = []
        b1 = BlockMapManager().filter_blocks(blocks)
@@ -74,13 +94,13 @@
            for s in sb_dict:
                if sb_dict[s]:
                    bs.append(sb_dict[s])
        if len(bs) < 2:
        if len(bs) < same_count:
            return set(), bs
        s_count = len(bs)
        fblocks = set()
        # 求2个平台的交集
        for ces in combinations(bs, 2):
        for ces in combinations(bs, same_count):
            ic = None
            for c in ces:
                if ic is None:
trade/buy_money_count_setting.py
@@ -5,15 +5,16 @@
import constant
from db.mysql_data_delegate import Mysqldb
from l2.l2_data_manager import OrderBeginPosInfo
class BuyMoneyAndCountSetting:
    __mysql = Mysqldb()
    __instance = None
    # 常规买
    __normal_buy = [10, [("15:00:00", constant.BUY_MONEY_PER_CODE)]]  # (数量, [("时间", 金额)])
    __normal_buy = [10, [("15:00:00", constant.BUY_MONEY_PER_CODE, 4)]]  # (数量, [("时间", 金额, 买入数量)])
    # 扫入买
    __radical_buy = [4, [("15:00:00", constant.BUY_MONEY_PER_CODE)]]  # (数量, [("时间", 金额)])
    __radical_buy = [4, [("15:00:00", constant.BUY_MONEY_PER_CODE, 3)]]  # (数量, [("时间", 金额, 买入数量)])
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
@@ -79,37 +80,62 @@
class BuyMoneyUtil:
    @classmethod
    def get_buy_money(cls, time_str, money_list: list):
    def get_buy_data(cls, time_str, buy_mode, deals, delegates):
        """
        @param time_str:
        @param money_list:[("09:30:00",20000)]
        @return:
        获取买入数据
        @param time_str: 买入时间
        @param buy_mode: 买入模式
        @return:是否可买入, 买入金额, 信息
        """
        if len(money_list) == 0:
            return constant.BUY_MONEY_PER_CODE
        for money_info in money_list:
        # radical_deals, radical_delegates, normal_deals, normal_delegates
        # if buy_mode == OrderBeginPosInfo.MODE_RADICAL:
        # [(成交代码, 成交时间)]
        # deals = DealAndDelegateWithBuyModeDataManager().get_deal_codes_info(buy_mode)
        if deals is None:
            deals = []
        # [(委托代码, 委托时间)]
        # delegates = DealAndDelegateWithBuyModeDataManager().get_delegates_codes_info(buy_mode)
        if delegates is None:
            delegates =[]
        # 最大委托数量
        max_count = 0
        # 配置数据:[(时间,金额,数量)]
        money_list = []
        if buy_mode == OrderBeginPosInfo.MODE_RADICAL:
            max_count, money_list = BuyMoneyAndCountSetting().get_radical_buy_setting()
        else:
            max_count, money_list = BuyMoneyAndCountSetting().get_normal_buy_setting()
        codes = set([x[0] for x in deals])
        if len(codes) >= max_count:
            return False, 0, f"成交数量({len(codes)})超过{max_count}个"
        # 获取当前时间段允许成交的数量
        start_time = "09:25:00"
        end_info = None
        for i in range(0, len(money_list)):
            money_info = money_list[i]
            if int(time_str.replace(":", "")) <= int(money_info[0].replace(":", "")):
                return money_info[1]
        return constant.BUY_MONEY_PER_CODE
def set_buy_money(deal_codes, delegate_codes):
    """
    设置买入金额
    @param deal_codes:
    @param delegate_codes:
    @return:
    """
    codes = set()
    if deal_codes:
        codes |= deal_codes
    if delegate_codes:
        codes |= delegate_codes
    if len(codes) < 4:
        constant.BUY_MONEY_PER_CODE = 50000
    else:
        constant.BUY_MONEY_PER_CODE = 20000
                end_info = money_info
                if i > 0:
                    start_time = money_list[i - 1][0]
                break
        # 获取时间段已经成交/已经挂单的代码数量
        end_time_int = int(end_info[0].replace(":", ""))
        start_time_int = int(start_time.replace(":", ""))
        codes = set()
        for d in deals:
            if start_time_int < int(d[1].replace(":", "")) <= end_time_int:
                codes.add(d[0])
        for d in delegates:
            if start_time_int < int(d[1].replace(":", "")) <= end_time_int:
                codes.add(d[0])
        if len(codes) >= end_info[2]:
            return True, constant.BUY_MONEY_PER_CODE, f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})超过{end_info[2]}个,按照默认金额委托"
        else:
            return True, end_info[
                1], f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})没有超过{end_info[2]}个,委托金额为:{end_info[1]}"
if __name__ == '__main__':
    set_buy_money({"000333"}, None)
    pass
trade/current_price_process_manager.py
@@ -123,8 +123,9 @@
                        min_volume = int(round(50 * 10000 / limit_up_price))
                        # 传递笼子价
                        add_datas.append(
                            # (代码, 最小量, 涨停价,影子订单价格,买量, 特殊价格)
                            (d, min_volume, limit_up_price, round(tool.get_shadow_price(limit_up_price), 2),
                             tool.get_buy_volume(limit_up_price)))
                             tool.get_buy_volume(limit_up_price), constant.AVAILABLE_BUY_MONEYS))
                    huaxin_target_codes_manager.HuaXinL2SubscriptCodesManager.push(add_datas, request_id)
            except Exception as e:
                logging.exception(e)
trade/huaxin/huaxin_trade_data_update.py
@@ -9,9 +9,10 @@
from code_attribute import gpcode_manager
from huaxin_client import constant as huaxin_client_constant
from l2.l2_data_manager import TradePointManager, OrderBeginPosInfo
from log_module import async_log_util
from log_module.log import hx_logger_trade_debug, logger_system, logger_debug
from trade import trade_manager, trade_data_manager, buy_money_count_setting
from trade import trade_manager, trade_data_manager, order_statistic
from trade.huaxin import huaxin_trade_api, huaxin_trade_record_manager
from trade.huaxin.huaxin_trade_order_processor import HuaxinOrderEntity, TradeResultProcessor
@@ -42,7 +43,8 @@
                            __process_thread_pool.submit(huaxin_trade_record_manager.DelegateRecordManager.add, data)
                            # 是否可以撤单
                            if data:
                                codes = []
                                codes_info = []
                                codes = set()
                                for d in data:
                                    code = d["securityID"]
                                    orderStatus = d["orderStatus"]
@@ -72,10 +74,13 @@
                                    TradeResultProcessor.process_buy_order(order)
                                    if huaxin_util.is_can_cancel(orderStatus) and str(direction) == str(
                                            huaxin_util.TORA_TSTP_D_Buy):
                                        codes.append(code)
                                trade_manager.delegate_codes = set(codes)
                                buy_money_count_setting.set_buy_money(trade_manager.deal_codes,
                                                                      trade_manager.delegate_codes)
                                        codes.add(code)
                                        order_begin_pos = TradePointManager().get_buy_compute_start_data_cache(code)
                                        mode = OrderBeginPosInfo.MODE_ACTIVE
                                        if order_begin_pos:
                                            mode = order_begin_pos.mode
                                        codes_info.append((code, insertTime, mode))
                                order_statistic.DealAndDelegateWithBuyModeDataManager().set_delegates_info(codes_info)
                                if codes:
                                    try:
                                        trade_manager.process_trade_delegate_data([{"code": c} for c in codes])
@@ -106,8 +111,6 @@
                                for d in datas:
                                    if str(d['direction']) == str(huaxin_util.TORA_TSTP_D_Buy):
                                        buy_deal_codes.add(d['securityID'])
                                trade_manager.deal_codes = buy_deal_codes
                                buy_money_count_setting.set_buy_money(trade_manager.deal_codes, trade_manager.delegate_codes)
                            except Exception as e:
                                logger_debug.exception(e)
                            huaxin_trade_record_manager.DealRecordManager.add(datas)
trade/order_statistic.py
New file
@@ -0,0 +1,91 @@
import json
from db import redis_manager
from db.redis_manager_delegate import RedisUtils
from log_module import async_log_util
from log_module.log import logger_debug
from utils import tool
class DealAndDelegateWithBuyModeDataManager:
    """
    成交与委托买入模式数据管理
    成交数据需要持久化
    """
    __instance = None
    __db = 2
    __redisManager = redis_manager.RedisManager(2)
    __deal_codes = set()
    __deal_mode_list_dict = {}
    __delegates_mode_list_dict = {}
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(DealAndDelegateWithBuyModeDataManager, cls).__new__(cls, *args, **kwargs)
            cls.__load_datas()
        return cls.__instance
    @classmethod
    def __get_redis(cls):
        return cls.__redisManager.getRedis()
    @classmethod
    def __load_datas(cls):
        keys = RedisUtils.keys(cls.__get_redis(), "deal_delegate_by_mode-*")
        for k in keys:
            mode = int(k.split("-")[1])
            val = RedisUtils.get(cls.__get_redis(), k)
            cls.__deal_mode_list_dict[mode] = json.loads(val)
        for m in cls.__deal_mode_list_dict:
            cls.__deal_codes |= set([x[0] for x in cls.__deal_mode_list_dict[m]])
    def add_deal_code(self, code, deal_time, mode):
        """
        添加成交数据
        @param code:
        @param deal_time:
        @param mode: 买入模式
        @return:
        """
        async_log_util.info(logger_debug, f"下单模式统计成交:{code}-{deal_time}-{mode}")
        # 添加成交数据
        if code in self.__deal_codes:
            return
        self.__deal_codes.add(code)
        if mode not in self.__deal_mode_list_dict:
            self.__deal_mode_list_dict[mode] = []
        self.__deal_mode_list_dict[mode].append((code, deal_time))
        # 将当前数据缓存到数据库
        RedisUtils.setex_async(self.__db, f"deal_delegate_by_mode-{mode}", tool.get_expire(),
                               json.dumps(self.__deal_mode_list_dict[mode]))
    def get_deal_codes_info(self, mode):
        """
        获取成交代码信息
        @param mode:
        @return:
        """
        return self.__deal_mode_list_dict.get(mode)
    def set_delegates_info(self, delegates):
        """
        设置委托信息
        @param delegates:[(代码,委托时间, 委托模式)]
        @return:
        """
        temp_dict = {}
        for d in delegates:
            mode = d[2]
            if mode not in temp_dict:
                temp_dict[mode] = []
            temp_dict[mode].append((d[0], d[1]))
        self.__delegates_mode_list_dict = temp_dict
    def get_delegates_codes_info(self, mode):
        """
        获取成交代码信息
        @param mode:
        @return:
        """
        return self.__delegates_mode_list_dict.get(mode)
trade/trade_manager.py
@@ -24,7 +24,9 @@
from l2 import l2_data_manager, l2_data_log
from log_module.log import *
from trade.buy_money_count_setting import BuyMoneyUtil
from trade.huaxin.huaxin_trade_record_manager import TradeOrderIdManager
from trade.order_statistic import DealAndDelegateWithBuyModeDataManager
from trade.trade_data_manager import AccountMoneyManager, RadicalBuyDealCodesManager
from utils import import_util, tool, huaxin_util
@@ -36,11 +38,6 @@
guiTrade = None  # trade_gui.THSGuiTrade() if trade_gui is not None else None
latest_trade_delegate_data = []
# 成交的代码
deal_codes = set()
# 委托代码
delegate_codes = set()
# 关闭购买入口
@@ -179,6 +176,7 @@
    def get_mode_cache(self):
        return self.__auto_cancel_sell_mode
# 代码的交易状态管理
class CodesTradeStateManager:
@@ -419,7 +417,11 @@
    async_log_util.info(logger_trade, "{} trade_manager.__buy 开始".format(code))
    try:
        if constant.API_TRADE_ENABLE:
            count = tool.get_buy_volume(price)
            can_buy, money, msg = BuyMoneyUtil.get_buy_data(tool.get_now_time_str(), mode, DealAndDelegateWithBuyModeDataManager().get_deal_codes_info(mode), DealAndDelegateWithBuyModeDataManager().get_delegates_codes_info(mode))
            if not can_buy:
                raise Exception(msg)
            count = tool.get_buy_volume_by_money(price, money)
            # if mode == OrderBeginPosInfo.MODE_RADICAL:
            #     # 激进买入金额为1手
            #     count = 100
@@ -636,7 +638,11 @@
    # 加入黑名单
    if not l2_trade_util.is_in_forbidden_trade_codes(code):
        l2_trade_util.forbidden_trade(code, "buy success", force=True)
        if TradePointManager().get_latest_place_order_mode(code) == OrderBeginPosInfo.MODE_RADICAL:
        mode = TradePointManager().get_latest_place_order_mode(code)
        if mode is None:
            mode = OrderBeginPosInfo.MODE_NORMAL
        DealAndDelegateWithBuyModeDataManager().add_deal_code(code, tool.get_now_time_str(), mode)
        if mode == OrderBeginPosInfo.MODE_RADICAL:
            RadicalBuyDealCodesManager().add_deal_code(code)
    # 取s消所有的挂单
    if constant.API_TRADE_ENABLE:
utils/tool.py
@@ -377,7 +377,11 @@
def get_buy_volume(limit_up_price):
    count = (constant.BUY_MONEY_PER_CODE // int(round(float(limit_up_price) * 100))) * 100
    return get_buy_volume_by_money(limit_up_price, constant.BUY_MONEY_PER_CODE)
def get_buy_volume_by_money(limit_up_price, money):
    count = (money // int(round(float(limit_up_price) * 100))) * 100
    if count < 100:
        count = 100
    return count