Administrator
2023-07-18 1c76abc59af35931b70b4742038dae0cfe4890d4
华鑫适配
3个文件已删除
12个文件已修改
2个文件已添加
1267 ■■■■ 已修改文件
code_attribute/code_nature_analyse.py 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/cancel_buy_strategy.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/code_price_manager.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_source_util.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server.py 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/block_info.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/block_test.py 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/code_plate_key_manager.py 235 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hot_block.py 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hot_block.spec 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hot_block_data_process.py 378 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_block_util.py 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_data_manager.py 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/current_price_process_manager.py 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/trade_api_server.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/trade_server.py 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_attribute/code_nature_analyse.py
@@ -54,7 +54,7 @@
# 获取K线形态
# 返回 (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V)
# 返回 (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V,是否有形态,天量大阳信息,是否具有辨识度)
def get_k_format(limit_up_price, record_datas):
    p1_data = get_lowest_price_rate(record_datas)
    p1 = p1_data[0] >= 0.249, p1_data[1]
@@ -71,7 +71,10 @@
    p7 = (p1[0] or p2[0] or p3[0] or p4[0] or p5[0] or p6[0], '')
    return p1, p2, p3, p4, p5, p6, p7, p8
    # 是否具有辨识度
    p9 = is_special(record_datas)
    return p1, p2, p3, p4, p5, p6, p7, p8, p9
# 是否具有K线形态
@@ -114,9 +117,9 @@
    for i in range(len(datas)):
        item = datas[i]
        # 获取首板涨停次数
        if __is_limit_up(item) and i>0 and not __is_limit_up(datas[i-1]):
        if __is_limit_up(item) and i > 0 and not __is_limit_up(datas[i - 1]):
            # 首板涨停
            count+=1
            count += 1
    return count
@@ -264,6 +267,12 @@
    return abs(limit_up_price - data["close"]) < 0.001
# 是否涨停过
def __is_limited_up(data):
    limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(data["pre_close"]))
    return abs(limit_up_price - data["high"]) < 0.001
# 首板涨停溢价率
def get_limit_up_premium_rate(datas):
    datas = copy.deepcopy(datas)
@@ -311,5 +320,25 @@
    return count / len(first_rate_list)
# 是否具有辨识度
def is_special(datas):
    # 30个交易日内有≥5天曾涨停且连续涨停数或曾涨停≥2天
    if len(datas) > 30:
        datas = datas[-30:]
    count = 0
    continue_count = 0
    last_index = -1
    for i in range(len(datas)):
        if __is_limited_up(datas[i]):
            if last_index >= 0 and i - last_index == 1:
                continue_count += 1
            count += 1
            last_index = i
    if count >= 5 and continue_count > 0:
        return True, ''
    return False, ''
if __name__ == "__main__":
    print(CodeNatureRecordManager.get_k_format("603717"))
l2/cancel_buy_strategy.py
@@ -9,8 +9,8 @@
import logging
import time
from code_attribute import big_money_num_manager, gpcode_manager
import constant
from code_attribute import big_money_num_manager, gpcode_manager
import l2_data_util
from db import redis_manager
from utils import tool
l2/code_price_manager.py
@@ -40,11 +40,31 @@
    def __get_buy1_price(cls, code):
        return cls.__get_redis().get(f"buy1_price-{code}")
    # 设置炸板后的最低价
    @classmethod
    def __save_open_limit_up_lowest_price(cls, code, price):
        cls.__get_redis().setex(f"open_limit_up_lowest_price-{code}", tool.get_expire(), f"{price}")
    @classmethod
    def __get_open_limit_up_lowest_price(cls, code):
        return cls.__get_redis().get(f"open_limit_up_lowest_price-{code}")
    @classmethod
    def set_open_limit_up_lowest_price(cls, code, price):
        old_price = cls.__get_open_limit_up_lowest_price(code)
        if not old_price or float(old_price) - float(price) > 0.001:
            cls.__save_open_limit_up_lowest_price(code, price)
    @classmethod
    def get_buy1_price(cls, code):
        if code in cls.__current_buy_1_price:
            return cls.__current_buy_1_price.get(code)
        return cls.__get_buy1_price(code)
    @classmethod
    def get_open_limit_up_lowest_price(cls, code):
        price = cls.__get_open_limit_up_lowest_price(code)
        return price
    # 处理
    @classmethod
@@ -74,6 +94,10 @@
            # 有涨停时间,当前没有涨停,之前没有打开涨停
            cls.__save_buy1_price_info(code, old_limit_up_time, time_str)
        if old_limit_up_time and not is_limit_up:
            # 之前涨停过且现在尚未涨停
            cls.set_open_limit_up_lowest_price(code, buy_1_price)
    # 是否可以下单
    @classmethod
    def is_can_buy(cls, code):
l2/l2_data_manager_new.py
@@ -5,13 +5,15 @@
    limit_up_time_manager, global_data_loader, gpcode_manager
import constant
from l2.huaxin import l2_huaxin_util, huaxin_delegate_postion_manager
from third_data import kpl_data_manager
from utils import global_util, ths_industry_util, tool
import l2_data_util
from db import redis_manager
from third_data.code_plate_key_manager import CodePlateKeyBuyManager
from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
    trade_result_manager, first_code_score_manager
from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager
    trade_result_manager, first_code_score_manager, current_price_process_manager
from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager, \
    transaction_progress
from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \
    L2LimitUpSellStatisticUtil, DCancelBigNumComputer
from l2.l2_data_manager import L2DataException, TradePointManager
@@ -160,6 +162,7 @@
    __buyL2SafeCountManager = safe_count_manager.BuyL2SafeCountManager()
    __l2PlaceOrderParamsManagerDict = {}
    __last_buy_single_dict = {}
    __TradeBuyQueue = transaction_progress.TradeBuyQueue()
    # 获取代码评分
    @classmethod
@@ -711,37 +714,54 @@
        if gpcode_manager.PauseBuyCodesManager.is_in(code):
            return False, True, f"该代码被暂停交易"
        # 判断买1价格档位
        zyltgb = global_util.zyltgb_map.get(code)
        if zyltgb is None:
            global_data_loader.load_zyltgb()
            zyltgb = global_util.zyltgb_map.get(code)
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_HUAXIN:
            trade_price = current_price_process_manager.get_trade_price(code)
            if trade_price is None:
                return False, True, f"尚未获取到当前成交价"
            if float(limit_up_price) - float(trade_price) > 0.02001:
                return False, False, f"当前成交价({trade_price})尚未在2档及以内"
        if zyltgb >= 200 * 100000000:
            buy1_price = code_price_manager.Buy1PriceManager.get_buy1_price(code)
            if buy1_price is None:
                return False, True, f"尚未获取到买1价"
            dif = float(limit_up_price) - float(buy1_price)
            # 大于10档
            if dif > 0.10001:
                return False, True, f"自由流通200亿以上,买1剩余档数大于10档,买一({buy1_price})涨停({limit_up_price})"
        # elif zyltgb >= 80 * 100000000:
        #     # 大于2档
        #     if dif > 0.02001:
        #         return False, True, f"买1剩余档数大于2档,买一({buy1_price})涨停({limit_up_price})"
        # elif zyltgb >= 60 * 100000000:
        #     # 大于2档
        #     if dif > 0.03001:
        #         return False, True, f"买1剩余档数大于3档,买一({buy1_price})涨停({limit_up_price})"
        # elif zyltgb >= 40 * 100000000:
        #     # 大于2档
        #     if dif > 0.04001:
        #         return False, True, f"买1剩余档数大于4档,买一({buy1_price})涨停({limit_up_price})"
        # else:
        #     if dif > 0.05001:
        #         return False, True, f"买1剩余档数大于5档,买一({buy1_price})涨停({limit_up_price})"
            # 判断成交进度是否距离我们的位置很近
            total_data = local_today_datas.get(code)
            trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code)
            if not is_default and trade_index:
                buy_index_set = set()
                num_operate_map = local_today_num_operate_map.get(code)
                for i in range(trade_index + 1, total_data[-1]["index"] + 1):
                    if L2DataUtil.is_limit_up_price_buy(total_data[i]["val"]):
                        left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code,
                                                                                                              total_data[
                                                                                                                  i][
                                                                                                                  "index"],
                                                                                                              total_data,
                                                                                                              num_operate_map)
                        if left_count > 0:
                            buy_index_set.add(total_data[i]["index"])
                if len(buy_index_set) < 5:
                    return False, False, f"成交位置距离当前位置小于5笔"
        else:
            # 判断买1价格档位
            zyltgb = global_util.zyltgb_map.get(code)
            if zyltgb is None:
                global_data_loader.load_zyltgb()
                zyltgb = global_util.zyltgb_map.get(code)
            if zyltgb >= 200 * 100000000:
                buy1_price = code_price_manager.Buy1PriceManager.get_buy1_price(code)
                if buy1_price is None:
                    return False, True, f"尚未获取到买1价"
                dif = float(limit_up_price) - float(buy1_price)
                # 大于10档
                if dif > 0.10001:
                    return False, True, f"自由流通200亿以上,买1剩余档数大于10档,买一({buy1_price})涨停({limit_up_price})"
        open_limit_up_lowest_price = code_price_manager.Buy1PriceManager.get_open_limit_up_lowest_price(code)
        price_pre_close = gpcode_manager.get_price_pre(code)
        if open_limit_up_lowest_price and (
                float(open_limit_up_lowest_price) - price_pre_close) / price_pre_close < 0.05:
            return False, True, f"炸板后最低价跌至5%以下"
        limit_up_info = code_price_manager.Buy1PriceManager.get_limit_up_info(code)
        if limit_up_info[0] is None and False:
@@ -783,13 +803,43 @@
    @classmethod
    def can_buy_first(cls, code, limit_up_price, score_index, score, score_info, volume_rate_info):
        def is_has_k_format(score_info):
            # (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V,是否有形态,天量大阳信息,是否具有辨识度)
            if score_info[1][3][6][0] and not score_info[1][3][3][0]:
                return True
            if score_info[1][3][7][0]:
                return True
            return False
        if float(limit_up_price) >= 40:
            return False, True, "股价大于40块"
        # 获取涨停
        latest_2_day_limit_up_datas_temp = kpl_data_manager.get_current_limit_up_data_records(2)
        latest_2_day_limit_up_datas = []
        for d in latest_2_day_limit_up_datas_temp:
            latest_2_day_limit_up_datas.extend(d[1])
        # 判断板块
        plate_can_buy, msg = CodePlateKeyBuyManager.can_buy(code)
        plate_can_buy, msg, block_type = CodePlateKeyBuyManager.can_buy(code,
                                                                        kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas,
                                                                        latest_2_day_limit_up_datas,
                                                                        kpl_data_manager.KPLLimitUpDataRecordManager.total_datas)
        if not plate_can_buy:
            return False, True, msg
        has_k_format = is_has_k_format(score_info)
        # 独苗
        if block_type == CodePlateKeyBuyManager.BLOCK_TYPE_START_UP:
            # 必须满足(分数≥150且上板时量≥40 % 且有K线形态)或(具有辨识度)的才能买
            if has_k_format and score_index >= 0 and volume_rate_info[0] >= 0.4:
                return True, False, "独苗:分数≥150且上板时量≥40% 且有K线形态"
            elif score_info[1][3][8][0]:
                return True, False, "独苗:具有辨识度"
            else:
                return False, True, f"独苗:不满足买入条件"
        else:
            return True, False, msg
        # if volume_rate_info[0] < 0.4:
        #     return False, True, f"量大于40%才下单,量比:{volume_rate_info[0]}"
