Administrator
2024-09-09 3b872137fb8d0e894c868197eff915748c704a0e
激进买入-买入完善
7个文件已修改
295 ■■■■ 已修改文件
l2/l2_data_manager.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/place_order_single_data_manager.py 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
servers/huaxin_trade_server.py 108 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_data_manager.py 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_manager.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager.py
@@ -17,6 +17,7 @@
    MODE_NORMAL = 0
    MODE_FAST = 1
    MODE_ACTIVE = 2
    MODE_RADICAL = 3
    # mode: 0-普通交易  1-快速交易
    def __init__(self, buy_single_index=None, buy_exec_index=-1, buy_compute_index=None, num=0, count=0,
l2/l2_data_manager_new.py
@@ -35,7 +35,8 @@
from log_module.log import logger_l2_trade_buy, logger_l2_process, logger_l2_error, logger_debug, \
    logger_l2_not_buy_reasons, logger_real_place_order_position, logger_l2_trade_buy_queue
from trade.trade_data_manager import CodeActualPriceProcessor, PlaceOrderCountManager, AccountMoneyManager
from trade.trade_data_manager import CodeActualPriceProcessor, PlaceOrderCountManager, AccountMoneyManager, \
    RadicalBuyDealCodesManager
from trade.trade_manager import TradeTargetCodeModeManager
@@ -730,16 +731,19 @@
                # 不处于可下单状态
                return False
            __start_time = tool.get_now_timestamp()
            order_begin_pos = cls.__get_order_begin_pos(
                code)
            can, need_clear_data, reason, is_valid_exec_index = cls.__can_buy_first(code)
            if order_begin_pos.MODE_RADICAL == order_begin_pos.mode:
                # 激进下单不判断条件
                can, need_clear_data, reason, is_valid_exec_index = True, False, "激进下单", True
            else:
                can, need_clear_data, reason, is_valid_exec_index = cls.__can_buy_first(code)
            # __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True)
            # 删除虚拟下单
            if code in cls.unreal_buy_dict:
                cls.unreal_buy_dict.pop(code)
            order_begin_pos = cls.__get_order_begin_pos(
                code)
            if not can:
                if not is_valid_exec_index:
                    if cls.__latest_exec_indexes.get(code) and cls.__latest_exec_indexes[code][
@@ -852,6 +856,32 @@
        return True, ""
    @classmethod
    def __is_on_limit_up_buy(cls, code, buy_exec_index):
        total_data = local_today_datas.get(code)
        latest_exec_indexes = cls.__latest_exec_indexes[code]
        if not latest_exec_indexes:
            latest_exec_indexes = []
        # 判断是否是炸开后买入
        last_exec_index = 0
        if len(latest_exec_indexes) > 1:
            last_exec_index = latest_exec_indexes[-2]
        # 获取最近的非涨停价成交时间
        not_limit_up_trade_time_with_ms = current_price_process_manager.get_trade_not_limit_up_time_with_ms(
            code)
        is_limit_up_buy = True
        if not_limit_up_trade_time_with_ms:
            t1 = int(
                L2DataUtil.get_time_with_ms(total_data[last_exec_index]["val"]).replace(":", "").replace(".",
                                                                                                         ""))
            t2 = int(not_limit_up_trade_time_with_ms.replace(":", "").replace(".", ""))
            t3 = int(L2DataUtil.get_time_with_ms(total_data[buy_exec_index]["val"]).replace(":", "").replace(
                ".", ""))
            if t1 < t2 <= t3:
                # 炸板时间在两次下单时间中间
                is_limit_up_buy = False
        return is_limit_up_buy
    @classmethod
    def __can_buy_first(cls, code):
        """
        是否可以下单
@@ -954,32 +984,12 @@
            # 1.当前成交价为涨停价
            # 2.距离最近的非板上成交的时间大于一个阈值
            if abs(limit_up_price - float(trade_price)) < 0.001:
                latest_exec_indexes = cls.__latest_exec_indexes[code]
                if not latest_exec_indexes:
                    latest_exec_indexes = []
                # 判断是否是炸开后买入
                last_exec_index = 0
                if len(latest_exec_indexes) > 1:
                    last_exec_index = latest_exec_indexes[-2]
                # 获取最近的非涨停价成交时间
                not_limit_up_trade_time_with_ms = current_price_process_manager.get_trade_not_limit_up_time_with_ms(
                    code)
                is_limit_up_buy = True
                if not_limit_up_trade_time_with_ms:
                    t1 = int(
                        L2DataUtil.get_time_with_ms(total_data[last_exec_index]["val"]).replace(":", "").replace(".",
                                                                                                                 ""))
                    t2 = int(not_limit_up_trade_time_with_ms.replace(":", "").replace(".", ""))
                    t3 = int(L2DataUtil.get_time_with_ms(total_data[order_begin_pos.buy_exec_index]["val"]).replace(":",
                                                                                                                    "").replace(
                        ".", ""))
                    if t1 < t2 <= t3:
                        # 炸板时间在两次下单时间中间
                        is_limit_up_buy = False
                is_limit_up_buy = cls.__is_on_limit_up_buy(code, order_begin_pos.buy_exec_index)
                if is_limit_up_buy:
                    # 板上买且非加绿
                    # 获取最近的非涨停价成交时间
                    not_limit_up_trade_time_with_ms = current_price_process_manager.get_trade_not_limit_up_time_with_ms(
                        code)
                    # 判断成交进度到当前数据的笔数,如果少于10笔且还有未成交的大单(>=299)就可以下单
                    trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code)
                    if trade_index is None:
@@ -1726,7 +1736,7 @@
                start = None
        return None
    # 计算激进买的下单信号
    # 计算积极买的下单信号
    @classmethod
    def __compute_active_order_begin_pos(cls, code, continue_count, start_index, end_index):
        """
@@ -1824,6 +1834,50 @@
        return False, -1, "未获取到激进买的起始信号", '', OrderBeginPosInfo.MODE_NORMAL
    # 计算激进买的下单信号
    @classmethod
    def __compute_radical_order_begin_pos(cls, code, start_index, end_index):
        """
        计算激进买入信号:
        1.非板上放量
        2.检测到299万大单买入
        @param code:
        @param start_index:
        @param end_index:
        @return: (是否获取到信号, 信号位置)
        """
        # 激进买信号的时间
        radical_data = RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.get(code)
        if not radical_data:
            return False, None, "不满足激进买的条件"
        if t.time() > radical_data[0]:
            return False, None, "超过生效时间"
        # 判断是否是板上放量
        if cls.__is_on_limit_up_buy(code, start_index):
            return False, None, "板上放量"
        total_datas = local_today_datas[code]
        min_num = int(29900 / gpcode_manager.get_limit_up_price_as_num(code))
        single_index = None
        for i in range(start_index, end_index + 1):
            data = total_datas[i]
            val = data["val"]
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            if val["num"] < min_num:
                continue
            if int(val["orderNo"]) <= radical_data[1]:
                # 主动买单后的数据不算
                continue
            single_index = i
            break
        if single_index is not None:
            return True, single_index, "有大单"
        return False, None, "无大单"
    @classmethod
    def test__compute_active_order_begin_pos(cls, code, continue_count, start_index, end_index):
        return cls.__compute_active_order_begin_pos(code, continue_count, start_index, end_index)
l2/l2_transaction_data_manager.py
@@ -569,7 +569,7 @@
                # 是否是涨停
                if d[1] == limit_up_price:
                    # 有涨停主动买
                    L2TradeSingleDataManager.set_limit_up_active_buy(code, datas[-1][3])
                    L2TradeSingleDataManager.set_limit_up_active_buy(code, datas[-1][3], datas[-1][6])
                    break
        except:
            pass
l2/place_order_single_data_manager.py
@@ -203,10 +203,12 @@
        @return:
        """
    def OnLimitUpActiveBuy(self, code, huaxin_timestamp):
    def OnLimitUpActiveBuy(self, code, huaxin_timestamp, buy_no):
        """
        涨停主动买触发
         涨停主动买触发
        @param code:
        @param huaxin_timestamp:
        @param buy_no:
        @return:
        """
@@ -274,8 +276,8 @@
        #     cls.__callback.OnTradeSingle(code, 0, cls.TYPE_ACTIVE, cls.__latest_sell_active_deal_data_dict[code])
    @classmethod
    def set_limit_up_active_buy(cls, code, huaxin_timestamp):
        cls.__callback.OnLimitUpActiveBuy(code, huaxin_timestamp)
    def set_limit_up_active_buy(cls, code, huaxin_timestamp, buy_no):
        cls.__callback.OnLimitUpActiveBuy(code, huaxin_timestamp, buy_no)
    @classmethod
    def get_valid_trade_single(cls, code, latest_time_with_ms):
servers/huaxin_trade_server.py
@@ -29,6 +29,7 @@
from l2.huaxin import huaxin_target_codes_manager, l2_huaxin_util
from l2.huaxin.huaxin_target_codes_manager import HuaXinL1TargetCodesManager
from l2.l2_data_manager import TradePointManager, OrderBeginPosInfo
from l2.l2_data_manager_new import L2TradeDataProcessor
from l2.l2_data_util import L2DataUtil
from l2.l2_sell_manager import L2MarketSellManager
from l2.l2_transaction_data_manager import HuaXinSellOrderStatisticManager, BigOrderDealManager
@@ -48,6 +49,7 @@
    huaxin_trade_record_manager, huaxin_sell_util
from api.outside_api_command_callback import OutsideApiCommandCallback
from trade.sell.sell_rule_manager import TradeRuleManager
from trade.trade_data_manager import RadicalBuyDealCodesManager
from trade.trade_manager import CodesTradeStateManager
from utils import socket_util, middle_api_protocol, tool, huaxin_util, global_util
@@ -655,6 +657,7 @@
            if huaxin_util.is_deal(order_status):
                if int(str(data["direction"])) == huaxin_util.TORA_TSTP_D_Buy:
                    l2_trade_util.forbidden_trade(data["securityID"], msg="已成交", force=True)
                    RadicalBuyDealCodesManager().add_deal_code(data["securityID"])
                # 成交,更新成交列表与资金列表
                huaxin_trade_data_update.add_deal_list()
                huaxin_trade_data_update.add_money_list()
@@ -668,6 +671,9 @@
class MyL2TradeSingleCallback(L2TradeSingleCallback):
    # 积极买板块计算结果缓存:{"code",(有效时间, 结果)}
    __radical_buy_by_blocks_result_cache = {}
    def OnTradeSingle(self, code, big_buy_order_count, _type, data):
        # 只处理深证的票
        try:
@@ -757,44 +763,82 @@
        except Exception as e:
            logger_debug.exception(e)
    def OnLimitUpActiveBuy(self, code, huaxin_timestamp):
    def OnLimitUpActiveBuy(self, code, huaxin_timestamp, buy_no):
        try:
            # 判断最近60个交易日有无涨停
            # 判断昨日是否涨停过
            async_log_util.info(logger_l2_radical_buy, f"涨停主动买:{code}-{huaxin_timestamp}")
            deal_codes = RadicalBuyDealCodesManager().get_deal_codes()
            if len(deal_codes) >= 2:
                async_log_util.info(logger_l2_radical_buy, f"成交代码个数大于2个:{code}-{deal_codes}")
                return
            if code in deal_codes:
                async_log_util.info(logger_l2_radical_buy, f"该代码已经成交:{code}")
                return
            k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
            if k_format and k_format[13] and not k_format[14]:
                # 判断是否有大单,判断最近的主动买占了总买额的多少
                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}")
                refer_sell_time = refer_sell_data[0]
                # 获取最近的主动买成交量
                deal_infos = HuaXinSellOrderStatisticManager.get_latest_6s_active_buy_deal_volumes(code)
                async_log_util.info(logger_l2_radical_buy, f"最近主动买成交:{code}-{deal_infos}")
                if refer_sell_data:  # and refer_sell_data[1] > 100 * 1e4:
                    # 总卖额要大于100w
                    deal_volume = 0
                    for i in range(0, len(deal_infos)):
                        # >=统计到的总卖
                        if int(refer_sell_time.replace(":", "")) > int(deal_infos[i][0].replace(":", "")):
                            break
                        deal_volume += deal_infos[i][1]
                    async_log_util.info(logger_l2_radical_buy, f"成交量:{deal_volume}/{refer_sell_data[2]}")
                    # 判断参考时间之后是否有大单成交
                    big_deal_money_list = BigOrderDealManager().get_total_buy_money_list(code)
                    if len(big_deal_money_list) > 0 or True:
                        # 有大单成交
                        yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes()
                        if yesterday_codes is None:
                            yesterday_codes = set()
                        result = RadicalBuyBlockManager.is_radical_buy(code, yesterday_codes)
                        if result[0]:
                            if refer_sell_data[1] < 500 * 1e4:
                                async_log_util.info(logger_l2_radical_buy, f"不能扫:{code}-总卖额偏少{refer_sell_data[1]}/500w")
                            else:
                                async_log_util.info(logger_l2_radical_buy, f"可以扫:{code}-{result}")
                        async_log_util.info(logger_l2_radical_buy, f"计算板块结果:{code}-{result}")
                # 获取激进买的板块
                result = self.__radical_buy_by_blocks_result_cache.get(code)
                if not result or result[0] < time.time():
                    yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes()
                    if yesterday_codes is None:
                        yesterday_codes = set()
                    result = RadicalBuyBlockManager.is_radical_buy(code, yesterday_codes)
                    async_log_util.info(logger_l2_radical_buy, f"计算板块结果:{code}-{result}")
                    self.__radical_buy_by_blocks_result_cache[code] = (time.time() + 3, result)
                else:
                    # 取缓存
                    result = result[1]
                if result[0]:
                    # 有可以扫的板块
                    # 判断最近的主动买占了总买额的多少
                    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:
                            refer_sell_time = refer_sell_data[0]
                            # 获取最近的主动买成交量
                            deal_infos = HuaXinSellOrderStatisticManager.get_latest_6s_active_buy_deal_volumes(code)
                            async_log_util.info(logger_l2_radical_buy, f"最近主动买成交:{code}-{deal_infos}")
                            # 总卖额要大于100w
                            deal_volume = 0
                            for i in range(0, len(deal_infos)):
                                # >=统计到的总卖
                                if int(refer_sell_time.replace(":", "")) > int(deal_infos[i][0].replace(":", "")):
                                    break
                                deal_volume += deal_infos[i][1]
                            async_log_util.info(logger_l2_radical_buy, f"成交量:{deal_volume}/{refer_sell_data[2]}")
                            deal_rate = round(deal_volume / refer_sell_data[2], 2)
                            if deal_rate > 0.5:
                                # 判断参考时间之后是否有大单成交
                                # big_deal_money_list = BigOrderDealManager().get_total_buy_money_list(code)
                                # 成交比例大于50%
                                total_datas = l2_data_util.local_today_datas.get(code)
                                buy_single_index, buy_exec_index = total_datas[-1]["index"], total_datas[-1]["index"]
                                buy_volume_rate = L2TradeDataProcessor.volume_rate_info[code][0]
                                sell_info = (refer_sell_data[0], refer_sell_data[0])
                                threshold_money = 0
                                order_begin_pos_info = OrderBeginPosInfo(buy_single_index=buy_single_index,
                                                                         buy_exec_index=buy_exec_index,
                                                                         buy_compute_index=buy_exec_index,
                                                                         num=deal_volume // 100, count=1,
                                                                         max_num_set=set(),
                                                                         buy_volume_rate=buy_volume_rate,
                                                                         mode=OrderBeginPosInfo.MODE_RADICAL,
                                                                         mode_desc="激进买入",
                                                                         sell_info=sell_info,
                                                                         threshold_money=threshold_money)
                                L2TradeDataProcessor.save_order_begin_data(code, order_begin_pos_info)
                                L2TradeDataProcessor.start_buy(code, total_datas[-1], total_datas[-1]["index"], True)
                        else:
                            # L2委托有大单就扫
                            # 记录买入信号, 3s内有效
                            RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict[code] = (
                                time.time() + 3, buy_no)
                else:
                    volume_rate = code_volumn_manager.get_volume_rate(code)
                    async_log_util.info(logger_l2_radical_buy, f"图形不符合要求:{code},量比:{volume_rate}")
trade/trade_data_manager.py
@@ -459,5 +459,57 @@
        return self.__mysqldb.select_all(sql)
# 激进买成交代码
class RadicalBuyDealCodesManager:
    """
    激进买成交代码管理
    """
    __db = 2
    __redis_manager = redis_manager.RedisManager(2)
    __deal_codes_cache = set()
    __instance = None
    __mysqldb = Mysqldb()
    # 根据L2数据来激进买入的有效时间:{"code":(有效截至时间, 买单号)}
    buy_by_l2_delegate_expire_time_dict = {}
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(RadicalBuyDealCodesManager, cls).__new__(cls, *args, **kwargs)
            cls.__instance.__load_data()
        return cls.__instance
    @classmethod
    def __load_data(cls):
        __redis = cls.__get_redis()
        result = RedisUtils.get(cls.__get_redis(), "radical_buy_deal_codes")
        if result:
            result = json.loads(result)
            cls.__deal_codes_cache = set(result)
    @classmethod
    def __get_redis(cls):
        return cls.__redis_manager.getRedis()
    def add_deal_code(self, code):
        """
        添加已成交的代码
        @param code:
        @return:
        """
        self.__deal_codes_cache.add(code)
        RedisUtils.sadd_async(self.__db, "radical_buy_deal_codes", code)
        RedisUtils.expire_async(self.__db, "radical_buy_deal_codes", tool.get_expire())
    def get_deal_codes(self):
        """
        获取已经成交的代码
        @return:
        """
        if self.__deal_codes_cache:
            return self.__deal_codes_cache
        return set()
if __name__ == "__main__":
    print(AccountMoneyManager().get_deal_count())
trade/trade_manager.py
@@ -15,6 +15,7 @@
from db import mysql_data_delegate as mysql_data, redis_manager_delegate as redis_manager
from db.mysql_data_delegate import Mysqldb
from db.redis_manager_delegate import RedisUtils
from l2.l2_data_manager import OrderBeginPosInfo
from log_module import async_log_util
from output import kp_client_msg_manager
from trade import trade_data_manager, l2_trade_util, trade_juejin, trade_huaxin, trade_constant
@@ -24,7 +25,7 @@
from log_module.log import *
from trade.huaxin.huaxin_trade_record_manager import TradeOrderIdManager
from trade.trade_data_manager import AccountMoneyManager
from trade.trade_data_manager import AccountMoneyManager, RadicalBuyDealCodesManager
from utils import import_util, tool, huaxin_util
trade_gui = import_util.import_lib("trade.trade_gui")
@@ -300,7 +301,6 @@
    # 设置交易账户的可用金额
# 保存交易成功的数据
def save_trade_success_data(datas, day=datetime.datetime.now().strftime("%Y%m%d")):
    time_str = tool.get_now_time_str()
@@ -451,6 +451,9 @@
    try:
        if constant.API_TRADE_ENABLE:
            count = tool.get_buy_volume(price)
            if mode == OrderBeginPosInfo.MODE_RADICAL:
                # 激进买入金额为1手
                count = 100
            if constant.TRADE_WAY == constant.TRADE_WAY_JUEJIN:
                trade_juejin.order_volume(code, price, count)
            elif constant.TRADE_WAY == constant.TRADE_WAY_HUAXIN:
@@ -664,6 +667,7 @@
    # 加入黑名单
    if not l2_trade_util.is_in_forbidden_trade_codes(code):
        l2_trade_util.forbidden_trade(code, "buy success", force=True)
        RadicalBuyDealCodesManager().add_deal_code(code)
    # 取s消所有的挂单
    if constant.API_TRADE_ENABLE:
        if constant.TRADE_WAY == constant.TRADE_WAY_JUEJIN: