1.修改买入策略中空数据BUG
2.涨跌统计因子实时计算结果打印
3.板块强度数据打印时间至收盘
4个文件已修改
140 ■■■■ 已修改文件
main.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/buying_strategy.py 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/market_sentiment_analysis.py 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/plate_strength_analysis.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py
@@ -119,7 +119,8 @@
    def get_market_sift_plate_its_stock_power_process(market_sift_plate_stock_dict):
        # print(f"回调成功===精选板块股票强度数据更新==={market_sift_plate_stock_dict}")
        # logger_kpl_jingxuan_in.info(f"{market_sift_plate_stock_dict}")
        data_cache.market_sift_plate_stock_dict = market_sift_plate_stock_dict
        if market_sift_plate_stock_dict:
            data_cache.market_sift_plate_stock_dict = market_sift_plate_stock_dict
    # 板块强度下个股强度线程
    threading.Thread(target=plate_strength_analysis.get_market_sift_plate_its_stock_power_process,
strategy/buying_strategy.py
@@ -207,25 +207,26 @@
                strength_list_have_it = False  # 为查询结果赋初值
                strength_plate = []
                market_sift_plate_stock_dict = data_cache.market_sift_plate_stock_dict
                # 遍历字典的每个键值对
                for key, values in market_sift_plate_stock_dict.items():
                    # 遍历每个键对应的列表中的列表
                    for stock_list in values:
                        if len(stock_list) > 1 and symbol_code in stock_list[1]:
                            async_log_util.info(logger,
                                                f"在板块强度个股列表中找到了 {key}:{k_line_data[0]['sec_name']}。")
                            # 打印概念对应的个股列表
                            # print(f"stock_list=={stock_list}")
                            # 将个股精选的相关两个概念字符串转化为列表
                            correlation_plate_list = stock_list[4].split('、')
                            async_log_util.info(logger,
                                                f"【{stock_list[0]}】,当日当时涨幅:{stock_list[2]}%,当时涨速:{stock_list[3]},个股精选相关板块=={correlation_plate_list} ,领涨次数:{stock_list[6]}")
                            # 如果只需要找到一个就停止,可以在这里使用 break
                            if len(values) >= 2:
                                async_log_util.info(logger, f"单一板块内瞬时拉升数为:{len(values)},分别为===={values}")
                                # 如果子列表长度大于1且第二个元素包含 当前进入涨幅视界的symbol_code
                                strength_list_have_it = True
                                strength_plate = correlation_plate_list
                if market_sift_plate_stock_dict is not None:
                    # 遍历字典的每个键值对
                    for key, values in market_sift_plate_stock_dict.items():
                        # 遍历每个键对应的列表中的列表
                        for stock_list in values:
                            if len(stock_list) > 1 and symbol_code in stock_list[1]:
                                async_log_util.info(logger,
                                                    f"在板块强度个股列表中找到了 {key}:{k_line_data[0]['sec_name']}。")
                                # 打印概念对应的个股列表
                                # print(f"stock_list=={stock_list}")
                                # 将个股精选的相关两个概念字符串转化为列表
                                correlation_plate_list = stock_list[4].split('、')
                                async_log_util.info(logger,
                                                    f"【{stock_list[0]}】,当日当时涨幅:{stock_list[2]}%,当时涨速:{stock_list[3]},个股精选相关板块=={correlation_plate_list} ,领涨次数:{stock_list[6]}")
                                # 如果只需要找到一个就停止,可以在这里使用 break
                                if len(values) >= 2:
                                    async_log_util.info(logger, f"单一板块内瞬时拉升数为:{len(values)},分别为===={values}")
                                    # 如果子列表长度大于1且第二个元素包含 当前进入涨幅视界的symbol_code
                                    strength_list_have_it = True
                                    strength_plate = correlation_plate_list
                '''
                初始化K线近期显著指标的序号 并找出来,如果没有,则返回空值
                '''
strategy/market_sentiment_analysis.py
@@ -420,32 +420,32 @@
# ====================== 数据预处理 ======================
def preprocess_data(data):
    """
    预处理原始数据:
    1. 转换所有数值字段为整数
    2. 解析涨跌分布(ZSZDFB)为整数列表
    3. 分离涨跌幅分布数据
    """
    processed = {}
    # 通用字段类型转换
    for key, value in data.items():
        if isinstance(value, str) and value.isdigit():  # 处理字符串数字
            processed[key] = int(value)
        elif key == 'ZSZDFB':  # 特殊处理涨跌分布
            # 过滤空值并转换为整数列表
            processed[key] = [int(x) for x in value.strip(',').split(',')]
        else:
            processed[key] = value  # 保留原始类型
    # 分离涨跌幅分布数据(示例划分,具体区间需确认)
    # 假设ZSZDFB对应从-10%到10%的18个区间分布(根据数据长度推测)
    processed['price_distribution'] = {
        'bins': list(range(-10, 11)),  # 生成-10到10的整数区间标识
        'counts': processed['ZSZDFB']
    }
    return processed
# def preprocess_data(data):
#     """
#     预处理原始数据:
#     1. 转换所有数值字段为整数
#     2. 解析涨跌分布(ZSZDFB)为整数列表
#     3. 分离涨跌幅分布数据
#     """
#     processed = {}
#
#     # 通用字段类型转换
#     for key, value in data.items():
#         if isinstance(value, str) and value.isdigit():  # 处理字符串数字
#             processed[key] = int(value)
#         elif key == 'ZSZDFB':  # 特殊处理涨跌分布
#             # 过滤空值并转换为整数列表
#             processed[key] = [int(x) for x in value.strip(',').split(',')]
#         else:
#             processed[key] = value  # 保留原始类型
#
#     # 分离涨跌幅分布数据(示例划分,具体区间需确认)
#     # 假设ZSZDFB对应从-10%到10%的18个区间分布(根据数据长度推测)
#     processed['price_distribution'] = {
#         'bins': list(range(-10, 11)),  # 生成-10到10的整数区间标识
#         'counts': processed['ZSZDFB']
#     }
#     return processed
# data = preprocess_data(raw_data)
@@ -625,6 +625,10 @@
                    connecting_board_height = data_cache.real_time_market_sentiment_dirt.get('lbgd', None)  # 连板高度
                    # 获取市场情绪-涨跌统计
                    data_cache.rise_and_fall_statistics_dirt = kpl_api.getMarketFelling()  # 涨跌统计字典
                    # 涨跌统计因子计算
                    factors = calculate_factors(data_cache.rise_and_fall_statistics_dirt)
                    # 涨跌统计生成信号
                    signals = generate_signals(factors)
                    limit_up_numbers = data_cache.rise_and_fall_statistics_dirt.get('ZT', None)  # 涨停家数
                    actual_limit_up_numbers = data_cache.rise_and_fall_statistics_dirt.get('SJZT', None)  # 实际涨停家数
                    ST_limit_up_numbers = data_cache.rise_and_fall_statistics_dirt.get('STZT', None)  # ST涨停家数
@@ -648,17 +652,18 @@
                        logger.info(
                            f"上涨家数:{rise_numbers},下跌家数:{fall_numbers},实际涨停家数:{actual_limit_up_numbers},实际跌停家数:{actual_limit_down_numbers}")
                        logger.info(f"涨跌统计字典{data_cache.rise_and_fall_statistics_dirt}")
                        logger.info(f"涨跌统计因子的计算={factors}")
                    # 低迷情绪比例
                    low_emotion_mood_ratio = 1
                    # 理想交易行情分数【评估当前行情是否有利于低吸策略取得更高抓板率的分数(是否是理想的交易行情)】
                    ideal_trading_market_score = 1
                    # 33分是个两级分化阶梯不好,目前不好拿捏,暂时不用
                    # if data_cache.real_time_market_strong <= 33:
                    if data_cache.real_time_market_strong < 30:
                        # 如果大盘综合强度分数小于30,将低迷情绪分数比例设置为0.01,可用资金缩小一百倍
                        low_emotion_mood_ratio = 0.01
                        ideal_trading_market_score = 0.01
                        if data_cache.real_time_market_strong <= 10:
                            low_emotion_mood_ratio = 0
                    logger.info(f"极端低迷情绪比例===={low_emotion_mood_ratio * 100}%")
                            ideal_trading_market_score = 0
                    logger.info(f"理想交易行情分数===={ideal_trading_market_score * 100}%")
                    data_cache.index_trend_expectation_score = index_trend_expectation()
                    logger.info(f"大盘指数情绪预期分数==={data_cache.index_trend_expectation_score}分")
@@ -668,26 +673,27 @@
                    # 获取计算今天新增的持仓数量
                    addition_position_number = len(data_cache.addition_position_symbols_set)
                    # 定义一个今日的剩余新增持仓数量的变量
                    # 定义一个今日的剩余新增持仓数量的变量 【目前策略默认一日三仓 所以设置常量3】
                    Unfinished_opening_plan_number = 3 - addition_position_number
                    logger.info(f"今日的剩余新增持仓数量==={Unfinished_opening_plan_number}")
                    usefulMoney = data_cache.account_finance_dict[0].get('usefulMoney', 0)
                    logger.info(f"账户可用资金==={usefulMoney}元")
                    if Unfinished_opening_plan_number != 0:
                        # 如果GUI看盘上没有手动设置具体的下单金额,就按照评分策略的金额下单,否则就按照GUI设置的金额下单。
                        if data_cache.BUY_MONEY_PER_CODE < 0:
                            # 根据账户可用金额 计算今日计划下单金额
                            # 账户可用金额 默认乘以0.9,永远留一点钱,一方面也冗余一些计算误差
                            #  ((大盘综合强度分数 + 大盘指数情绪预期分数) * 0.01) * (账户可用金额 * 0.9 * 极端低迷情绪比例 / 今日最大新增持仓票数)
                            # data_cache.today_planned_order_amount = ((data_cache.real_time_market_strong + data_cache.index_trend_expectation_score) * 0.01) * (
                            #                                                 usefulMoney * 0.9 * low_emotion_mood_ratio / Unfinished_opening_plan_number)
                            data_cache.today_planned_order_amount = usefulMoney * 0.95 * low_emotion_mood_ratio / Unfinished_opening_plan_number
                            logger.info(
                                f"采用开仓策略计算方式=》今日计划下单金额:{data_cache.today_planned_order_amount},")
                        else:
                    # 如果一日三仓的计划还未完成 且 未设置过开仓计划金额
                    if Unfinished_opening_plan_number != 0 and data_cache.today_planned_order_amount <= 0:
                        # 如果GUI看盘手动设置了具体的下单金额【ata_cache.BUY_MONEY_PER_CODE 中默认值为-1,只有当GUI看盘手动设置了并提交才会>=0】,就按照GUI设置的金额下单。否则就按照评分策略的金额下单,
                        if data_cache.BUY_MONEY_PER_CODE >= 0:
                            data_cache.today_planned_order_amount = data_cache.BUY_MONEY_PER_CODE
                            logger.info(f"采用GUI设置方式=》今日计划下单金额:{data_cache.today_planned_order_amount}")
                        else:
                            # 如果今日还没有一个新增仓位,就不停计算更新计划金额
                            if addition_position_number <= 0:
                                # 根据账户可用金额 计算今日计划下单金额
                                # 账户可用金额 默认乘以0.95,永远留一点钱,一方面也冗余一些计算误差
                                #  ((大盘综合强度分数 + 大盘指数情绪预期分数) * 0.01) * (账户可用金额 * 0.9 * 极端低迷情绪比例 / 今日最大新增持仓票数)
                                # data_cache.today_planned_order_amount = ((data_cache.real_time_market_strong + data_cache.index_trend_expectation_score) * 0.01) * (
                                #                                                 usefulMoney * 0.9 * low_emotion_mood_ratio / Unfinished_opening_plan_number)
                                data_cache.today_planned_order_amount = usefulMoney * 0.95 * ideal_trading_market_score / Unfinished_opening_plan_number
                                logger.info(f"采用开仓策略计算方式=》今日计划下单金额:{data_cache.today_planned_order_amount}")
        except Exception as error:
            logger_debug.exception(error)
            logger.error(f"实时设置计划持仓数量 函数报错: {error}")
strategy/plate_strength_analysis.py
@@ -71,7 +71,7 @@
        return log_data
    # 定义一个时间段,在这个时间段内才会执行下面的代码,主要就是把强度数据作为日志打印存储下来。
    now_time = tool.get_now_time_str()
    if not (data_cache.OPENING_TIME < now_time < data_cache.NOON_MARKET_TIME):
    if not (data_cache.OPENING_TIME < now_time < data_cache.CLOSING_TIME):
        return
    data = (kpl_api.getMarketJingXuanRealRankingInfo())