admin
2025-04-21 ebd3c4ec85d6bf1d429d4d0e428933958002b640
总手涨跌分布数据分析
1个文件已修改
97 ■■■■■ 已修改文件
strategy/market_sentiment_analysis.py 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/market_sentiment_analysis.py
@@ -411,40 +411,53 @@
# 计算市场分布形态因子 函数
# ====================== 输入数据 ======================
data = {'-1': '1382', '-10': '3', '-2': '278', '-3': '105', '-4': '41', '-5': '18', '-6': '8', '-7': '4', '-8': '5', '-9': '1', '0': '350', '1': '2217', '10': '6', '2': '487', '3': '109', '4': '48', '5': '22', '6': '10', '7': '8', '8': '5', '9': '1', 'DT': 6, 'SJDT': '3', 'SJZT': '14', 'STDT': '3', 'STZT': '2', 'SZJS': 2929, 'XDJS': 1851, 'ZSZDFB': '1189,885,159,212,257,31,136,125,31,22,27,1,5,43,2,66,224,10,', 'ZT': 16, 'sign': '市场人气一般', 'szln': 3571292, 'qscln': 8377352, 's_zrcs': 4219994, 'q_zrcs': 9969991, 's_zrtj': 48920069, 'q_zrtj': 111190413}
data = {'-1': '2676', '-10': '4', '-2': '769', '-3': '181', '-4': '59', '-5': '43', '-6': '18', '-7': '11', '-8': '5', '-9': '4', '0': '219', '1': '714', '10': '6', '2': '214', '3': '69', '4': '45', '5': '23', '6': '9', '7': '9', '8': '7', '9': '6', 'DT': 17, 'SJDT': '8', 'SJZT': '17', 'STDT': '9', 'STZT': '4', 'SZJS': 1123, 'XDJS': 3787, 'ZSZDFB': '480,1639,112,123,351,26,76,202,15,17,32,1,15,30,5,78,204,18,', 'ZT': 21, 'sign': '市场人气一般', 'szln': 2591290, 'qscln': 6629612, 's_zrcs': 2604433, 'q_zrcs': 6660830, 's_zrtj': 38031347, 'q_zrtj': 91465597}
# ====================== 数据预处理 ======================
# 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 parse_zszdfb(zszdfb_str):
    """
    解析ZSZDFB数据为易读的字典格式
    参数:
        zszdfb_str: ZSZDFB原始字符串(如'1929,247,56,...')
    返回:
        {
            "区间分布": [
                {"区间": "[-10%, -9%)", "成交量(手)": 1929},
                {"区间": "[-9%, -8%)", "成交量(手)": 247},
                ...
            ],
            "总成交量(手)": int,
            "说明": "本数据包含从-10%到+8%的成交量分布,共18个1%间隔区间"
        }
    """
    # 1. 清洗并转换原始数据为整数列表
    counts = [int(x) for x in zszdfb_str.strip(',').split(',') if x]
    # 2. 定义区间划分(假设从-10%到+8%,1%间隔)
    bins = [
        "[-10%, -9%)", "[-9%, -8%)", "[-8%, -7%)", "[-7%, -6%)", "[-6%, -5%)",
        "[-5%, -4%)", "[-4%, -3%)", "[-3%, -2%)", "[-2%, -1%)", "[-1%, 0%)",
        "[0%, 1%)", "[1%, 2%)", "[2%, 3%)", "[3%, 4%)", "[4%, 5%)",
        "[5%, 6%)", "[6%, 7%)", "[7%, 8%)"
    ]
# data = preprocess_data(raw_data)
    # 3. 验证数据长度
    if len(counts) != len(bins):
        raise ValueError(f"数据长度不匹配!预期{len(bins)}个区间,实际{len(counts)}个值")
    # 4. 构建结构化输出
    result = {
        "区间分布": [
            {"区间": bin_name, "成交量(手)": count}
            for bin_name, count in zip(bins, counts)
        ],
        "总成交量(手)": sum(counts),
        "说明": "本数据包含从-10%到+8%的成交量分布,共18个1%间隔区间"
    }
    return result
