Administrator
2025-05-26 b51b2ae184fad5aaf37a78903987e064f192d430
third_data/code_plate_key_manager.py
@@ -5,20 +5,25 @@
# 涨停代码关键词板块管理
import copy
import datetime
import itertools
import json
import time
import constant
from code_attribute import gpcode_manager
from db.redis_manager_delegate import RedisUtils
from third_data import kpl_block_util, kpl_api, kpl_util
from settings.trade_setting import MarketSituationManager
from third_data.history_k_data_manager import HistoryKDataManager
from third_data.history_k_data_util import HistoryKDatasUtils
from third_data.kpl_data_constant import LimitUpCodesBlockRecordManager, ContainsLimitupCodesBlocksManager
from third_data.third_blocks_manager import BlockMapManager
from utils import global_util, tool, buy_condition_util
from log_module import async_log_util
from db import redis_manager_delegate as redis_manager
from db import redis_manager_delegate as redis_manager, mysql_data_delegate as mysql_data
from log_module.log import logger_kpl_block_can_buy, logger_kpl_jx_out, logger_kpl_jx_in, logger_debug
from log_module.log import logger_kpl_block_can_buy, logger_kpl_jx_out, logger_kpl_jx_in, logger_debug, \
    logger_kpl_latest_gaobiao
