Administrator
4 天以前 24483098305c456c37d0dab1bc7b6908e55af11b
D撤重新生效
8个文件已修改
278 ■■■■■ 已修改文件
cancel_strategy/s_l_h_cancel_strategy.py 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/constant.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/trade_client.py 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/cancel_buy_strategy.py 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
log_module/log.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
log_module/log_export.py 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
servers/huaxin_trade_server.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cancel_strategy/s_l_h_cancel_strategy.py
@@ -15,9 +15,9 @@
from log_module import async_log_util
from third_data import code_plate_key_manager
from trade.buy_radical import radical_buy_data_manager
from utils import tool
from utils import tool, trade_util
from l2.transaction_progress import TradeBuyQueue
from trade import l2_trade_factor, trade_record_log_util, trade_constant
from trade import l2_trade_factor, trade_record_log_util, trade_constant, trade_manager
from l2 import l2_log, l2_data_source_util
from l2.l2_data_util import L2DataUtil, local_today_datas, local_today_canceled_buyno_map, local_today_buyno_map
from log_module.log import logger_l2_s_cancel, logger_debug, logger_l2_l_cancel, logger_l2_h_cancel
@@ -2886,5 +2886,62 @@
        self.__compute_watch_index(code, buy_single_index)
# ---------------------------------D撤-------------------------------
# 计算 成交位->真实下单位置 总共还剩下多少手没有撤单
# 成交位变化之后重新计算
class DCancelBigNumComputer:
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(DCancelBigNumComputer, cls).__new__(cls, *args, **kwargs)
        return cls.__instance
    def need_cancel(self, code, buy1_info, limit_up_price, time_str):
        """
        是否需要撤单
        @param limit_up_price:
        @param code:
        @param buy1_info:(买1价, 买1量)
        @param time_str: 时间字符串
        @return:
        """
        # 获取是否处于下单状态
        trade_state = trade_manager.CodesTradeStateManager().get_trade_state_cache(code)
        if not trade_util.is_delegated(trade_state):
            return False, "尚未下单"
        if abs(limit_up_price - buy1_info[0]) >= 0.001:
            return False, "非涨停价"
        # 是否小于3000w
        if buy1_info[0] * buy1_info[1] > 3000e4:
            return False, "封单额大于3000w"
        # 获取下单时间
        place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
        if not place_order_index:
            return False, "没获取到真实下单位置"
        total_datas = local_today_datas.get(code)
        # 买1时间要大于下单时间
        if total_datas[place_order_index]['val']['time'] >= time_str:
            return False, "L1时间<=下单时间"
        human_rate = CancelRateHumanSettingManager().get_l_down(code)
        if human_rate and human_rate > 0.7:
            return False, "人为设置撤单比例大于0.7"
        volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code)
        if volume_rate <= 0.4 and tool.trade_time_sub(time_str, total_datas[place_order_index]['val']['time']) <= 6:
            return True, f"量比({volume_rate})<=40%且在挂单6s内,封单额≤3000万"
        if 6 < tool.trade_time_sub(time_str, total_datas[place_order_index]['val']['time']) <= 10*60:
            return True, f"下单后10分钟内,封单额≤3000万"
        return False, '无撤单条件'
if __name__ == "__main__":
    CancelRateHumanSettingManager()
huaxin_client/constant.py
@@ -16,3 +16,5 @@
L2_CODES_INFO_PATH = "/home/userzjj/logs/l2_codes.txt"
# 影子订单的量
SHADOW_ORDER_VOLUME = 100
# 启用虚拟账户
ENABLE_VIRTUAL_ACCOUNT = True
huaxin_client/trade_client.py
@@ -9,7 +9,7 @@
import zmq
from huaxin_client import command_manager
from huaxin_client import command_manager, huaxin_sinfo_util
from huaxin_client import constant
from huaxin_client import socket_util
import traderapi
@@ -17,12 +17,12 @@
from huaxin_client.log import logger
# 正式账号
from huaxin_client.trade_transform_protocol import TradeRequest, TradeResponse
from log_module import async_log_util
from log_module.log import logger_local_huaxin_trade_debug, logger_system, logger_trade
from utils import tool
from log_module.log import logger_local_huaxin_trade_debug, logger_system, logger_trade, logger_debug
########B类########
from utils import tool
UserID = '388000013349'
# 登陆密码
Password = '110808'
@@ -627,6 +627,7 @@
        self.__temp_money_account_list_dict = {}
        self.__temp_order_found_list_dict = {}
        self.call_back_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10)
        self.own_order_local_ids = set()
    def OnFrontConnected(self) -> "void":
        logger.info('OnFrontConnected')