l2/l2_data_source_util.py
@@ -1,6 +1,7 @@
"""
L2数据溯源
"""
import constant
from utils import tool
@@ -113,7 +114,10 @@
        buy_index = cls.__get_buy_index_cache(code, cancel_data["index"])
        if buy_index is not None:
            return buy_index
        return cls.__get_buy_index_with_cancel_data_by_ths_l2(code, cancel_data, local_today_num_operate_map)
        if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_HUAXIN:
            return cls.__get_buy_index_with_cancel_data_by_huaxin_l2(code, cancel_data, local_today_num_operate_map)
        else:
            return cls.__get_buy_index_with_cancel_data_by_ths_l2(code, cancel_data, local_today_num_operate_map)
    # 根据买撤数据(与今日总的数据)计算买入数据
    @classmethod
server.py
@@ -22,7 +22,7 @@
import l2.l2_data_util
from output import code_info_output
from third_data import hot_block_data_process, block_info, kpl_api
from third_data import  block_info, kpl_api
from third_data.code_plate_key_manager import CodesHisReasonAndBlocksManager
from third_data.history_k_data_util import HistoryKDatasUtils
from third_data.kpl_data_manager import KPLCodeLimitUpReasonManager, KPLLimitUpDataRecordManager
@@ -46,6 +46,8 @@
    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True, pipe_juejin=None, pipe_ui=None):
        self.pipe_juejin = pipe_juejin  # 增加的参数
        self.pipe_ui = pipe_ui
        # 初始化数据
        block_info.init()
        socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate=bind_and_activate)
@@ -387,6 +389,10 @@
                                                                     gpcode_manager.get_limit_up_price(code),
                                                                     volumes_data)
                        gpcode_manager.FirstCodeManager.add_record(codes)
                        # 初始化板块信息
                        for code in codes:
                            block_info.init_code(code)
                        if new_add_codes:
                            gpcode_manager.set_first_gp_codes_with_data(HistoryKDatasUtils.get_gp_latest_info(codes,
                                                                                                              fields="symbol,sec_name,sec_type,sec_level"))
@@ -776,8 +782,8 @@
                    data_json = data_process.parse(_str)
                    day = data_json["day"]
                    datas = data_json["data"]
                    if datas:
                        hot_block_data_process.save_datas(day, datas)
                    # if datas:
                    #     hot_block_data_process.save_datas(day, datas)
                    print(datas)
                elif type == 71:
                    # 根据代码获取选股宝热门概念
third_data/block_info.py
@@ -9,6 +9,8 @@
from third_data.history_k_data_util import HistoryKDatasUtils
from third_data.kpl_data_manager import KPLLimitUpDataRecordManager, KPLDataManager
from third_data import kpl_data_manager
__before_block_dict = {}
__kplDataManager = KPLDataManager()
@@ -160,7 +162,7 @@
                code_ = d[3]
                limit_up_codes_info_set.add((code_, d[5]))
                block_codes_set.add(code_)
            elif d[3]==code:
            elif d[3] == code:
                limit_up_codes_info_set.add((d[3], d[5]))
    # 获取涨停的顺序
    limit_up_index = -1
@@ -229,5 +231,16 @@
    return fresult
# 初始化板块数据
def init():
    # 加载数据到内存中
    kpl_data_manager.get_current_limit_up_data_records(10)
def init_code(code):
    # 加载历史涨停原因
    __load_before_block(code)
if __name__ == "__main__":
    get_info("603133")
third_data/block_test.py
New file
@@ -0,0 +1,20 @@
from third_data import kpl_data_manager
from third_data.code_plate_key_manager import CodePlateKeyBuyManager, LimitUpCodesPlateKeyManager
from third_data.kpl_util import KPLDataType
from utils import tool
if __name__ == "__main__":
    code = "002559"
    latest_2_day_limit_up_datas_temp = kpl_data_manager.get_current_limit_up_data_records(2)
    latest_2_day_limit_up_datas = []
    for d in latest_2_day_limit_up_datas_temp:
        latest_2_day_limit_up_datas.extend(d[1])
    current_limit_up_datas = kpl_data_manager.KPLDataManager().get_from_file(KPLDataType.LIMIT_UP,
                                                                             tool.get_now_date_str())
    LimitUpCodesPlateKeyManager().set_today_limit_up([(d[0], d[5]) for d in current_limit_up_datas])
    limit_up_record_datas = kpl_data_manager.KPLLimitUpDataRecordManager.list_all(tool.get_now_date_str())
    results = CodePlateKeyBuyManager.get_can_buy_block(code, current_limit_up_datas, latest_2_day_limit_up_datas,
                                             limit_up_record_datas)
    print(results)
third_data/code_plate_key_manager.py
@@ -6,6 +6,7 @@
import json
import constant
from third_data import kpl_block_util
from utils import global_util, tool
from log_module import log
from db import redis_manager
@@ -124,9 +125,9 @@
                # (名称,净流入金额,排名)
                temp_list.append((datas[i][1], datas[i][3], len(temp_list)))
                # 只获取前10个
                if len(temp_list) > 5:
                if len(temp_list) > 10:
                    break
                if datas[i][3] < 1 * 10000 * 10000:
                if datas[i][3] < 3 * 10000 * 10000:
                    break
        for temp in temp_list:
@@ -147,9 +148,9 @@
            if datas[i][1] in constant.KPL_INVALID_BLOCKS:
                continue
            temp_list.append((datas[i][1], datas[i][2], len(temp_list)))
            if len(temp_list) > 5:
            if len(temp_list) > 10:
                break
            if datas[i][2] < 1 * 10000 * 10000:
            if datas[i][2] < 3 * 10000 * 10000:
                break
        cls.top_5_industry_list = temp_list
        cls.__reset_top_5_dict()