from third_data.kpl_util import KPLPlatManager
from trade import l2_trade_util, trade_constant
@@ -227,6 +232,13 @@
    """
    __redis_manager = redis_manager.RedisManager(3)
    __kpl_forbidden_plates_cache = set()
    # 已经删除了的板块
    __deleted_kpl_forbidden_plates_cache = set()
    # 监控的高标板块代码字典:{"板块":{"代码1","代码2"}}
    __watch_block_high_codes = {}
    # 高标代码
    __watch_high_codes = set()
    __instance = None
@@ -241,8 +253,10 @@
        __redis = cls.__get_redis()
        try:
            cls.__kpl_forbidden_plates_cache = RedisUtils.smembers(__redis, "kpl_forbidden_plates")
            cls.__deleted_kpl_forbidden_plates_cache = RedisUtils.smembers(__redis, "deleted_kpl_forbidden_plates")
        finally:
            RedisUtils.realse(__redis)
        cls.__load_latest_gb()
    @classmethod
    def __get_redis(cls):
@@ -253,10 +267,17 @@
        RedisUtils.sadd(self.__get_redis(), "kpl_forbidden_plates", plate)
        RedisUtils.expire(self.__get_redis(), "kpl_forbidden_plates", tool.get_expire())
        self.__deleted_kpl_forbidden_plates_cache.discard(plate)
        RedisUtils.srem(self.__get_redis(), "deleted_kpl_forbidden_plates", plate)
        RedisUtils.expire(self.__get_redis(), "deleted_kpl_forbidden_plates", tool.get_expire())
    def delete_plate(self, plate):
        self.__kpl_forbidden_plates_cache.discard(plate)
        RedisUtils.srem(self.__get_redis(), "kpl_forbidden_plates", plate)
        RedisUtils.expire(self.__get_redis(), "kpl_forbidden_plates", tool.get_expire())
        self.__deleted_kpl_forbidden_plates_cache.add(plate)
        RedisUtils.sadd(self.__get_redis(), "deleted_kpl_forbidden_plates", plate)
        RedisUtils.expire(self.__get_redis(), "deleted_kpl_forbidden_plates", tool.get_expire())
    def list_all(self):
        return RedisUtils.smembers(self.__get_redis(), "kpl_forbidden_plates")
@@ -264,10 +285,131 @@
    def list_all_cache(self):
        return self.__kpl_forbidden_plates_cache
    def list_all_deleted_cache(self):
        return self.__deleted_kpl_forbidden_plates_cache
    def is_in_cache(self, plate):
        if self.__kpl_forbidden_plates_cache and plate in self.__kpl_forbidden_plates_cache:
            return True
        return False
    @classmethod
    def __load_latest_gb(cls):
        """
        加载最近的市场高标
        @return:
        """
        # 获取最近10个交易日涨停的涨停数据
        dates = HistoryKDatasUtils.get_latest_trading_date_cache(10)
        if not dates:
            return
        min_date = dates[-1]
        sql = f"SELECT r.`_code`, r.`_hot_block_name`, r.`_day`, r.`_open` FROM `kpl_limit_up_record` r WHERE r.`_day`>='{min_date}'"
        mysqldb = mysql_data.Mysqldb()
        results = mysqldb.select_all(sql)
        code_days_map = {}
        # 每炸板
        f_code_days_map = {}
        for r in results:
            if r[0] not in code_days_map:
                code_days_map[r[0]] = set()
            code_days_map[r[0]].add(r[2])
            if not r[3]:
                if r[0] not in f_code_days_map:
                    f_code_days_map[r[0]] = set()
                f_code_days_map[r[0]].add(r[2])
        # 过滤涨停次数>=3次的数据
        target_codes = set()
        for code in code_days_map:
            if f_code_days_map.get(code) and (len(f_code_days_map.get(code)) >= 4 or (
                    tool.is_ge_code(code) and len(f_code_days_map.get(code)) >= 2)):
                # 且有3天属于连续涨停
                day_list = list(code_days_map[code])
                day_list.sort(reverse=True)
                step = 3
                has_continue = False
                for i in range(0, len(day_list) - step + 1):
                    item_list = day_list[i:i + step]
                    # 是否属于连续涨停
                    is_sub = False
                    for j in range(0, len(dates) - step):
                        if f"{dates[j:j + step]}" == f"{item_list}":
                            is_sub = True
                            break
                    if is_sub:
                        has_continue = True
                        break
                if not has_continue:
                    continue
                has_big_deal = False
                # 最近10个交易日的成交额要大于10亿
                volumes_data = HistoryKDataManager().get_history_bars(code, dates[0])
                if volumes_data:
                    for d in volumes_data[:10]:
                        if d["amount"] > 10e8:
                            has_big_deal = True
                            break
                if not has_big_deal:
                    continue
                target_codes.add(code)
        # 代码对应的板块
        code_blocks = {}
        for r in results:
            if r[0] not in target_codes:
                continue
            if r[0] not in code_blocks:
                code_blocks[r[0]] = set()
            code_blocks[r[0]].add(kpl_util.filter_block(r[1]))
        # 所有板块对应的代码集合
        block_codes = {}
        for code in code_blocks:
            for b in code_blocks[code]:
                if b in constant.KPL_INVALID_BLOCKS:
                    continue
                if b not in block_codes:
                    block_codes[b] = set()
                block_codes[b].add(code)
        print(block_codes)
        cls.__watch_block_high_codes = block_codes
        logger_kpl_latest_gaobiao.info(f"{block_codes}")
        cls.__watch_high_codes.clear()
        for b in block_codes:
            cls.__watch_high_codes |= block_codes[b]
        for k in block_codes:
            print(k, [(x, gpcode_manager.get_code_name(x)) for x in block_codes[k]])
    def get_watch_high_codes(self):
        return self.__watch_high_codes
    def get_watch_high_codes_by_block(self, b):
        return self.__watch_block_high_codes.get(b)
    def compute(self, code_rate_dict: dict):
        """
        根据比例计算需要拉黑的代码
        @param code_rate_dict: 涨幅百分数
        @return:
        """
        try:
            if self.__watch_block_high_codes:
                forbidden_blocks = set()
                for b in self.__watch_block_high_codes:
                    total_rate = 0
                    for code in self.__watch_block_high_codes[b]:
                        if code in code_rate_dict:
                            total_rate += code_rate_dict.get(code)
                    average_rate = total_rate / len(self.__watch_block_high_codes[b])
                    if average_rate < 1:
                        forbidden_blocks.add(b)
                    # async_log_util.info(logger_debug, f"板块平均涨幅 {b}-{average_rate}")
                self.__kpl_forbidden_plates_cache = forbidden_blocks
                async_log_util.info(logger_debug, f"拉黑板块:{forbidden_blocks}")
        except Exception as e:
            logger_debug.exception(e)
class LimitUpCodesPlateKeyManager:
@@ -479,6 +621,12 @@
        @return:
        """
        cls.__market_strong = strong
    @classmethod
    def is_ignore_block_in_money(cls):
        if cls.__market_strong and cls.__market_strong >= constant.IGNORE_BLOCK_IN_MONEY_MARKET_STRONG:
            return True
        return False
    @classmethod
    def get_market_strong(cls):
@@ -1211,5 +1359,4 @@
if __name__ == "__main__":
    RealTimeKplMarketData.set_market_strong(120)
    print(RealTimeKplMarketData.get_jingxuan_in_block_threshold_count())
    KPLPlateForbiddenManager().compute()