@@ -814,6 +815,29 @@
    def OnRtnOrder(self, pOrderField: "CTORATstpOrderField") -> "void":
        try:
            # TODO
            # if constant.ENABLE_VIRTUAL_ACCOUNT and not huaxin_sinfo_util.is_own_channel(pOrderField.SInfo):
            #     # 非自有渠道的单
            #     return
            order_data = {"sinfo": pOrderField.SInfo, "securityID": pOrderField.SecurityID,
                          "orderLocalID": pOrderField.OrderLocalID,
                          "direction": pOrderField.Direction, "orderSysID": pOrderField.OrderSysID,
                          "insertTime": pOrderField.InsertTime, "insertDate": pOrderField.InsertDate,
                          "acceptTime": pOrderField.AcceptTime, "cancelTime": pOrderField.CancelTime,
                          "limitPrice": pOrderField.LimitPrice, "accountID": pOrderField.AccountID,
                          "orderRef": pOrderField.OrderRef, "turnover": pOrderField.Turnover,
                          "volume": pOrderField.VolumeTotalOriginal, "volumeTraded": pOrderField.VolumeTraded,
                          "orderStatus": pOrderField.OrderStatus,
                          "orderSubmitStatus": pOrderField.OrderSubmitStatus,
                          "statusMsg": pOrderField.StatusMsg, "volumeCanceled": pOrderField.VolumeCanceled,
                          "localUpdateTime": int(time.time() * 1000000)}
            try:
                if huaxin_sinfo_util.is_own_channel(pOrderField.SInfo):
                    self.own_order_local_ids.add(pOrderField.OrderLocalID)
                    async_log_util.info(logger_local_huaxin_trade_debug, f"添加自有订单号:{pOrderField.OrderLocalID}")
            except Exception as e:
                logger_debug.exception(e)
            async_log_util.info(logger_local_huaxin_trade_debug,
                                '[%d] OnRtnOrder: SInfo[%s] InvestorID[%s] SecurityID[%s] OrderRef[%d] OrderLocalID[%s] LimitPrice[%.2f] VolumeTotalOriginal[%d] OrderSysID[%s] OrderStatus[%s] InsertTime[%s]'
                                % (round(time.time() * 1000), pOrderField.SInfo, pOrderField.InvestorID,
@@ -823,24 +847,7 @@
                                   pOrderField.OrderStatus, pOrderField.InsertTime))
            if pOrderField.OrderStatus == traderapi.TORA_TSTP_OST_Unknown:
                pass
            #     if queue_trade_w_l2_r is not None:
            #         queue_trade_w_l2_r.put_nowait(
            #             json.dumps({"type": "listen_volume", "data": {"code": pOrderField.SecurityID,
            #                                                           "volume": pOrderField.VolumeTotalOriginal}}).encode(
            #                 'utf-8'))
            else:
                order_data = {"sinfo": pOrderField.SInfo, "securityID": pOrderField.SecurityID,
                              "orderLocalID": pOrderField.OrderLocalID,
                              "direction": pOrderField.Direction, "orderSysID": pOrderField.OrderSysID,
                              "insertTime": pOrderField.InsertTime, "insertDate": pOrderField.InsertDate,
                              "acceptTime": pOrderField.AcceptTime, "cancelTime": pOrderField.CancelTime,
                              "limitPrice": pOrderField.LimitPrice, "accountID": pOrderField.AccountID,
                              "orderRef": pOrderField.OrderRef, "turnover": pOrderField.Turnover,
                              "volume": pOrderField.VolumeTotalOriginal, "volumeTraded": pOrderField.VolumeTraded,
                              "orderStatus": pOrderField.OrderStatus,
                              "orderSubmitStatus": pOrderField.OrderSubmitStatus,
                              "statusMsg": pOrderField.StatusMsg, "volumeCanceled": pOrderField.VolumeCanceled,
                              "localUpdateTime": int(time.time()*1000)}
                self.call_back_thread_pool.submit(self.__data_callback, TYPE_ORDER, 0, order_data)
        except Exception as e:
            async_log_util.error(logger_local_huaxin_trade_debug, "OnRtnOrder 出错")