@@ -212,7 +213,7 @@
            return False, None
#
# 代码历史涨停原因与板块管理
class CodesHisReasonAndBlocksManager:
    __redisManager = redis_manager.RedisManager(1)
    # 历史涨停原因
@@ -273,7 +274,7 @@
        return reasons | blocks
# 目标代码关键词管理
# 目标代码板块关键词管理
class TargetCodePlateKeyManager:
    __redisManager = redis_manager.RedisManager(1)
    __CodesPlateKeysManager = CodesHisReasonAndBlocksManager()
@@ -287,7 +288,7 @@
        k1 = set()
        if code in LimitUpCodesPlateKeyManager.today_total_limit_up_reason_dict:
            k1 = {LimitUpCodesPlateKeyManager.today_total_limit_up_reason_dict[code]}
        # 加载历史原因
        # 加载今日历史原因
        k11 = self.__get_redis().smembers(f"kpl_limit_up_reason_his-{code}")
        k2 = self.__CodesPlateKeysManager.get_history_limit_up_reason(code)
        if k2 is None:
@@ -310,22 +311,155 @@
class CodePlateKeyBuyManager:
    # 无板块
    BLOCK_TYPE_NONE = -1
    # 一般板块
    BLOCK_TYPE_COMMON = 0
    # 强势板块
    BLOCK_TYPE_STRONG = 1
    # 猛拉板块
    BLOCK_TYPE_SOON_LIMIT_UP = 2
    # 潜伏板块
    BLOCK_TYPE_START_UP = 3
    __TargetCodePlateKeyManager = TargetCodePlateKeyManager()
    __LimitUpCodesPlateKeyManager = LimitUpCodesPlateKeyManager()
    __CodesHisReasonAndBlocksManager = CodesHisReasonAndBlocksManager()
    # 是否可以下单
    # 获取可以买的板块
    # current_limit_up_datas: 今日实时涨停
    # latest_2_day_limit_up_datas:最近2天的实时涨停(不含今日)
    # limit_up_record_datas:今日历史涨停
    @classmethod
    def can_buy(cls, code):
        if constant.TEST:
            return True, ""
    def get_can_buy_block(cls, code, current_limit_up_datas, latest_2_day_limit_up_datas, limit_up_record_datas):
        now_time = int(tool.get_now_time_str().replace(":", ""))
        times = [100000, 103000, 110000, 133000, 150000]
        time_index = 0
        for i in range(len(times)):
            if now_time < times[i]:
                time_index = i
                break
        # 获取板块
        keys, k1, k11, k2, k3, k4 = cls.__TargetCodePlateKeyManager.get_plate_keys(code)
        log.logger_kpl_debug.info("{}关键词:{},{},{},{},{},{}", code, keys, k1, k11, k2, k3, k4)
        # 涨停列表中匹配关键词
        log.logger_kpl_debug.info("{}关键词:所有-{},今日-{},今日历史-{},历史-{},二级行业-{},代码板块-{}", code, keys, k1, k11, k2, k3, k4)
        # 涨停列表中匹配关键词,返回(板块:代码集合),代码集合中已经排除自身
        match_limit_up_result = cls.__LimitUpCodesPlateKeyManager.match_limit_up_reason_keys(code, keys)
        log.logger_kpl_debug.info("{}关键词身位匹配结果:{}", code, match_limit_up_result)
        if not match_limit_up_result:
            return False, "未在涨停列表中未匹配到涨停原因"
            return cls.BLOCK_TYPE_NONE, None, "未在涨停列表中未匹配到涨停原因"
        # 获取板块归类
        for block in match_limit_up_result:
            # 获取强势板块
            strong_result = kpl_block_util.is_strong_block(block, current_limit_up_datas, latest_2_day_limit_up_datas)
            # 获取猛拉板块
            soon_limit_up_result = kpl_block_util.is_soon_limit_up(code, block, limit_up_record_datas)
            # 获取身位
            rank = kpl_block_util.get_code_rank(code, block, limit_up_record_datas)
            # 主板身位
            sh_sz_rank = kpl_block_util.get_sh_sz_code_rank(code, block, limit_up_record_datas)
            # 是否后排
            is_back_row = kpl_block_util.is_back_row(code, block, current_limit_up_datas)
            # 是否满足市场流入前几
            is_in_top_input = RealTimeKplMarketData.is_in_top(set([block]))[0]
            log.logger_kpl_debug.info("{}-{}  板块判断结果:强势板块-{}  猛拉板块-{} 身位-{} 主板身位-{} 是否后排-{} 是否在流入前排-{}", code, block,
                                      strong_result, soon_limit_up_result, rank, sh_sz_rank, is_back_row,
                                      is_in_top_input)
            if time_index == 0:
                # 09:30:00 - 10:00:00
                if strong_result[0]:
                    # 强势板块
                    # 买主板龙1,2,3,4  买后排
                    if is_back_row and sh_sz_rank <= 3:
                        return cls.BLOCK_TYPE_STRONG, block, f"{block} 强势板块:买主板龙1,2,3,4  买后排"
                if soon_limit_up_result[0]:
                    # 猛拉板块
                    # 只买龙2 买后排
                    if is_back_row and rank == 1:
                        return cls.BLOCK_TYPE_SOON_LIMIT_UP, block, f"{block} 猛拉板块:只买龙2,买后排"
                # 其他板块
                if is_in_top_input and sh_sz_rank <= 1 and is_back_row:
                    # 看精选/行业流入   买龙主板1,2  买后排
                    return cls.BLOCK_TYPE_COMMON, block, f"{block} 其他板块:看精选/行业流入   买龙主板1,2  买后排"
            elif time_index == 1:
                # 10:00:00 - 10:30:00
                if strong_result[0]:
                    # 强势板块
                    # 买主板龙1,2,3  买后排
                    if is_back_row and sh_sz_rank <= 2:
                        return cls.BLOCK_TYPE_STRONG, block, f"{block} 强势板块:买主板龙1,2,3  买后排"
                if soon_limit_up_result[0]:
                    # 猛拉板块
                    # 只买龙2 买后排
                    if is_back_row and rank == 1:
                        return cls.BLOCK_TYPE_SOON_LIMIT_UP, block, f"{block} 猛拉板块:只买龙2,买后排"
                # 其他板块
                if is_in_top_input and sh_sz_rank <= 1 and is_back_row:
                    # 看精选/行业流入   买龙主板1,2  买后排
                    return cls.BLOCK_TYPE_COMMON, block, f"{block} 其他板块:看精选/行业流入   买龙主板1,2  买后排"
            elif time_index == 2:
                # 10:30:00 - 11:00:00
                if strong_result[0]:
                    # 强势板块
                    # 买主板龙1,2  买后排
                    if is_back_row and sh_sz_rank <= 1:
                        return cls.BLOCK_TYPE_STRONG, block, f"{block} 强势板块:买主板龙1,2  买后排"
                if soon_limit_up_result[0]:
                    # 猛拉板块
                    # 只买龙2 买后排
                    if is_back_row and rank == 1:
                        return cls.BLOCK_TYPE_SOON_LIMIT_UP, block, f"{block} 猛拉板块:只买龙2,买后排"
                # 其他板块
                if is_in_top_input and sh_sz_rank <= 1 and is_back_row:
                    # 看精选/行业流入   买龙主板1,2  买后排
                    return cls.BLOCK_TYPE_COMMON, block, f"{block} 其他板块:看精选/行业流入   买龙主板1,2  买后排"
            elif time_index == 3:
                # 11:00:00 - 13:30:00
                if soon_limit_up_result[0]:
                    # 猛拉板块
                    # 只买龙2 买后排
                    if is_back_row and rank == 1:
                        return cls.BLOCK_TYPE_SOON_LIMIT_UP, block, f"{block} 猛拉板块:只买龙2,买后排"
                # 其他板块
                if is_in_top_input and sh_sz_rank <= 1 and is_back_row:
                    # 看精选/行业流入   买龙主板1,2  买后排
                    return cls.BLOCK_TYPE_COMMON, block, f"{block} 其他板块:看精选/行业流入,买龙主板1,2 ,买后排"
            elif time_index == 4:
                # 13:30:00 - 15:00:00
                if soon_limit_up_result[0]:
                    # 猛拉板块
                    # 只买龙2 买后排
                    if is_back_row and rank == 1:
                        return cls.BLOCK_TYPE_SOON_LIMIT_UP, block, f"{block} 猛拉板块:只买龙2,买后排"
                # 其他板块
                if is_in_top_input:
                    # 精选/行业流入符合
                    if sh_sz_rank <= 1 and is_back_row:
                        # 看精选/行业流入   买龙主板1,2  买后排
                        return cls.BLOCK_TYPE_COMMON, block, f"{block} 其他板块:精选/行业流入符合,买龙主板1,2,买后排"
                else:
                    if sh_sz_rank == 0 and not is_back_row:
                        return cls.BLOCK_TYPE_START_UP, block, f"{block} 其他板块: 买主板龙1,买主板独苗"
        return cls.BLOCK_TYPE_NONE, None, f"板块({match_limit_up_result.keys()})不符合买入条件"
    # 是否可以下单
    # 返回:是否可以下单,消息,板块类型
    @classmethod
    def can_buy(cls, code, current_limit_up_datas, latest_2_day_limit_up_datas, limit_up_record_datas):
        if constant.TEST:
            return True, "", cls.BLOCK_TYPE_NONE
        block_type, block, block_msg = cls.get_can_buy_block(code, current_limit_up_datas, latest_2_day_limit_up_datas,
                                                             limit_up_record_datas)
        if block_type == cls.BLOCK_TYPE_NONE:
            return False, block_msg, block_type
        # ---------------------------------判断目标代码的板块-------------------start------------
        # 判断匹配出的涨停原因,判断是否有已经下单的票