# ====================== 核心因子计算 ======================
def calculate_factors(data):
@@ -492,6 +505,9 @@
        q_zrcs = int(data.get('q_zrcs'))  # - q_zrcs(买方昨日持仓数):买方在昨日的持仓数量
        s_zrtj = int(data.get('s_zrtj'))  # - s_zrtj(卖方资金今日统计):卖方当日的资金流出量
        q_zrtj = int(data.get('q_zrtj'))  # - q_zrtj(买方资金今日统计):买方当日的资金流入量
        # 执行总手涨跌分布解析
        parsed_data = parse_zszdfb(ZSZDFB)
        """计算市场关键指标因子"""
        factors = {}
@@ -566,7 +582,8 @@
            'fall_percentages': fall_percentages,  # 跌幅段的股票分布比例
            'rise_and_fall_sum': rise_and_fall_sum,
            'rise_max_key': rise_max_key,
            'fall_max_key': fall_max_key
            'fall_max_key': fall_max_key,
            'parsed_data': parsed_data
        }
        # 按值排序并提取前三个键值对
        sorted_items = sorted(factors['rise_vs_fall']['percentages'].items(), key=lambda item: item[1], reverse=True)
@@ -685,7 +702,7 @@
                        logger.info(f"涨跌统计字典{data_cache.rise_and_fall_statistics_dirt}")
                        logger.info(f"涨跌统计因子的计算={factors}")
                        logger.info(f"涨跌统计生成信号={signals}")
                        logger.info("========== 关键指标 ==========")
                        logger.info("========== 关键涨跌统计数据 ==========")
                        logger.info(f"总股票数: {factors['total_stocks']}\n"
                                    f"涨跌比(BDR): {factors['rise_vs_fall']['rise_vs_fall_ratio']:.2f}\n"
                                    f"极端波动比例: {factors['sentiment']['extreme_ratio']:.2%}\n"
@@ -697,6 +714,12 @@
                                    f"聚集区域:{factors['rise_vs_fall']['gather_area']},聚集区域的比例值:{factors['rise_vs_fall']['percentages'].get(factors['rise_vs_fall']['gather_area'])}%\n"
                                    f"零散区域:{factors['rise_vs_fall']['scattered_area']},聚集区域的比例值:{factors['rise_vs_fall']['percentages'].get(factors['rise_vs_fall']['scattered_area'])}%\n"
                                    f"涨跌因子字典={factors['rise_vs_fall']}\n")
                        logger.info("\n========== 总手涨跌分布 ==========")
                        # 打印结果(美化输出)
                        for item in factors['rise_vs_fall']['parsed_data']["区间分布"]:
                            logger.info(f"{item['区间']}: {item['成交量(手)']}手")
                        logger.info(f"\n总成交量: {factors['rise_vs_fall']['parsed_data']['总成交量(手)']}手")
                        logger.info(f"\n说明: {factors['rise_vs_fall']['parsed_data']['说明']}")
                        logger.info("\n========== 策略信号 ==========")
                        for i, signal in enumerate(signals, 1):
                            logger.info(f"信号{i}: {signal}")
@@ -704,10 +727,11 @@
                    # 理想交易行情分数【评估当前行情是否有利于低吸策略取得更高抓板率的分数(是否是理想的交易行情)】
                    ideal_trading_market_score = 1
                    # 33分是个两级分化阶梯不好,目前不好拿捏,暂时不用
                    # if data_cache.real_time_market_strong <= 33:
                    if data_cache.real_time_market_strong < 30:
                    # if data_cache.real_time_market_strong <= 33:   实际跌停大于10个
                    if data_cache.real_time_market_strong < 30 and actual_limit_down_numbers > 10:
                        # 如果大盘综合强度分数小于30,将低迷情绪分数比例设置为0.01,可用资金缩小一百倍
                        ideal_trading_market_score = 0.01
                    logger.info(f"理想交易行情分数===={ideal_trading_market_score * 100}%")
                    data_cache.index_trend_expectation_score = index_trend_expectation()
@@ -794,3 +818,10 @@
    print("\n========== 策略信号 ==========")
    for i, signal in enumerate(signals, 1):
        print(f"信号{i}: {signal}")
    print("\n========== 总手涨跌分布 ==========")
    # 打印结果(美化输出)
    for item in factors['rise_vs_fall']['parsed_data']["区间分布"]:
        print(f"{item['区间']}: {item['成交量(手)']}手")
    print(f"\n总成交量: {factors['rise_vs_fall']['parsed_data']['总成交量(手)']}手")
    print(f"说明: {factors['rise_vs_fall']['parsed_data']['说明']}")