Administrator
2024-04-15 5adedb7c797ad08b7607c56e8255c21609c97000
新版深证下单完善
6个文件已修改
298 ■■■■■ 已修改文件
l2/l2_data_manager_new.py 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_transaction_data_manager.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/place_order_single_data_manager.py 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
log_module/log.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_server.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_result_manager.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py
@@ -1,4 +1,5 @@
import logging
import threading
import time as t
from code_attribute import big_money_num_manager, code_volumn_manager, code_data_util, industry_codes_sort, \
@@ -19,7 +20,7 @@
from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
    trade_result_manager, current_price_process_manager, trade_data_manager, trade_huaxin, trade_record_log_util
from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \
    transaction_progress, cancel_buy_strategy
    transaction_progress, cancel_buy_strategy, place_order_single_data_manager
from l2.cancel_buy_strategy import SCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \
    LCancelBigNumComputer, LatestCancelIndexManager, LCancelRateManager, GCancelBigNumComputer
from l2.l2_data_manager import L2DataException, OrderBeginPosInfo
@@ -244,6 +245,9 @@
    __MarketSituationManager = MarketSituationManager()
    __re_compute_threading_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10)
    # 买入锁
    __buy_lock_dict = {}
    # 获取代码评分
    @classmethod
    def get_code_scores(cls):
@@ -325,8 +329,8 @@
            limit_up_price = gpcode_manager.get_limit_up_price(code)
            if limit_up_price:
                limit_up_price = round(float(limit_up_price), 2)
            if trade_price_info and limit_up_price and trade_price_info[0] == limit_up_price:
                filter_limit_up_sell = True
            # if trade_price_info and limit_up_price and trade_price_info[0] == limit_up_price:
            #     filter_limit_up_sell = True
            datas = l2_huaxin_util.get_format_l2_datas(code, origin_datas, limit_up_price, _start_index,
                                                       filter_limit_up_sell)
            __start_time = round(t.time() * 1000)
@@ -399,9 +403,10 @@
                    try:
                        for d in add_datas:
                            if L2DataUtil.is_limit_up_price_sell(d['val']):
                                L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell(code,d)
                            elif  L2DataUtil.is_limit_up_price_sell_cancel(d['val']):
                                L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell_cancel(code,d['val']['orderNo'])
                                L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell(code, d)
                            elif L2DataUtil.is_limit_up_price_sell_cancel(d['val']):
                                L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell_cancel(code,
                                                                                                d['val']['orderNo'])
                    except Exception as e:
                        logger_debug.exception(e)
                except:
@@ -644,89 +649,103 @@
            pass
    @classmethod
    def start_buy(cls, code, last_data, last_data_index, is_first_code):
        cls.__buy(code, 0, last_data, last_data_index, is_first_code)
    @classmethod
    def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code):
        __start_time = tool.get_now_timestamp()
        can, need_clear_data, reason = False, False, ""
        if not is_first_code:
            can, need_clear_data, reason = cls.__can_buy(code)
        else:
            can, need_clear_data, reason = cls.__can_buy_first(code)
        # 添加买入锁
        if code not in cls.__buy_lock_dict:
            cls.__buy_lock_dict[code] = threading.Lock()
        # __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)
        with cls.__buy_lock_dict[code]:
            # 判断是否可以下单,不处于可下单状态需要返回
            state = cls.__CodesTradeStateManager.get_trade_state_cache(code)
            if state == trade_manager.TRADE_STATE_BUY_DELEGATED or state == trade_manager.TRADE_STATE_BUY_PLACE_ORDER or state == trade_manager.TRADE_STATE_BUY_SUCCESS:
                # 不处于可下单状态
                return False
            __start_time = tool.get_now_timestamp()
            can, need_clear_data, reason = False, False, ""
            if not is_first_code:
                can, need_clear_data, reason = cls.__can_buy(code)
            else:
                can, need_clear_data, reason = cls.__can_buy_first(code)
        order_begin_pos = cls.__get_order_begin_pos(
            code)
        if not can:
            l2_log.debug(code, "不可以下单,原因:{}", reason)
            trade_record_log_util.add_cant_place_order_log(code, reason)
            if need_clear_data:
                trade_result_manager.real_cancel_success(code, order_begin_pos.buy_single_index,
                                                         order_begin_pos.buy_exec_index,
                                                         local_today_datas.get(code))
            return False
        else:
            l2_log.debug(code, "可以下单,原因:{}", reason)
            try:
                l2_log.debug(code, "开始执行买入")
                trade_manager.start_buy(code, capture_timestamp, last_data,
                                        last_data_index, order_begin_pos.mode, order_begin_pos.buy_exec_index)
                l2_log.debug(code, "执行买入成功")
                ################下单成功处理################
                trade_result_manager.real_buy_success(code, cls.__TradePointManager)
                l2_log.debug(code, "处理买入成功1")
                cancel_buy_strategy.set_real_place_position(code, local_today_datas.get(code)[-1]["index"],
                                                            order_begin_pos.buy_single_index, is_default=True)
                l2_log.debug(code, "处理买入成功2")
                params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc()
                l2_log.debug(code, params_desc)
                ############记录下单时的数据############
            # __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:
                l2_log.debug(code, "不可以下单,原因:{}", reason)
                trade_record_log_util.add_cant_place_order_log(code, reason)
                if need_clear_data:
                    trade_result_manager.real_cancel_success(code, order_begin_pos.buy_single_index,
                                                             order_begin_pos.buy_exec_index,
                                                             local_today_datas.get(code))
                return False
            else:
                l2_log.debug(code, "可以下单,原因:{}", reason)
                try:
                    jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache(
                        code), KPLCodeJXBlockManager().get_jx_blocks_cache(code, by=True)
                    if jx_blocks:
                        jx_blocks = jx_blocks[0]
                    if jx_blocks_by:
                        jx_blocks_by = jx_blocks_by[0]
                    l2_log.debug(code, "开始执行买入")
                    trade_manager.start_buy(code, capture_timestamp, last_data,
                                            last_data_index, order_begin_pos.mode, order_begin_pos.buy_exec_index)
                    l2_log.debug(code, "执行买入成功")
                    ################下单成功处理################
                    trade_result_manager.real_buy_success(code, cls.__TradePointManager)
                    l2_log.debug(code, "处理买入成功1")
                    cancel_buy_strategy.set_real_place_position(code, local_today_datas.get(code)[-1]["index"],
                                                                order_begin_pos.buy_single_index, is_default=True)
                    l2_log.debug(code, "处理买入成功2")
                    params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc()
                    l2_log.debug(code, params_desc)
                    ############记录下单时的数据############
                    try:
                        jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache(
                            code), KPLCodeJXBlockManager().get_jx_blocks_cache(code, by=True)
                        if jx_blocks:
                            jx_blocks = jx_blocks[0]
                        if jx_blocks_by:
                            jx_blocks_by = jx_blocks_by[0]
                    info = cls.__trade_log_placr_order_info_dict[code]
                    info.mode = order_begin_pos.mode
                    info.set_buy_index(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
                    info.set_sell_info(order_begin_pos.sell_info)
                    if jx_blocks:
                        info.set_kpl_blocks(list(jx_blocks))
                    elif jx_blocks_by:
                        info.set_kpl_blocks(list(jx_blocks_by))
                    else:
                        info.set_kpl_blocks([])
                    can_buy_result = CodePlateKeyBuyManager.can_buy(code)
                    if can_buy_result:
                        if not can_buy_result[0] and can_buy_result[1]:
                            info.set_kpl_match_blocks(["独苗"])
                        elif not can_buy_result[0] and not can_buy_result[1]:
                            info.set_kpl_match_blocks(["非独苗不满足身位"])
                        info = cls.__trade_log_placr_order_info_dict[code]
                        info.mode = order_begin_pos.mode
                        info.set_buy_index(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index)
                        info.set_sell_info(order_begin_pos.sell_info)
                        if jx_blocks:
                            info.set_kpl_blocks(list(jx_blocks))
                        elif jx_blocks_by:
                            info.set_kpl_blocks(list(jx_blocks_by))
                        else:
                            temps = []
                            temps.extend(can_buy_result[0])
                            if can_buy_result[5]:
                                temps.append(f"激进买入:{can_buy_result[5]}")
                            info.set_kpl_match_blocks(temps)
                    trade_record_log_util.add_place_order_log(code, info)
                            info.set_kpl_blocks([])
                        can_buy_result = CodePlateKeyBuyManager.can_buy(code)
                        if can_buy_result:
                            if not can_buy_result[0] and can_buy_result[1]:
                                info.set_kpl_match_blocks(["独苗"])
                            elif not can_buy_result[0] and not can_buy_result[1]:
                                info.set_kpl_match_blocks(["非独苗不满足身位"])
                            else:
                                temps = []
                                temps.extend(can_buy_result[0])
                                if can_buy_result[5]:
                                    temps.append(f"激进买入:{can_buy_result[5]}")
                                info.set_kpl_match_blocks(temps)
                        trade_record_log_util.add_place_order_log(code, info)
                    except Exception as e:
                        async_log_util.error(logger_l2_error, f"加入买入记录日志出错:{str(e)}")
                except Exception as e:
                    async_log_util.error(logger_l2_error, f"加入买入记录日志出错:{str(e)}")
            except Exception as e:
                async_log_util.exception(logger_l2_error, e)
                l2_log.debug(code, "执行买入异常:{}", str(e))
                pass
            finally:
                # l2_log.debug(code, "m值影响因子:{}", l2_trade_factor.L2TradeFactorUtil.factors_to_string(code))
                pass
            return True
                    async_log_util.exception(logger_l2_error, e)
                    l2_log.debug(code, "执行买入异常:{}", str(e))
                    pass
                finally:
                    # l2_log.debug(code, "m值影响因子:{}", l2_trade_factor.L2TradeFactorUtil.factors_to_string(code))
                    pass
                return True
    # 是否可以取消
    @classmethod
@@ -1335,6 +1354,8 @@
                order_begin_pos.mode = OrderBeginPosInfo.MODE_ACTIVE
                order_begin_pos.sell_info = sell_info
                fast_msg = sell_info
                # 用了信号就必须清除掉原有信号
                place_order_single_data_manager.L2TradeSingleDataManager.clear_data(code)
            # if not has_single:
            #     # 第二步:计算闪电下单信号
@@ -1680,19 +1701,20 @@
            if code.find("60") == 0:
                threshold_money = 0
            else:
                for i in range(start_index - 1, -1, -1):
                    val = total_datas[i]["val"]
                    if tool.compare_time(val["time"], refer_sell_data[0]) < 0:
                        # 将本s的计算上去
                        break
                    if L2DataUtil.is_sell(val):
                        threshold_money += val["num"] * int(float(val["price"]) * 100)
                    elif L2DataUtil.is_sell_cancel(val):
                        threshold_money -= val["num"] * int(float(val["price"]) * 100)
                    elif L2DataUtil.is_buy(val):
                        # 判断价格(大于卖1) 被买吃掉
                        if round(float(val["price"]), 2) - sell_1_price >= 0:
                            threshold_money -= val["num"] * int(float(val["price"]) * 100)
                pass
                # for i in range(start_index - 1, -1, -1):
                #     val = total_datas[i]["val"]
                #     if tool.compare_time(val["time"], refer_sell_data[0]) < 0:
                #         # 将本s的计算上去
                #         break
                #     if L2DataUtil.is_sell(val):
                #         threshold_money += val["num"] * int(float(val["price"]) * 100)
                #     elif L2DataUtil.is_sell_cancel(val):
                #         threshold_money -= val["num"] * int(float(val["price"]) * 100)
                #     elif L2DataUtil.is_buy(val):
                #         # 判断价格(大于卖1) 被买吃掉
                #         if round(float(val["price"]), 2) - sell_1_price >= 0:
                #             threshold_money -= val["num"] * int(float(val["price"]) * 100)
            # 第二步:计算起始信号
            second_930 = 9 * 3600 + 30 * 60 + 0
            total_datas = local_today_datas.get(code)
@@ -1712,6 +1734,14 @@
                    if _val["num"] * float(_val["price"]) < 5000:
                        continue
                    if last_index is None or (total_datas[last_index]["val"]["time"] == total_datas[i]["val"]["time"]):
                        single = place_order_single_data_manager.L2TradeSingleDataManager.get_valid_trade_single(code,
                                                                                                                 tool.to_time_with_ms(
                                                                                                                     _val[
                                                                                                                         'time'],
                                                                                                                     _val[
                                                                                                                         'tms']))
                        if not single:
                            continue
                        if start is None:
                            start = i
                        last_index = i
@@ -2103,6 +2133,11 @@
        trigger_buy = True
        # 间隔最大时间为3s
        max_space_time_ms = 3 * 1000
        if code.find("00") == 0 and threshold_money > 0:
            # 深证非板上放量
            max_space_time_ms = 1 * 1000
            threshold_num = 0
        # 不下单的信息
        not_buy_msg = ""
        max_buy_num_set = set(max_num_set)
@@ -2121,12 +2156,12 @@
                    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, threshold_money, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms"
            if L2DataUtil.is_sell(_val):
                threshold_money += _val["num"] * int(float(_val["price"]) * 100)
                threshold_num = round(threshold_money / (limit_up_price * 100))
            elif L2DataUtil.is_sell_cancel(_val):
                threshold_money -= _val["num"] * int(float(_val["price"]) * 100)
                threshold_num = round(threshold_money / (limit_up_price * 100))
            # if L2DataUtil.is_sell(_val):
            #     threshold_money += _val["num"] * int(float(_val["price"]) * 100)
            #     threshold_num = round(threshold_money / (limit_up_price * 100))
            # elif L2DataUtil.is_sell_cancel(_val):
            #     threshold_money -= _val["num"] * int(float(_val["price"]) * 100)
            #     threshold_num = round(threshold_money / (limit_up_price * 100))
            # 涨停买
            elif L2DataUtil.is_limit_up_price_buy(_val):
                if l2_data_util.is_big_money(_val):
@@ -2186,6 +2221,9 @@
            if threshold_money <= 0:
                # 板上下单需要安全笔数3笔
                safe_count = 3
            elif code.find("00") == 0:
                # 深证非板上放量
                safe_count = 2
            if buy_count < safe_count:
                not_buy_msg = f"【{i}】安全笔数不足,{buy_count}/{safe_count}"
l2/l2_transaction_data_manager.py
@@ -11,7 +11,7 @@
from l2.place_order_single_data_manager import L2TradeSingleDataProcessor, L2TradeSingleDataManager
from log_module import async_log_util
from log_module.log import hx_logger_l2_transaction_desc, hx_logger_l2_transaction_sell_order
from log_module.log import hx_logger_l2_transaction_desc, hx_logger_l2_transaction_sell_order, hx_logger_l2_active_sell
from utils import tool
@@ -152,6 +152,10 @@
                if not _is_active_sell:
                    continue
                if d[1] == limit_up_price:
                    # 涨停主动卖
                    L2TradeSingleDataProcessor.add_active_limit_up_sell_data(d)
                # 判断是否是涨停被动变主动
                last_trade_data = cls.__last_trade_data_dict.get(code)
                if last_trade_data and not is_active_sell(last_trade_data[7], last_trade_data[6]) and last_trade_data[
@@ -185,6 +189,9 @@
                        # 只保留10w以上的单
                        if money > 100000:
                            cls.__latest_all_sell_orders_dict[code].append(info)
                        if limit_up_price == info[2]:
                            # 将涨停主动卖记入日志
                            l2_log.info(code, hx_logger_l2_active_sell, f"{info}")
                        cls.__latest_sell_order_dict[code] = [d[7], d[2], d[1], (d[3], d[6]), (d[3], d[6])]
            finally:
l2/place_order_single_data_manager.py
@@ -17,6 +17,9 @@
    __latest_limit_up_sell_order_no_set_dict = {}
    # 主动卖订单号集合
    __active_sell_order_no_set_dict = {}
    @classmethod
    def add_l2_delegate_limit_up_sell(cls, code, data):
        """
@@ -86,6 +89,12 @@
            if not sell_list:
                return
            sell_info = sell_list[-1]
            # 主动卖订单集合
            active_sell_order_no_set = cls.__active_sell_order_no_set_dict.get(code)
            if active_sell_order_no_set and sell_info['val']['orderNo'] in active_sell_order_no_set:
                l2_log.info(code, logger_l2_trade_buy,f"最近的卖是主动卖:{sell_info['val']['orderNo']}")
                return
            sell_info_num = sell_info['val']['num']
            deal_num = cls.__latest_sell_data[code][1] // 100
@@ -97,6 +106,23 @@
                l2_log.info(code, logger_l2_trade_buy, f"{code}#找到最近的被动涨停卖单数据:{sell_info['val']['orderNo']}, 可以触发下单")
                # l2_log.info(code, logger_l2_trade_buy, f"找到最近的被动涨停卖单数据:{data['val']['orderNo']}, 可以触发下单")
        except Exception as e:
            logger_debug.exception(e)
    @classmethod
    def add_active_limit_up_sell_data(cls, data):
        """
        添加主动卖数据
        @param data:
        @return:
        """
        try:
            code = data[0]
            sell_no = data[7]
            if code not in cls.__active_sell_order_no_set_dict:
                cls.__active_sell_order_no_set_dict[code] = set()
            cls.__active_sell_order_no_set_dict[code].add(sell_no)
        except Exception as e:
            logger_debug.exception(e)
@@ -149,7 +175,7 @@
        # 生效时间在1s以内
        cls.__latest_sell_data_dict[code] = (data, tool.trade_time_add_millionsecond(deal_time, 1000))
        if cls.__callback:
            cls.__callback.OnTradeSingle(code, cls.__latest_sell_data_dict[code])
            cls.__callback.OnTradeSingle(code, cls.TYPE_PASSIVE, cls.__latest_sell_data_dict[code])
    @classmethod
    def set_sell_passive_to_active_datas(cls, code, passive_data, active_data):
@@ -166,7 +192,7 @@
        cls.__latest_sell_active_deal_data_dict[code] = (
            active_data, tool.trade_time_add_millionsecond(deal_time, 1000))
        if cls.__callback:
            cls.__callback.OnTradeSingle(code, cls.__latest_sell_active_deal_data_dict[code])
            cls.__callback.OnTradeSingle(code, cls.TYPE_ACTIVE, cls.__latest_sell_active_deal_data_dict[code])
    @classmethod
    def get_valid_trade_single(cls, code, latest_time_with_ms):
log_module/log.py
@@ -251,6 +251,9 @@
        logger.add(self.get_hx_path("trade", "trade_loop"),
                   filter=lambda record: record["extra"].get("name") == "hx_trade_loop",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(self.get_hx_path("trade", "l2_active_sell"),
                   filter=lambda record: record["extra"].get("name") == "hx_l2_active_sell",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(self.get_local_huaxin_path("l2", "transaction"),
                   filter=lambda record: record["extra"].get("name") == "local_huaxin_transaction",
@@ -411,6 +414,7 @@
hx_logger_trade_callback = __mylogger.get_logger("hx_trade_callback")
hx_logger_trade_debug = __mylogger.get_logger("hx_trade_debug")
hx_logger_trade_loop = __mylogger.get_logger("hx_trade_loop")
hx_logger_l2_active_sell = __mylogger.get_logger("hx_l2_active_sell")
# -------------------------------华鑫本地日志---------------------------------
logger_local_huaxin_l2_transaction = __mylogger.get_logger("local_huaxin_transaction")
trade/huaxin/huaxin_trade_server.py
@@ -1709,6 +1709,9 @@
class MyL2TradeSingleCallback(L2TradeSingleCallback):
    def OnTradeSingle(self, code, _type, data):
        # 只处理深证的票
        if code.find("00")!=0:
            return
        try:
            # 判断是否下单
            state = CodesTradeStateManager().get_trade_state_cache(code)
@@ -1718,7 +1721,7 @@
                return
            # 找到最近的大买单
            total_datas = l2_data_util.local_today_datas.get(code)
            for i in range(len(total_datas)-1,-1,-1):
            for i in range(len(total_datas) - 1, -1, -1):
                d = total_datas[i]
                val = d['val']
                if not L2DataUtil.is_limit_up_price_buy(val):
@@ -1727,12 +1730,12 @@
                    continue
                if val['orderNo'] < data[0][6]:
                    continue
                result = L2TradeSingleDataManager.is_can_place_order(code,d)
                result = L2TradeSingleDataManager.is_can_place_order(code, d)
                if result and result[0]:
                    l2_log.info(code,logger_l2_trade_buy,f"触发下单:{result[1]}")
                    l2_log.info(code, logger_l2_trade_buy, f"触发下单:{result[1]}")
                    l2_data_manager_new.L2TradeDataProcessor.start_buy(code,total_datas[-1],total_datas[-1]["index"],True)
        except Exception as e:
            logger_debug.exception(e)
# 回调
trade/trade_result_manager.py
@@ -2,7 +2,7 @@
import logging
from code_attribute.gpcode_manager import MustBuyCodesManager
from l2 import l2_data_manager
from l2 import l2_data_manager, place_order_single_data_manager
from l2.cancel_buy_strategy import HourCancelBigNumComputer, SCancelBigNumComputer, \
    LCancelBigNumComputer, DCancelBigNumComputer, GCancelBigNumComputer, FCancelBigNumComputer
from l2.l2_data_manager import OrderBeginPosInfo
@@ -93,6 +93,8 @@
    PlaceOrderCountManager().place_order(code)
    # 下单成功之后移除红名单
    MustBuyCodesManager().remove_code(code)
    # 清除下单信号
    place_order_single_data_manager.L2TradeSingleDataManager.clear_data(code)
__latest_cancel_l2_data_dict = {}