@@ -358,22 +492,22 @@
        # ---------------------------------判断目标代码的板块-------------------end------------
        # 获取板块可以下单的个数
        can_buy_codes_count_dict = {}
        # can_buy_codes_count_dict = {}
        #
        # for key__ in match_limit_up_result:
        #     can_buy_count, msg = RealTimeKplMarketData.get_can_buy_codes_count(code, key__)
        #     can_buy_codes_count_dict[key__] = can_buy_count
        for key__ in match_limit_up_result:
            can_buy_count, msg = RealTimeKplMarketData.get_can_buy_codes_count(code, key__)
            can_buy_codes_count_dict[key__] = can_buy_count
        has_available_key = False
        for key in can_buy_codes_count_dict:
            if can_buy_codes_count_dict[key] > 0:
                has_available_key = True
                break
        if not has_available_key:
            return False, f"匹配到的【{','.join(match_limit_up_result.keys())}】没在精选/行业可以买入的板块中"
        # has_available_key = False
        # for key in can_buy_codes_count_dict:
        #     if can_buy_codes_count_dict[key] > 0:
        #         has_available_key = True
        #         break
        # if not has_available_key:
        #     return False, f"匹配到的【{','.join(match_limit_up_result.keys())}】没在精选/行业可以买入的板块中"
        # ---------------------------------加载已经下单/成交的代码信息------------start-------------
        match_reasons = match_limit_up_result.keys()
        # match_reasons = match_limit_up_result.keys()
        # 判断匹配到的原因是否已经有下单/买入成功的代码
        codes_delegate = set(trade_manager.get_codes_by_trade_states(
            {trade_manager.TRADE_STATE_BUY_DELEGATED, trade_manager.TRADE_STATE_BUY_PLACE_ORDER}))
