Administrator
2024-05-28 517f6c8ce6c68bfcd652ceeb7b79f79408dfec76
third_data/code_plate_key_manager.py
@@ -443,6 +443,11 @@
    # 返回key集合(排除无效板块),今日涨停原因,今日历史涨停原因,历史涨停原因,二级,精选板块
    def get_plate_keys(self, code):
        """
        获取代码的板块
        @param code:
        @return: (板块关键词集合,今日涨停原因+涨停推荐原因,今日历史涨停原因,历史涨停原因,精选板块)
        """
        keys = set()
        k1 = set()
@@ -508,65 +513,30 @@
    # 是否需要激进买
    @classmethod
    def __is_need_active_buy(cls, code, block, current_limit_up_datas, limit_up_record_datas,
                             yesterday_current_limit_up_codes):
        code_limit_up_reason_dict = {}
        for d in limit_up_record_datas:
            code_limit_up_reason_dict[d[3]] = d[2]
    def __is_need_active_buy(cls, code, block, current_rank, open_limit_up_count):
        """
        板块是否需要激进买入
        规则:根据身位判断是否需要激进买,根据时间划分
        @param code: 代码
        @param block: 板块名称
        @param current_rank: 目前在板块中的身位,从0开始
        @param open_limit_up_count: 开1的数量
        @return:
        """
        # 前面有高位板/非主板涨停且曾涨停主板排老大则激进买
        block_codes_info = []
        contains_code = False
        for d in current_limit_up_datas:
            reason = kpl_util.get_current_limit_up_reason(d)
            if reason != block:
                continue
            if d[0] == code:
                contains_code = True
            # 格式:[代码,涨停时间,是否高位板, 自由流通市值]
            block_codes_info.append((d[0], d[2], d[0] in yesterday_current_limit_up_codes, d[7]))
        if not contains_code:
            block_codes_info.append((code, int(time.time()), False, global_util.zyltgb_map.get(code)))
        block_codes_info.sort(key=lambda x: x[1])
        # 暂存在当前代码之前涨停的高位板/非主板代码
        before_codes = []
        for info in block_codes_info:
            if info[0] == code:
        real_current_rank = max(current_rank - open_limit_up_count, 0)
        TIME_STR_RANGES = ["10:00:00", "10:30:00", "11:00:00", "13:00:00", "13:30:00", "14:00:00", "14:30:00",
                           "15:00:00"]
        TIME_INT_RANGES = [int(x.replace(':', '')) for x in TIME_STR_RANGES]
        MAX_RANKS = [3, 3, 2, 2, 1, 0, 0, 0]
        now_time_str = tool.get_now_time_str().replace(':', '')
        for i in range(len(TIME_INT_RANGES)):
            if int(now_time_str) <= TIME_INT_RANGES[i]:
                if MAX_RANKS[i] > real_current_rank:
                    return True
                break
            if info[2] or not tool.is_shsz_code(info[0]):
                before_codes.append(info[0])
        if before_codes:
            # 判断历史涨停主板身位
            record_shsz_rank, record_shsz_rank_codes = kpl_block_util.get_code_record_rank(code, block,
                                                                                           limit_up_record_datas,
                                                                                           code_limit_up_reason_dict,
                                                                                           yesterday_current_limit_up_codes,
                                                                                           shsz=True)
            if record_shsz_rank == 0:
                # 历史主板老大
                return True, f"主板老大且前面有非主板/高位板涨停,先于涨停代码:{before_codes}"
        # 排除自己有3个涨停,且这4个中自由流通市值最小,且涨停过的代码中主板排名前4
        if len(block_codes_info) >= 4:
            temp_codes = []
            for info in block_codes_info:
                # 不是高位板且是主板
                if not info[2] and tool.is_shsz_code(info[0]):
                    # 格式:(代码, 自由流通市值)
                    temp_codes.append((info[0], info[3]))
            # 判断是否为主板中自由市值最小
            temp_codes.sort(key=lambda x: x[1])
            if temp_codes[0][0] == code:
                # 自由市值最小
                # 判断历史身位
                record_shsz_rank, record_shsz_rank_codes = kpl_block_util.get_code_record_rank(code, block,
                                                                                               limit_up_record_datas,
                                                                                               code_limit_up_reason_dict,
                                                                                               yesterday_current_limit_up_codes,
                                                                                               shsz=True)
                if record_shsz_rank < 4:
                    return True, f"板块有大于3票涨停,且自由流通市值最小,身位({record_shsz_rank})前4"
        return False, "不满足激进买入条件"
        return False
    # 返回内容(是否可买, 是否为独苗, 描述信息, 是否为强势主线, 是否需要激进买)
    @classmethod
@@ -581,18 +551,14 @@
        block_codes = current_limit_up_block_codes_dict.get(block)
        if block_codes is None:
            block_codes = set()
        # 计算是否需要激进买入
        active_buy = cls.__is_need_active_buy(code, block, current_limit_up_datas,
                                              limit_up_record_datas,
                                              yesterday_current_limit_up_codes)
        if not block_codes:
            # 高位板泛化板块中无板块
            if not high_level_block_codes.get(block):
                return False, True, f"{block}:板块无涨停", False, active_buy
                return False, True, f"{block}:板块无涨停", False, False
        elif len(block_codes) == 1 and code in block_codes:
            if not high_level_block_codes.get(block):
                return False, True, f"{block}:板块只有当前代码涨停", False, active_buy
                return False, True, f"{block}:板块只有当前代码涨停", False, False
        # 可以买的最大排名
        # open_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes(code, block, limit_up_record_datas,
        #                                                                   code_limit_up_reason_dict)
@@ -655,6 +621,9 @@
                                                                                                    current_open_limit_up_codes),
                                                                                                shsz=True,
                                                                                                limit_up_time=first_limit_up_time)
        # 计算是否需要激进买入
        is_active_buy = cls.__is_need_active_buy(code, block, current_shsz_rank, len(current_open_limit_up_codes))
        # record_shsz_rank, record_shsz_rank_codes = kpl_block_util.get_code_record_rank(code, block,
        #                                                                                limit_up_record_datas,
        #                                                                                code_limit_up_reason_dict,
@@ -662,10 +631,10 @@
        #                                                                                shsz=True)
        if int(tool.get_now_time_str().replace(":", "")) <= int("094000") and is_strong_block:
            # 强势主线加强势10分钟
            return True, False, f"【{block}】:强势主线+强势10分钟", is_strong_block, active_buy
            return True, False, f"【{block}】:强势主线+强势10分钟", is_strong_block, is_active_buy
        if current_shsz_rank < len(current_open_limit_up_codes) + max_rank:
            return True, False, f"【{block}】前排代码:{current_shsz_rank}", is_strong_block, active_buy
            return True, False, f"【{block}】前排代码:{current_shsz_rank}", is_strong_block, is_active_buy
        else:
            # k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
            # if k_format and k_format[8][0]:
@@ -678,8 +647,8 @@
                situation = MarketSituationManager().get_situation_cache()
                zylt_threshold_as_yi = buy_condition_util.get_zyltgb_threshold(situation)
                if zyltgb_as_yi and zylt_threshold_as_yi[2] <= zyltgb_as_yi <= zylt_threshold_as_yi[3]:
                    return True, False, f"【{block}】强势板块 自由流通市值({zyltgb_as_yi})大于{zylt_threshold_as_yi[2]}亿 小于{zylt_threshold_as_yi[3]}亿", is_strong_block, active_buy
            return False, False, f"【{block}】前排代码:{front_current_shsz_rank_codes} 超过{len(current_open_limit_up_codes) + max_rank}个", is_strong_block, active_buy
                    return True, False, f"【{block}】强势板块 自由流通市值({zyltgb_as_yi})大于{zylt_threshold_as_yi[2]}亿 小于{zylt_threshold_as_yi[3]}亿", is_strong_block, is_active_buy
            return False, False, f"【{block}】前排代码:{front_current_shsz_rank_codes} 超过{len(current_open_limit_up_codes) + max_rank}个", is_strong_block, is_active_buy
        # 过时的代码
        # if open_limit_up_codes:
@@ -699,6 +668,101 @@
        #             cls.__remove_from_l2(code, f"{code}根据身位禁止买入:【{block}】历史身位{record_shsz_rank}")
        #
        #         return False, f"板块-{block}: top4涨停板块,非主板开1,不为主板龙1(实时身位-{current_shsz_rank}:{front_current_shsz_rank_codes},历史身位-{record_shsz_rank})"
    @classmethod
    def __is_block_can_buy_new(cls, code, block, current_limit_up_datas, code_limit_up_reasons_dict,
                               yesterday_current_limit_up_codes, limit_up_record_datas,
                               current_limit_up_block_codes_dict,
                               high_level_code_blocks=None, high_level_block_codes=None):
        """
        该票的板块是否可以买
        @param code:
        @param block:
        @param current_limit_up_datas:
        @param code_limit_up_reasons_dict:
        @param yesterday_current_limit_up_codes:
        @param limit_up_record_datas:
        @param current_limit_up_block_codes_dict:
        @param high_level_code_blocks:
        @param high_level_block_codes:
        @return:
        """
        # 独苗判断
        if high_level_code_blocks is None:
            high_level_code_blocks = {}
        if high_level_block_codes is None:
            high_level_block_codes = {}
        block_codes = current_limit_up_block_codes_dict.get(block)
        if block_codes is None:
            block_codes = set()
        # 历史涨停代码
        block_codes_records = set()
        if limit_up_record_datas:
            for k in limit_up_record_datas:
                if block in code_limit_up_reasons_dict.get(k[3]):
                    block_codes_records.add(k[3])
        if not block_codes:
            # 高位板泛化板块中无板块
            if not high_level_block_codes.get(block):
                return False, True, f"{block}:板块无涨停", False, False, 0, 0, 0
        elif len(block_codes) == 1 and code in block_codes:
            if not high_level_block_codes.get(block):
                return False, True, f"{block}:板块只有当前代码涨停", False, False, 0, 0, 0
        # 可以买的最大排名
        # open_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes(code, block, limit_up_record_datas,
        #                                                                   code_limit_up_reason_dict)
        current_open_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes_current(code, block,
                                                                                          current_limit_up_datas)
        is_strong_block = False
        # 最多买老几
        RANKS = [5, 4, 3, 3, 3, 2, 2]
        RANK_TIMES = ["10:00:00", "10:30:00", "11:00:00", "11:30:00", "13:30:00", "14:00:00", "15:00:00"]
        now_time_str = tool.get_now_time_str()
        max_rank = 2
        for i in range(len(RANK_TIMES)):
            if tool.trade_time_sub(now_time_str, RANK_TIMES[i]) <= 0:
                max_rank = RANKS[i]
                break
        # 需要排除的老大的代码
        exclude_first_codes = set()
        # 获取主板开1的代码
        # 剔除高位板
        if current_open_limit_up_codes and yesterday_current_limit_up_codes:
            current_open_limit_up_codes -= yesterday_current_limit_up_codes
        # 获取代码的初次涨停时间
        first_limit_up_time = time.time()
        # if limit_up_record_datas:
        for r in limit_up_record_datas:
            if r[3] == code:
                first_limit_up_time = int(r[5])
        # 获取主板实时身位,剔除高位板
        current_shsz_rank, front_current_shsz_rank_codes = kpl_block_util.get_code_current_rank(code, block,
                                                                                                current_limit_up_datas,
                                                                                                code_limit_up_reasons_dict,
                                                                                                yesterday_current_limit_up_codes,
                                                                                                exclude_first_codes,
                                                                                                len(
                                                                                                    current_open_limit_up_codes),
                                                                                                shsz=True,
                                                                                                limit_up_time=first_limit_up_time)
        # 计算是否需要激进买入
        is_active_buy = cls.__is_need_active_buy(code, block, current_shsz_rank, len(current_open_limit_up_codes))
        if current_shsz_rank < len(current_open_limit_up_codes) + max_rank:
            return True, False, f"【{block}】前排代码:{current_shsz_rank}", is_strong_block, is_active_buy, current_shsz_rank, len(
                block_codes), len(block_codes_records)
        else:
            return False, False, f"【{block}】前排代码:{front_current_shsz_rank_codes} 超过{len(current_open_limit_up_codes) + max_rank}个", is_strong_block, is_active_buy, current_shsz_rank, len(
                block_codes), len(block_codes_records)
    # 获取可以买的板块
    # current_limit_up_datas: 今日实时涨停
@@ -720,8 +784,9 @@
                        code_limit_up_reasons_dict[d[3]] = {list(before_blocks_dict.get(d[3]))[0]}
                    else:
                        code_limit_up_reasons_dict[d[3]] = {d[2]}
                        if d[6]:
                            code_limit_up_reasons_dict[d[3]] |= set(d[6].split("、"))
                        # 不包含推荐原因
                        # if d[6]:
                        #     code_limit_up_reasons_dict[d[3]] |= set(d[6].split("、"))
            return code_limit_up_reasons_dict
        if current_limit_up_datas is None:
@@ -740,15 +805,17 @@
        code_limit_up_reasons_dict = {}
        load_code_block()
        for block in keys:
            can_buy, unique, msg, is_strong, active_buy_info = cls.__is_block_can_buy(code, block,
                                                                                      current_limit_up_datas,
                                                                                      code_limit_up_reasons_dict,
                                                                                      yesterday_current_limit_up_codes,
                                                                                      limit_up_record_datas,
                                                                                      current_limit_up_block_codes_dict,
                                                                                      high_level_code_blocks=high_level_general_code_blocks,
                                                                                      high_level_block_codes=high_level_general_block_codes)
            fresults.append((block, can_buy, unique, msg, is_strong, active_buy_info))
            can_buy, unique, msg, is_strong, is_active_buy, current_rank, block_limit_up_count, block_limit_up_record_count = cls.__is_block_can_buy_new(
                code, block,
                current_limit_up_datas,
                code_limit_up_reasons_dict,
                yesterday_current_limit_up_codes,
                limit_up_record_datas,
                current_limit_up_block_codes_dict,
                high_level_code_blocks=high_level_general_code_blocks,
                high_level_block_codes=high_level_general_block_codes)
            fresults.append((block, can_buy, unique, msg, is_strong, is_active_buy, current_rank, block_limit_up_count,
                             block_limit_up_record_count))
        return fresults, keys
    # 是否可以下单
@@ -757,7 +824,7 @@
    @classmethod
    def can_buy(cls, code):
        if constant.TEST:
            return ["测试"], True, cls.BLOCK_TYPE_NONE, [], set(),["化工"]
            return [("测试", 0, 1, 1)], True, cls.BLOCK_TYPE_NONE, [], set(), ["化工"]
        # if True:
        #     # 测试
        #     return True, "不判断板块身位"
@@ -834,21 +901,24 @@
                # 强势主线最多同时挂3只票,最多成交2只票
                MAX_DELEGATE_COUNT = 3 if r[4] else 2
                MAX_DEAL_COUNT = 2 if r[4] else 1
                if r[0] in trade_success_blocks_count and len(trade_success_blocks_count[r[0]]) >= MAX_DEAL_COUNT:
                    msg_list.append(f"【{r[0]}】有成交代码:{trade_success_blocks_count[r[0]]}")
                    continue
                if r[0] in trade_delegate_blocks_count and len(trade_delegate_blocks_count[r[0]]) >= MAX_DELEGATE_COUNT:
                    msg_list.append(f"【{r[0]}】已挂单:{trade_delegate_blocks_count[r[0]]}")
                    continue
                can_buy_blocks.append(r[0])
                # if r[0] in trade_success_blocks_count and len(trade_success_blocks_count[r[0]]) >= MAX_DEAL_COUNT:
                #     msg_list.append(f"【{r[0]}】有成交代码:{trade_success_blocks_count[r[0]]}")
                #     continue
                # if r[0] in trade_delegate_blocks_count and len(trade_delegate_blocks_count[r[0]]) >= MAX_DELEGATE_COUNT:
                #     msg_list.append(f"【{r[0]}】已挂单:{trade_delegate_blocks_count[r[0]]}")
                #     continue
                if len(r) > 8:
                    can_buy_blocks.append((r[0], r[6], r[7], r[8]))
                else:
                    # (板块名称,身位,板块涨停数量)
                    can_buy_blocks.append((r[0], 0, 1, 1))
                if r[4]:
                    can_buy_strong_blocks.append(r[0])
                if r[3]:
                    msg_list.append(r[3])
                if r[5][0]:
                if r[5]:
                    active_buy_blocks.append(r[0])
                    msg_list.append(f"【{r[0]}】激进买入({r[5][1]})")
                    msg_list.append(f"【{r[0]}】激进买入({r[5]})")
            else:
                if r[3]:
                    msg_list.append(r[3])
@@ -898,7 +968,8 @@
                                                                                                                   current_limit_up_block_codes_dict,
                                                                                                                   high_level_general_code_blocks)
        # 保存板块计算结果
        cls.__can_buy_compute_result_dict[code] = (can_buy_blocks, unique, msg, can_buy_strong_blocks, keys, active_buy_blocks)
        cls.__can_buy_compute_result_dict[code] = (
            can_buy_blocks, unique, msg, can_buy_strong_blocks, keys, active_buy_blocks)
if __name__ == "__main__":