@@ -849,11 +856,20 @@
    def OnRtnTrade(self, pTradeField: "CTORATstpTradeField") -> "void":
        try:
            # if constant.ENABLE_VIRTUAL_ACCOUNT and pTradeField.OrderLocalID not in self.own_order_local_ids:
            #     # 非自有渠道的单
            #     return
            async_log_util.info(logger_local_huaxin_trade_debug,
                                'OnRtnTrade: TradeID[%s] InvestorID[%s] SecurityID[%s] OrderRef[%d] OrderLocalID[%s] Price[%.2f] Volume[%d]'
                                % (pTradeField.TradeID, pTradeField.InvestorID, pTradeField.SecurityID,
                                   pTradeField.OrderRef, pTradeField.OrderLocalID, pTradeField.Price,
                                   pTradeField.Volume))
            trade_data = {
                "direction": pTradeField.Direction, "orderSysID": pTradeField.OrderSysID,
                "securityID": pTradeField.SecurityID,
                "tradeID": pTradeField.TradeID, "orderLocalID": pTradeField.OrderLocalID, "price": pTradeField.Price,
                "volume": pTradeField.Volume, "tradeDate": pTradeField.TradeDate, "tradeTime": pTradeField.TradeTime
            }
        except:
            pass
@@ -962,6 +978,8 @@
            if nRequestID not in self.__temp_order_list_dict:
                self.__temp_order_list_dict[nRequestID] = []
            if not bIsLast:
                if huaxin_sinfo_util.is_own_channel(pOrderField.SInfo):
                    self.own_order_local_ids.add(pOrderField.OrderLocalID)
                # logger.info(
                #     'OnRspQryOrder[%d]: SecurityID[%s] OrderLocalID[%s] Direction[%s] OrderRef[%d] OrderSysID[%s] VolumeTraded[%d] OrderStatus[%s] OrderSubmitStatus[%s], StatusMsg[%s]'
                #     % (nRequestID, pOrderField.SecurityID, pOrderField.OrderLocalID, pOrderField.Direction,
l2/cancel_buy_strategy.py
@@ -20,7 +20,7 @@
from l2.l2_transaction_data_manager import HuaXinBuyOrderManager, HuaXinSellOrderStatisticManager
from trade.sell.sell_rule_manager import TradeRuleManager
from utils import tool
from utils import tool, trade_util
from l2.transaction_progress import TradeBuyQueue
from trade import trade_queue_manager, l2_trade_factor, trade_manager, trade_data_manager
from l2 import l2_log, l2_data_source_util, code_price_manager
@@ -176,71 +176,6 @@
                if total_datas[index]["val"]["orderNo"] not in deal_order_nos:
                    return True
            return False
# ---------------------------------D撤-------------------------------
# 计算 成交位->真实下单位置 总共还剩下多少手没有撤单
# 成交位变化之后重新计算
class DCancelBigNumComputer:
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __instance = None
    # 下单位之后的封单中的大单
    __follow_big_order_cache = {}
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(DCancelBigNumComputer, cls).__new__(cls, *args, **kwargs)
            cls.__load_datas()
        return cls.__instance
    @classmethod
    def __load_datas(cls):
        __redis = cls.__get_redis()
        try:
            pass
        finally:
            RedisUtils.realse(__redis)
    @classmethod
    def __get_redis(cls):
        return cls.__redis_manager.getRedis()
    # 是否有撤买的规则
    def has_auto_cancel_rules(self, code):
        rules = self.get_auto_cancel_rules(code)
        return True if rules else False
    def get_auto_cancel_rules(self, code):
        try:
            rules = TradeRuleManager().list_can_excut_rules_cache([TradeRuleManager.TYPE_BUY_CANCEL], code)
            return rules
        except:
            return None
    def need_cancel(self, code, buy1_volume):
        rules = self.get_auto_cancel_rules(code)
        if rules:
            for r in rules:
                if r.buy1_volume >= buy1_volume:
                    # 量低于
                    return True, r.id_
        return False, None
    def compute_d_cancel_watch_index(self, code):
        # 计算D撤囊括范围
        # real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code)
        pass
    def __clear_data(self, code):
        if code in self.__follow_big_order_cache:
            self.__follow_big_order_cache.pop(code)
    def place_order_success(self, code, buy_single_index, buy_exec_index):
        self.__clear_data(code)