@@ -385,7 +519,7 @@
        # 统计成交代码的板块
        trade_codes_blocks_dict = {}
        # 已经成交的板块
        trade_success_blocks = set()
        trade_success_blocks_count = {}
        for c in codes:
            keys_, k1_, k11_, k2_, k3_, k4_ = cls.__TargetCodePlateKeyManager.get_plate_keys(c)
            # 实时涨停原因
@@ -395,7 +529,9 @@
        for c in trade_codes_blocks_dict:
            for b in trade_codes_blocks_dict[c]:
                if c in codes_success:
                    trade_success_blocks.add(b)
                    if b not in trade_success_blocks_count:
                        trade_success_blocks_count[b] = set()
                    trade_success_blocks_count[b].add(c)
                if b not in trade_block_codes_dict:
                    trade_block_codes_dict[b] = set()
                trade_block_codes_dict[b].add(c)
@@ -403,27 +539,32 @@
        # ---------------------------------加载已经下单/成交的代码信息------------end-------------
        msg_list = []
        for key in can_buy_codes_count_dict:
            log.logger_kpl_debug.debug(f"{code}:板块可以下单的数量【{key}】-{can_buy_codes_count_dict[key]}")
            if can_buy_codes_count_dict[key] < 1:
                continue
        for key in [block]:
            # 板块中已经有成交的就不下单了
            if key in trade_success_blocks:
                msg_list.append(f"【{key}】中已经有成交代码")
                log.logger_kpl_debug.debug(f"{code}:板块已经有成交【{key}】")
                continue
            if key in trade_success_blocks_count:
                success_codes_count = len(trade_success_blocks_count[key])
                if success_codes_count >= 2:
                    msg_list.append(f"【{key}】中已经有{success_codes_count}个成交代码")
                    log.logger_kpl_debug.debug(f"{code}:板块({key})已经有成交【{trade_success_blocks_count[key]}】")
                    continue
                # 10:30以后买1个
                if int(tool.get_now_time_str().replace(":", "")) > int("103000") and success_codes_count >= 1:
                    msg_list.append(f"【{key}】中已经有{success_codes_count}个成交代码")
                    log.logger_kpl_debug.debug(f"{code}:板块({key})已经有成交【{trade_success_blocks_count[key]}】")
                    continue
            return True, block_msg, block_type
            # 板块可以下单数量
            if trade_block_codes_dict.get(key) is None or len(trade_block_codes_dict.get(key)) < \
                    can_buy_codes_count_dict[key]:
                order_count = len(trade_block_codes_dict.get(key)) if key in trade_block_codes_dict else 0
                logger_kpl_block_can_buy.info(
                    f"code={code}:【{key}】可以下单,现有数量:{order_count} 最大数量:{can_buy_codes_count_dict[key]}")
                return True, f"可以下单,板块:【{key}】,板块中已经下单的数量:{order_count}"
            else:
                order_count = len(trade_block_codes_dict.get(key))
                msg_list.append(f"【{key}】中下单代码数量{order_count}/允许下单数量{can_buy_codes_count_dict[key]}")
            # if trade_block_codes_dict.get(key) is None or len(trade_block_codes_dict.get(key)) < \
            #         can_buy_codes_count_dict[key]:
            #     order_count = len(trade_block_codes_dict.get(key)) if key in trade_block_codes_dict else 0
            #     logger_kpl_block_can_buy.info(
            #         f"code={code}:【{key}】可以下单,现有数量:{order_count} 最大数量:{can_buy_codes_count_dict[key]}")
            #     return True, f"可以下单,板块:【{key}】,板块中已经下单的数量:{order_count}"
            # else:
            #     order_count = len(trade_block_codes_dict.get(key))
            #     msg_list.append(f"【{key}】中下单代码数量{order_count}/允许下单数量{can_buy_codes_count_dict[key]}")
        return False, ",".join(msg_list)
        return False, ",".join(msg_list), block_type
if __name__ == "__main__":
third_data/hot_block.py
File was deleted
third_data/hot_block.spec
File was deleted
third_data/hot_block_data_process.py
File was deleted
third_data/kpl_block_util.py
New file
@@ -0,0 +1,121 @@
"""
开盘啦板块工具
"""
# 是否是强势板块
# current_limit_up_datas:实时涨停数据 (代码, 名称, 首次涨停时间, 最近涨停时间, 几板, 涨停原因, 板块, 实际流通, 主力净额,涨停原因代码,涨停原因代码数量)
import datetime
import time
from utils import tool
# latest_2_day_limit_up_datas:最近2天涨停数据
def is_strong_block(block, current_limit_up_datas, latest_2_day_limit_up_datas):
    # 是否开1,且尚未炸板
    if current_limit_up_datas:
        # 获取今日9:30的时间戳
        time_str = datetime.datetime.now().strftime("%Y-%m-%d") + " 09:30:00"
        timestamp = time.mktime(time.strptime(time_str, '%Y-%m-%d %H:%M:%S'))
        for k in current_limit_up_datas:
            if k[5] == block:
                if int(k[2]) < timestamp:
                    return True, "开一"
                elif k[0].find("30") == 0 or k[0].find("68") == 0:
                    return True, "20cm涨停"
        # 板块有二板且(3天内板块内无高于二板的票)
        has_continue_limit_up = False
        for k in current_limit_up_datas:
            if k[5] == block:
                if k[4] == "2连板":
                    has_continue_limit_up = True
                    break
        total_limit_up_datas = list(latest_2_day_limit_up_datas)
        total_limit_up_datas.extend(current_limit_up_datas)
        for k in total_limit_up_datas:
            if k[5] == block:
                if k[4].find("连板") > 0 and int(k[4][:1]) > 2:
                    has_continue_limit_up = False
                    break
        if has_continue_limit_up:
            return True, "板块有二板且3天内板块内无高于二板"
    return False, ""
