Administrator
2023-11-28 3ea84f8adaeeb851e590fa74ceed009a0a19b08c
近6个交易日涨幅过高实现
9个文件已修改
1个文件已添加
231 ■■■■ 已修改文件
code_attribute/code_nature_analyse.py 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_attribute/first_target_code_data_processor.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/code_price_manager.py 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/l2_trade_test.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_code_attribute.py 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/code_plate_key_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_api.py 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_server.py 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_attribute/code_nature_analyse.py
@@ -224,7 +224,7 @@
# 是否具有K线形态
def is_has_k_format(limit_up_price, record_datas):
    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v, has_format, volume_info, is_special = get_k_format(
    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v, has_format, volume_info, is_special, has_max_volume = get_k_format(
        float(limit_up_price), record_datas)
    if not has_format:
        return False, "不满足K线形态"
@@ -255,7 +255,7 @@
# 是否涨得太高
def is_up_too_high_in_10d(record_datas):
def is_up_too_high_in_10d_with_limit_up(record_datas):
    datas = copy.deepcopy(record_datas)
    datas.sort(key=lambda x: x["bob"])
    datas = datas[-10:]
@@ -348,6 +348,31 @@
    return False
# 在最近几天内股价是否长得太高
def is_price_too_high_in_days(record_datas, limit_up_price, day_count=6):
    datas = copy.deepcopy(record_datas)
    datas.sort(key=lambda x: x["bob"])
    datas = datas[0 - day_count:]
    min_price = None
    max_price = None
    for d in datas:
        if min_price is None:
            min_price = d["low"]
        if max_price is None:
            max_price = d["high"]
        if min_price > d["low"]:
            min_price = d["low"]
        if max_price < d["high"]:
            max_price = d["high"]
    if max_price > float(limit_up_price):
        return False
    rate = (float(limit_up_price) - min_price) / min_price
    # print(rate)
    if rate >= 0.25:
        return True
    return False
# 是否有涨停
def get_first_limit_up_count(datas):
    datas = copy.deepcopy(datas)
code_attribute/first_target_code_data_processor.py
@@ -123,7 +123,7 @@
                k_format = code_nature_analyse.get_k_format(limit_up_price, volumes_data)
                code_nature_analyse.CodeNatureRecordManager().save_k_format(code, k_format)
                if code_nature_analyse.is_up_too_high_in_10d(volumes_data):
                if code_nature_analyse.is_up_too_high_in_10d_with_limit_up(volumes_data):
                    # 判断是否太高
                    l2_trade_util.forbidden_trade(code, "股价长得太高")
                    HighIncreaseCodeManager().add_code(code)
@@ -133,6 +133,11 @@
                    l2_trade_util.forbidden_trade(code, "120天内股价长得太高")
                    HighIncreaseCodeManager().add_code(code)
                if code_nature_analyse.is_price_too_high_in_days(volumes_data, limit_up_price):
                    # 判断是否太高
                    l2_trade_util.forbidden_trade(code, "6天内股价长得太高")
                    HighIncreaseCodeManager().add_code(code)
                if code_nature_analyse.is_have_latest_max_volume(volumes_data, 2):
                    # 最近2天是否是最高量
                    code_nature_analyse.LatestMaxVolumeManager().set_has_latest_max_volume(code)
huaxin_client/l2_client.py
@@ -276,6 +276,7 @@
            d = {"dataTimeStamp": pDepthMarketData['DataTimeStamp'], "securityID": pDepthMarketData['SecurityID'],
                 "lastPrice": pDepthMarketData['LastPrice'],
                 "totalVolumeTrade": pDepthMarketData['TotalVolumeTrade'],
                 "totalValueTrade":pDepthMarketData['TotalValueTrade'],
                 "totalAskVolume": pDepthMarketData['TotalAskVolume'],
                 "avgAskPrice": pDepthMarketData["AvgAskPrice"],
                 "buy": [(pDepthMarketData['BidPrice1'], pDepthMarketData['BidVolume1']),
l2/code_price_manager.py
@@ -25,6 +25,8 @@
    # 最近3分钟内的买1金额
    __latest_3m_buy1_money_list_dict = {}
    __open_limit_up_lowest_price_cache = {}
    # 均价
    __average_rate_dict = {}
    __instance = None
@@ -139,16 +141,20 @@
        price = self.__get_open_limit_up_lowest_price_cache(code)
        return price
    # 处理
    def get_average_rate(self, code):
        return self.__average_rate_dict.get(code)
    def process(self, code, buy_1_price, buy_1_volume, time_str, limit_up_price, sell_1_price, sell_1_volumn):
    # 处理
    def process(self, code, buy_1_price, buy_1_volume, time_str, limit_up_price, sell_1_price, sell_1_volumn,
                average_rate=None):
        self.__average_rate_dict[code] = average_rate
        data_str = f"{buy_1_price},{buy_1_volume},{time_str},{limit_up_price},{sell_1_price},{sell_1_volumn}"
        if self.__latest_data.get(code) == data_str:
            return
        # 记录日志
        logger_trade_queue_price_info.info(
            f"code={code} data: time_str-{time_str}, buy_1_price-{buy_1_price},limit_up_price-{limit_up_price},sell_1_price-{sell_1_price},sell_1_volumn-{sell_1_volumn}")
            f"code={code} data: time_str-{time_str}, buy_1_price-{buy_1_price},limit_up_price-{limit_up_price},sell_1_price-{sell_1_price},sell_1_volumn-{sell_1_volumn},percent_rate-{percent_rate}")
        # 买1价格不能小于1块
        if float(buy_1_price) < 1.0:
            return
l2/l2_data_manager_new.py
@@ -846,6 +846,11 @@
            l2_trade_util.forbidden_trade(code, msg="当日下单次数已达10次")
            return False, True, f"当日下单次数已达10次"
        # ---------均价约束-------------
        average_rate = cls.__Buy1PriceManager.get_average_rate(code)
        if average_rate and average_rate <= 0.01:
            return False, True, f"均价涨幅({average_rate})小于1%"
        # -------量的约束--------
        if cls.volume_rate_info[code][0] < 0.2:
            return False, True, f"当日量比({cls.volume_rate_info[code][0]})小于0.2"
test/l2_trade_test.py
@@ -218,6 +218,7 @@
    def test_block(self):
        code = "002962"
        KPLCodeJXBlockManager().load_jx_blocks(code, 14.99, 14.99)
        KPLCodeJXBlockManager().load_jx_blocks(code, 14.99, 14.99)
        block_info.init_code(code)
        kpl_data_manager.KPLLimitUpDataRecordManager.load_total_datas()
        yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes()
test/test_code_attribute.py
New file
@@ -0,0 +1,25 @@
from code_attribute import code_nature_analyse
from utils import init_data_util
def is_too_high(datas):
    limit_up_price = round(datas[0]["close"] * 1.1, 2)
    datas.reverse()
    is_new_high = code_nature_analyse.is_price_too_high_in_days(datas, limit_up_price)
    return is_new_high
if __name__ == "__main__":
    code_str = "000536,000625,000628,000670,000766,000829,001311,001331,002189,002275,002331,002341,002363,002406,002416,002655,002691,002848,002861,002885,002906,002917,002962,300217,300462,300552,301111,301215,301372,600107,600178,600222,600288,600513,600698,600960,601777,603029,603286,603297,603569,605020,688314,688789"
    codes = code_str.split(",")
    for code in codes:
        if code.find("00") != 0 and code.find("60") != 0:
            continue
        try:
            datas = init_data_util.get_volumns_by_code(code, 120)
            datas = datas[3:]
            result = is_too_high(datas)
            if result:
                print(code, result)
        except:
            print(code, "出错")
third_data/code_plate_key_manager.py
@@ -104,7 +104,7 @@
                    async_log_util.info(logger_kpl_block_can_buy, f"{code}:获取到精选板块-{blocks}")
                else:
                    # 还没涨停的需要更新精选板块 更新精选板块
                    if abs(float(buy_1_price) - float(limit_up_price)) >= 0.001:
                    if abs(float(buy_1_price) - float(limit_up_price)) >= 0.001 or constant.TEST:
                        # 非涨停状态
                        UPDATE_TIME_SPACE = 5 * 60
                        time_diff = tool.trade_time_sub(tool.get_now_time_str(), "09:30:00")
trade/huaxin/huaxin_trade_api.py
@@ -37,6 +37,50 @@
def __run_recv_queue_trade(queue: multiprocessing.Queue):
    def __process_order(data):
        code = data["securityID"]
        accountID = data["accountID"]
        orderStatus = data["orderStatus"]
        orderRef = data["orderRef"]
        orderSysID = data["orderSysID"]
        insertTime = data.get("insertTime")
        acceptTime = data.get("acceptTime")
        insertDate = data.get("insertDate")
        direction = data.get("direction")
        limitPrice = data.get("limitPrice")
        volume = data.get("volume")
        is_shadow_order = False
        # 获取涨停价
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if limit_up_price and volume == huaxin_client_constant.SHADOW_ORDER_VOLUME:
            if abs(float(limitPrice) - float(limit_up_price)) >= 0.01:
                is_shadow_order = True
        order = HuaxinOrderEntity(code, orderStatus, orderRef, accountID, orderSysID,
                                  insertTime=insertTime, acceptTime=acceptTime,
                                  insertDate=insertDate, direction=direction,
                                  is_shadow_order=is_shadow_order)
        try:
            if order.direction == str(huaxin_util.TORA_TSTP_D_Sell):
                # 刷新持仓列表
                huaxin_trade_data_update.add_position_list()
            TradeResultProcessor.process_buy_order(order)
            TradeResultProcessor.process_sell_order(order)
        finally:
            try:
                # 加入2次,增大加入成功率
                __save_data_queue.put_nowait(data)
            except Exception as e:
                hx_logger_trade_debug.exception(e)
        if not is_shadow_order:
            # 订单相关回调
            # 重新请求委托列表与资金
            # huaxin_trade_data_update.add_delegate_list("来自交易管道")
            huaxin_trade_data_update.add_deal_list()
            huaxin_trade_data_update.add_money_list()
    # 设置结果
    def __set_response(data_json):
        if 'request_id' not in data_json:
@@ -62,6 +106,10 @@
                        async_log_util.info(hx_logger_trade_callback,
                                            f"response:request_id-{request_id}")
                        __response_thread_pool.submit(__set_response, data_json)
                        if type(data_json.get("data")) == dict:
                            data = data_json["data"].get("data")
                            if type(data) == dict and "orderRef" in data:
                                __response_thread_pool.submit(__process_order, data)
                    elif type_ == "trade_callback":
                        try:
                            # 交易回调
@@ -72,48 +120,7 @@
                            if ctype == 0:
                                data = data_json.get("data")
                                # 获取订单状态
                                code = data["securityID"]
                                accountID = data["accountID"]
                                orderStatus = data["orderStatus"]
                                orderRef = data["orderRef"]
                                orderSysID = data["orderSysID"]
                                insertTime = data.get("insertTime")
                                acceptTime = data.get("acceptTime")
                                insertDate = data.get("insertDate")
                                direction = data.get("direction")
                                limitPrice = data.get("limitPrice")
                                volume = data.get("volume")
                                is_shadow_order = False
                                # 获取涨停价
                                limit_up_price = gpcode_manager.get_limit_up_price(code)
                                if limit_up_price and volume == huaxin_client_constant.SHADOW_ORDER_VOLUME:
                                    if abs(float(limitPrice) - float(limit_up_price)) >= 0.01:
                                        is_shadow_order = True
                                order = HuaxinOrderEntity(code, orderStatus, orderRef, accountID, orderSysID,
                                                          insertTime=insertTime, acceptTime=acceptTime,
                                                          insertDate=insertDate, direction=direction,
                                                          is_shadow_order=is_shadow_order)
                                try:
                                    if order.direction == str(huaxin_util.TORA_TSTP_D_Sell):
                                        # 刷新持仓列表
                                        huaxin_trade_data_update.add_position_list()
                                    TradeResultProcessor.process_buy_order(order)
                                    TradeResultProcessor.process_sell_order(order)
                                finally:
                                    try:
                                        # 加入2次,增大加入成功率
                                        __save_data_queue.put_nowait(data)
                                    except Exception as e:
                                        hx_logger_trade_debug.exception(e)
                                if not is_shadow_order:
                                    # 订单相关回调
                                    # 重新请求委托列表与资金
                                    # huaxin_trade_data_update.add_delegate_list("来自交易管道")
                                    huaxin_trade_data_update.add_deal_list()
                                    huaxin_trade_data_update.add_money_list()
                            # print("响应结果:", data_json['data'])
                                __process_order(data)
                        finally:
                            pass
            except:
trade/huaxin/huaxin_trade_server.py
@@ -27,7 +27,7 @@
import inited_data
import outside_api_command_manager
from code_attribute import gpcode_manager, code_volumn_manager, global_data_loader
from code_attribute.gpcode_manager import CodePrePriceManager
from code_attribute.gpcode_manager import CodePrePriceManager, CodesNameManager
from db import mysql_data_delegate as mysql_data, redis_manager_delegate as redis_manager
from db.redis_manager_delegate import RedisUtils
from huaxin_client import l1_subscript_codes_manager, l2_data_transform_protocol
@@ -366,10 +366,17 @@
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if limit_up_price is not None:
            average_rate = None
            try:
                average_price = data["totalValueTrade"] / data["totalVolumeTrade"]
                pre_close_price = CodePrePriceManager.get_price_pre_cache(code)
                average_rate = round((average_price - pre_close_price) / pre_close_price, 4)
            except:
                pass
            # 处理买1,卖1信息
            code_price_manager.Buy1PriceManager().process(code, buy_1_price, buy_1_volume, time_str,
                                                          limit_up_price,
                                                          sell_1_price, sell_1_volume // 100)
                                                          sell_1_price, sell_1_volume // 100, average_rate)
            latest_3m_buy1_money_list = code_price_manager.Buy1PriceManager().get_latest_3m_buy1_money_list(code)
            # -----------------------------重新计算L撤后---------------------------
            # 如果时涨停状态
@@ -403,7 +410,9 @@
                volume_info = l2_data_manager_new.L2TradeDataProcessor.volume_rate_info.get(code)
                if volume_info:
                    volume_rate = volume_info[0]
                need_cancel, msg = UCancelBigNumComputer().need_cancel(code, order_begin_pos, kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reason_codes_dict(), volume_rate)
                need_cancel, msg = UCancelBigNumComputer().need_cancel(code, order_begin_pos,
                                                                       kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reason_codes_dict(),
                                                                       volume_rate)
                if need_cancel:
                    l2_data_manager_new.L2TradeDataProcessor.cancel_buy(code, msg)
            except Exception as e:
@@ -569,15 +578,13 @@
                            raise Exception("没有获取到L1现价")
                        price = round(float(current_price) - 0.05, 2)
                    async_log_util.info(logger_trade, f"API卖:  单价-{price}")
                    result = huaxin_trade_api.order(direction, code, volume, price, sinfo=sinfo,
                    order_ref = huaxin_util.create_order_ref()
                    result = huaxin_trade_api.order(direction, code, volume, price, sinfo=sinfo, order_ref=order_ref,
                                                    blocking=True, request_id=request_id)
                    logger_debug.info(f"卖接口返回数据:{result}")
                    order_ref = result.get("order_ref")
                    # 如果是在正常交易时间提交的2s之内还未成交的需要撤单
                    if int("092958") <= int(tool.get_now_time_str().replace(":", "")) <= int("150000"):
                        self.__cancel_sell_thread_pool.submit(lambda: self.__cancel_sell_order(code, order_ref))
                    self.send_response({"code": 0, "data": result}, client_id, request_id)
                    self.send_response(result, client_id, request_id)
                else:
                    result = huaxin_trade_api.order(direction, code, volume, price, price_type=price_type, sinfo=sinfo,
                                                    blocking=True, request_id=request_id)
@@ -1011,6 +1018,12 @@
            fdata = {"code": code, "total": 0, "available": 0, "sell_rules_count": sell_rules_count}
            if positions:
                for d in positions:
                    code_name = gpcode_manager.get_code_name(d["securityID"])
                    if not code_name:
                        # 判断是否有名称
                        results = HistoryKDatasUtils.get_gp_codes_names([d["securityID"]])
                        threading.Thread(
                            target=CodesNameManager.add_first_code_name(d["securityID"], results[0])).start()
                    if d["prePosition"] <= 0:
                        continue
                    if d["securityID"] != code:
@@ -1020,6 +1033,8 @@
                    break
            result = {"code": 0, "data": fdata}
            self.send_response(result, client_id, request_id)
        except Exception as e:
            logging.exception(e)
            self.send_response(json.dumps({"code": 1, "msg": f"数据处理出错:{e}"}), client_id, request_id)
@@ -1027,6 +1042,33 @@
    def OnCommonRequest(self, client_id, request_id, data):
        # 通用请求
        ctype = data["ctype"]
        try:
            if ctype == "get_sell_result":
                order_ref = data["order_ref"]
                order_entity = huaxin_trade_order_processor.TradeResultProcessor.get_huaxin_order_by_order_ref(
                    order_ref)
                if not order_entity:
                    self.send_response(json.dumps({"code": 1, "msg": f"没有获取到订单状态"}), client_id, request_id)
                else:
                    code_name = gpcode_manager.get_code_name(order_entity.code)
                    result = {}
                    if huaxin_util.is_canceled(order_entity.orderStatus):
                        result = {"code": 0,
                                  "data": {"orderStatus": order_entity.orderStatus, "code": order_entity.code,
                                           "msg": f"【{order_entity.code}({code_name})】已撤单"}}
                    elif huaxin_util.is_deal(order_entity.orderStatus):
                        result = {"code": 0,
                                  "data": {"orderStatus": order_entity.orderStatus, "code": order_entity.code,
                                           "msg": f"【{order_entity.code}({code_name})】已经成交"}}
                    else:
                        result = {"code": 0,
                                  "data": {"orderStatus": order_entity.orderStatus, "code": order_entity.code,
                                           "msg": f"【{order_entity.code}({code_name})】已挂单"}}
                    self.send_response(result, client_id, request_id)
        except Exception as e:
            logging.exception(e)
            self.send_response(json.dumps({"code": 1, "msg": f"数据处理出错:{e}"}), client_id, request_id)
        # 获取子类型