# ---------------------------------RD撤-------------------------------
# 扫入下单大单撤
l2/l2_data_manager_new.py
@@ -834,7 +834,7 @@
            cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index,
                                                            order_begin_pos.buy_exec_index)
        if cancel_data and not DCancelBigNumComputer().has_auto_cancel_rules(code):
        if cancel_data:
            try:
                # 撤单
                cls.cancel_buy(code, cancel_msg, cancel_index=cancel_data["index"], cancel_type=cancel_type)
@@ -1399,9 +1399,9 @@
        if cancel_type != trade_constant.CANCEL_TYPE_HUMAN:
            # 是否是交易队列触发
            # 扫入下单只有L撤能撤单
            if order_begin_pos and order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL and cancel_type not in {
            if order_begin_pos and cancel_type not in {
                trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD,
                trade_constant.CANCEL_TYPE_P, trade_constant.CANCEL_TYPE_F}:
                trade_constant.CANCEL_TYPE_P, trade_constant.CANCEL_TYPE_F, trade_constant.CANCEL_TYPE_D}:
                l2_log.cancel_debug(code, "撤单中断,原因:{}", "扫入下单不是L撤")
                return False
            # 加绿只有L撤/人撤生效
log_module/log.py
@@ -270,6 +270,11 @@
                   filter=lambda record: record["extra"].get("name") == "limit_up_record",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(self.get_path("virtual_account", "virtual_account_money_records"),
                   filter=lambda record: record["extra"].get("name") == "virtual_account_money_records",
                   rotation="00:00", compression="zip", enqueue=True)
        ################################华鑫日志################################
        logger.add(self.get_hx_path("l2", "transaction"),
                   filter=lambda record: record["extra"].get("name") == "hx_l2_transaction",
@@ -364,6 +369,11 @@
        logger.add(self.get_local_huaxin_path("trade", "trade_debug"),
                   filter=lambda record: record["extra"].get("name") == "local_huaxin_trade_debug",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(self.get_local_huaxin_path("trade", "deal"),
                   filter=lambda record: record["extra"].get("name") == "local_huaxin_trade_deal",
                   rotation="00:00", compression="zip", enqueue=True)
        logger.add(sys.stdout,
                   filter=lambda record: record["extra"].get("name") == "local_huaxin_l1_show_info")
        logger.add(self.get_local_huaxin_path("l1", "show_info"),
@@ -508,6 +518,8 @@
logger_l2_radical_buy_data = __mylogger.get_logger("l2_radical_buy_data")
logger_virtual_account_money_records= __mylogger.get_logger("virtual_account_money_records")
# -------------------------------华鑫日志---------------------------------
hx_logger_l2_orderdetail = __mylogger.get_logger("hx_l2_orderdetail")
hx_logger_l2_transaction = __mylogger.get_logger("hx_l2_transaction")
@@ -538,6 +550,9 @@
logger_local_huaxin_l2_subscript = __mylogger.get_logger("local_huaxin_subscript")
logger_local_huaxin_contact_debug = __mylogger.get_logger("local_huaxin_debug")
logger_local_huaxin_trade_debug = __mylogger.get_logger("local_huaxin_trade_debug")
logger_local_huaxin_trade_deal = __mylogger.get_logger("local_huaxin_trade_deal")
logger_local_huaxin_l1 = __mylogger.get_logger("local_huaxin_l1_show_info")
logger_local_huaxin_g_cancel = __mylogger.get_logger("local_huaxin_g_cancel")
logger_local_huaxin_l2_buy_no = __mylogger.get_logger("local_huaxin_l2_buy_no")
log_module/log_export.py
@@ -453,13 +453,12 @@
    return cancel_reason_dict
def __parse_content(line):
    line = line.split(" - ")[1]
    time_str = line[line.find("[") + 1:line.find("[") + 9]
    data = line[line.find("]") + 1:].strip()
    if data.find("thread-id=")>-1 and data.find("code=")>-1:
        data = data[data.find("code=")+11:].strip()
    if data.find("thread-id=") > -1 and data.find("code=") > -1:
        data = data[data.find("code=") + 11:].strip()
    return time_str, data
@@ -608,7 +607,6 @@
    return fdatas
@cache_log
def load_huaxin_l2_sell_deal_list(code=None, date=tool.get_now_date_str()):
    path = f"{constant.get_path_prefix()}/logs/huaxin/l2/sell_l2_deal.{date}.log"
@@ -622,7 +620,7 @@
                    data = line.split(" - ")[1].strip()
                    if data.startswith("["):
                        data = data[data.find("]") + 1:].strip()
                    if data.find("涨停主动买成交:") <0:
                    if data.find("涨停主动买成交:") < 0:
                        continue
                    data = data.split("涨停主动买成交:")[1]
                    data = eval(data)
@@ -856,12 +854,50 @@
    path = f"{constant.get_path_prefix()}/logs/gp/plates/special_codes.{date}.log"
    lines = __load_file_content(path)
    if lines:
            line = lines[0]
            line = line[line.find(" - ") + 3:]
            return eval(line)
        line = lines[0]
        line = line[line.find(" - ") + 3:]
        return eval(line)
    return None
def load_virtual_trade_account(date=tool.get_now_date_str()):
    """
    加载虚拟交易数据
    :param date:
    :return:
    """
    path = f"{constant.get_path_prefix()}/logs/gp/virtual_account/virtual_account_money_records.{date}.log"
    fdatas = []
    if os.path.exists(path):
        with open(path, 'r', encoding="utf-8") as f:
            lines = f.readlines()
            if lines:
                for line in lines:
                    time_str = __get_async_log_time(line)
                    data = line[line.find("]") + 1:].strip()
                    fdatas.append((time_str, eval(data)))
    return fdatas
def load_deal_list(date=tool.get_now_date_str()):
    """
    加载虚拟交易数据
    :param date:
    :return:
    """
    path = f"{constant.get_path_prefix()}/logs/huaxin_local/trade/deal.{date}.log"
    fdatas = []
    if os.path.exists(path):
        with open(path, 'r', encoding="utf-8") as f:
            lines = f.readlines()
            if lines:
                for line in lines:
                    # time_str = __get_async_log_time(line)
                    data = line[line.find("]") + 1:].strip()
                    fdatas.append(eval(data))
    return fdatas
if __name__ == '__main__':
    line = """
    2025-03-12 14:49:15.028 | DEBUG    | log_module.async_log_util:run_sync:66 - [14:49:14.899602] thread-id=3048 code=600841  L前监控范围:{1477, 1478, 1479, 1480, 1481, 1482, 1486, 1487, 1488, 1489, 1492, 1493, 1495, 1498, 1500} 计算范围:1477-1503
servers/huaxin_trade_server.py
@@ -14,7 +14,7 @@
import constant
import outside_api_command_manager
from cancel_strategy.s_l_h_cancel_strategy import SCancelBigNumComputer
from cancel_strategy.s_l_h_cancel_strategy import SCancelBigNumComputer, DCancelBigNumComputer
from code_attribute import gpcode_manager, code_volumn_manager, global_data_loader, zyltgb_util
from code_attribute.code_l1_data_manager import L1DataManager
from code_attribute.gpcode_manager import CodePrePriceManager, CodesNameManager, \
@@ -24,8 +24,7 @@
from huaxin_client.trade_transform_protocol import TradeResponse
from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, transaction_progress, \
    l2_data_source_util, l2_data_log, data_callback
from l2.cancel_buy_strategy import GCancelBigNumComputer, \
    DCancelBigNumComputer, RDCancelBigNumComputer
from l2.cancel_buy_strategy import GCancelBigNumComputer
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
@@ -466,14 +465,16 @@
        # -----------------------判断是是否有自动撤单规则-----------------------
        try:
            if DCancelBigNumComputer().has_auto_cancel_rules(code):
                need_cancel, rule_id = DCancelBigNumComputer().need_cancel(code, buy_1_volume)
            if True:
                need_cancel, msg = DCancelBigNumComputer().need_cancel(code, (buy_1_price, buy_1_volume),
                                                                       limit_up_price, time_str)
                if need_cancel:
                    try:
                        l2_data_manager_new.L2TradeDataProcessor.cancel_buy(code, f"盯封单撤:{time_str}-{buy_1_volume}",
                        l2_data_manager_new.L2TradeDataProcessor.cancel_buy(code,
                                                                            f"盯封单撤:{time_str}-{buy_1_volume} , {msg}",
                                                                            cancel_type=trade_constant.CANCEL_TYPE_D)
                    finally:
                        TradeRuleManager().excuted(rule_id)
                        pass
        except Exception as e:
            logger_debug.exception(e)