# 是否是猛拉板块
# limit_up_record_datas 今日历史涨停
def is_soon_limit_up(code, block, limit_up_record_datas):
    block_codes_infos = []
    limit_up_time = time.time()
    for k in limit_up_record_datas:
        if k[2] == block:
            if k[3] != code:
                block_codes_infos.append((k[3], int(k[5])))
            else:
                limit_up_time = int(k[5])
    # 排序
    block_codes_infos.append((code, limit_up_time))
    block_codes_infos.sort(key=lambda x: x[1])
    if len(block_codes_infos) < 2:
        return False, ""
    if block_codes_infos[1][1] - block_codes_infos[0][1] < 30 * 60:
        # 首次涨停时间间隔30分钟内
        return True, f"板块:{block}  龙1:{block_codes_infos[0][0]} 龙2:{block_codes_infos[1][0]}"
    return False, ""
# 代码是否是后排
def is_back_row(code, block, current_limit_up_datas):
    codes = set()
    for k in current_limit_up_datas:
        if k[5] == block:
            codes.add(k[0])
    codes.discard(code)
    if len(codes) == 0:
        return False
    else:
        return True
# 获取主板身位
def get_sh_sz_code_rank(code, block, limit_up_record_datas):
    block_codes_infos = []
    limit_up_time = time.time()
    for k in limit_up_record_datas:
        if k[3].find("00") != 0 and k[3].find("60") != 0:
            continue
        if k[2] == block:
            if k[3] != code:
                block_codes_infos.append((k[3], int(k[5])))
            else:
                limit_up_time = int(k[5])
    block_codes_infos.append((code, limit_up_time))
    block_codes_infos.sort(key=lambda x: x[1])
    for i in range(0, len(block_codes_infos)):
        if block_codes_infos[i][0] == code:
            return i
    return 0
# 获取身位
def get_code_rank(code, block, limit_up_record_datas):
    block_codes_infos = []
    limit_up_time = time.time()
    for k in limit_up_record_datas:
        if k[2] == block:
            if k[3] != code:
                block_codes_infos.append((k[3], int(k[5])))
            else:
                limit_up_time = int(k[5])
    block_codes_infos.append((code, limit_up_time))
    block_codes_infos.sort(key=lambda x: x[1])
    for i in range(0, len(block_codes_infos)):
        if block_codes_infos[i][0] == code:
            return i
    return 0
if __name__ == "__main__":
    pass
third_data/kpl_data_manager.py
@@ -10,9 +10,8 @@
from third_data import kpl_util, kpl_api
from third_data.code_plate_key_manager import LimitUpCodesPlateKeyManager, CodesHisReasonAndBlocksManager
# 代码对应的涨停原因保存
from third_data.kpl_util import KPLPlatManager
from third_data.kpl_util import KPLPlatManager, KPLDataType
class KPLCodeLimitUpReasonManager:
@@ -33,17 +32,16 @@
        return dict_
class KPLLimitUpDataRecordManager:
    total_datas = None
    latest_datas = {}
    latest_origin_datas=[]
    __kplPlatManager = KPLPlatManager()
    __LimitUpCodesPlateKeyManager = LimitUpCodesPlateKeyManager()
    __CodesPlateKeysManager = CodesHisReasonAndBlocksManager()
    @classmethod
    def __load_hist_and_blocks(cls,code):
    def __load_hist_and_blocks(cls, code):
        # 有数据新增,加载历史原因与板块
        his_reasons = cls.get_latest_infos(code, 10, False)
        his_reasons = set([r[0] for r in his_reasons])
@@ -55,7 +53,6 @@
                cls.__CodesPlateKeysManager.set_blocks(code, bs)
        except Exception as e:
            pass
    @classmethod
    def save_record(cls, day, records):
@@ -70,6 +67,7 @@
                code_block_dict[code].add(b)
                # 设置涨停数据
        if records:
            cls.latest_origin_datas = records
            cls.__LimitUpCodesPlateKeyManager.set_today_limit_up([(r[0], r[5]) for r in records])
        # 涨停数据记录
@@ -212,6 +210,28 @@
                return json.loads(lines[0])
        return None
    # 获取最近几天的数据,根据日期倒序返回
    def get_latest_from_file(self, type, count):
        files = os.listdir(constant.CACHE_PATH)
        file_name_list = []
        for f in files:
            if f[10:] == f"_{type.value}.log":
                file_name_list.append((f.split("_")[0], f))
        file_name_list.sort(key=lambda x: x[0], reverse=True)
        file_name_list = file_name_list[:count]
        fresults = []
        for file in file_name_list:
            path = f"{constant.CACHE_PATH}/{file[1]}"
            if not os.path.exists(path):
                continue
            with open(path, 'r') as f:
                lines = f.readlines()
                if lines:
                    fresults.append((file[0], json.loads(lines[0])))
        return fresults
    def save_data(self, type, datas):
        self.__latest_datas[type] = datas
        self.__save_in_file(type, datas)
@@ -244,6 +264,34 @@
            # print(day, list_)
# 历史涨停列表
__limit_up_list_records_dict = {}
# 获取最近几天的实时涨停信息
# 返回格式([日期,数据])
def get_current_limit_up_data_records(count):
    fresults = []
    day = tool.get_now_date_str()
    datas = []
    if day in __limit_up_list_records_dict:
        datas = __limit_up_list_records_dict[day]
    else:
        datas = KPLDataManager().get_latest_from_file(KPLDataType.LIMIT_UP, 10)
        if datas:
            # 保存数据
            __limit_up_list_records_dict[day] = datas
    for i in range(len(datas)):
        if datas[i][0] == day:
            continue
        fresults.append(datas[i])
        if len(fresults) >= count:
            break
    return fresults
if __name__ == "__main__":
    ds = set(["1", "2", "3"])
    print(ds.pop())
    fresults = get_current_limit_up_data_records(2)
    for d in fresults:
        print(d)
    get_current_limit_up_data_records(2)
trade/current_price_process_manager.py
@@ -169,3 +169,16 @@
                            break
            print(add_code_list, del_code_list)
__trade_price_dict = {}
# 设置成交价
def set_trade_price(code, price):
    __trade_price_dict[code] = price
# 获取成交价
def get_trade_price(code):
    return __trade_price_dict.get(code)
trade/huaxin/trade_api_server.py
@@ -13,6 +13,7 @@
from l2 import l2_data_manager_new
from l2.huaxin import huaxin_target_codes_manager
from log_module.log import  hx_logger_trade_debug
from third_data import block_info
from third_data.history_k_data_util import HistoryKDatasUtils
from trade import trade_manager, trade_huaxin
@@ -367,6 +368,9 @@
        try:
            datas = huaxin_target_codes_manager.pop()
            if datas:
                codes = [d[0] for d in datas]
                for code in codes:
                    block_info.init_code(code)
                result = huaxin_trade_api.set_l2_codes_data(datas)
                print("设置L2代码结果:", result)
        except Exception as e:
trade/huaxin/trade_server.py
@@ -8,13 +8,16 @@
import threading
import time
import dask
from code_attribute import gpcode_manager
from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, l2_data_manager
from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, l2_data_manager, transaction_progress
from l2.cancel_buy_strategy import HourCancelBigNumComputer, LCancelBigNumComputer, DCancelBigNumComputer
from l2.huaxin import huaxin_target_codes_manager
from log_module.log import hx_logger_l2_upload, hx_logger_contact_debug, hx_logger_trade_callback, \
    hx_logger_l2_orderdetail, hx_logger_l2_transaction, hx_logger_l2_market_data, logger_l2_trade_buy_queue
from trade import deal_big_money_manager
from third_data import block_info
from trade import deal_big_money_manager, current_price_process_manager
from trade.huaxin import huaxin_trade_api as trade_api, trade_api_server, huaxin_trade_api
@@ -32,6 +35,7 @@
class MyBaseRequestHandle(socketserver.BaseRequestHandler):
    __inited = False
    __TradeBuyQueue = transaction_progress.TradeBuyQueue()
    def setup(self):
        self.__init()
@@ -159,6 +163,9 @@
                        code = data["code"]
                        datas = data["data"]
                        hx_logger_l2_transaction.info(f"{code}#{datas}")
                        if datas:
                            # 设置成交价
                            current_price_process_manager.set_trade_price(code, datas[-1][1])
                        try:
                            buyno_map = l2_data_util.local_today_buyno_map.get(code)
                            hx_logger_l2_transaction.info(f"{code}的买入订单号数量:{len(buyno_map.keys()) if buyno_map else 0}")
@@ -174,32 +181,38 @@
                                code)
                            if True:
                                if buy_progress_index is not None:
                                    self.__TradeBuyQueue.set_traded_index(code, buy_progress_index)
                                    total_datas = l2_data_util.local_today_datas.get(code)
                                    num_operate_map = l2_data_util.local_today_num_operate_map.get(
                                        code)
                                    logger_l2_trade_buy_queue.info("获取成交位置成功: code-{} index-{}", code,
                                                                   buy_progress_index)
                                    buy_time = l2_data_util.local_today_datas.get(code)[buy_progress_index]["val"][
                                    buy_time = total_datas[buy_progress_index]["val"][
                                        "time"]
                                    HourCancelBigNumComputer.set_trade_progress(code, buy_time, buy_exec_index,
                                                                                buy_progress_index,
                                                                                l2_data_util.local_today_datas.get(
                                                                                    code),
                                                                                l2_data_util.local_today_num_operate_map.get(
                                                                                    code))
                                    LCancelBigNumComputer.set_trade_progress(code, buy_progress_index,
                                                                             l2_data_util.local_today_datas.get(
                                                                                 code))
                                    # 计算大单成交额
                                    deal_big_money_manager.set_trade_progress(code, buy_progress_index,
                                                                              l2_data_util.local_today_datas.get(
                                                                                  code),
                                                                              l2_data_util.local_today_num_operate_map.get(
                                                                                  code))
                                    DCancelBigNumComputer.set_trade_progress(code, buy_progress_index, buy_exec_index,
                                                                             l2_data_util.local_today_datas.get(
                                                                                 code),
                                                                             l2_data_util.local_today_num_operate_map.get(
                                                                                 code), 1000 * 10000,
                                                                             gpcode_manager.get_limit_up_price(code))
                                                                                buy_progress_index, total_datas,
                                                                                num_operate_map)
                                    f1 = dask.delayed(HourCancelBigNumComputer.set_trade_progress)(code, buy_time,
                                                                                                   buy_exec_index,
                                                                                                   buy_progress_index,
                                                                                                   total_datas,
                                                                                                   num_operate_map)
                                    f2 = dask.delayed(LCancelBigNumComputer.set_trade_progress)(code,
                                                                                                buy_progress_index,
                                                                                                total_datas)
                                    f3 = dask.delayed(deal_big_money_manager.set_trade_progress)(code,
                                                                                                 buy_progress_index,
                                                                                                 total_datas,
                                                                                                 num_operate_map)
                                    f4 = dask.delayed(DCancelBigNumComputer.set_trade_progress)(code,
                                                                                                buy_progress_index,
                                                                                                buy_exec_index,
                                                                                                total_datas,
                                                                                                num_operate_map,
                                                                                                1000 * 10000,
                                                                                                gpcode_manager.get_limit_up_price(
                                                                                                    code))
                                    dask.compute(f1, f2, f3, f4)
                        except Exception as e:
                            hx_logger_l2_transaction.exception(e)
@@ -251,6 +264,9 @@
def run():
    # 执行一些初始化数据
    block_info.init()
    print("create TradeServer")
    t1 = threading.Thread(target=lambda: clear_invalid_client(), daemon=True)
    t1.start()