| | |
| | | |
| | | # 计算市场分布形态因子 函数 |
| | | # ====================== 输入数据 ====================== |
| | | 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): |
| | |
| | | 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 = {} |
| | |
| | | '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) |
| | |
| | | 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" |
| | |
| | | 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}") |
| | |
| | | # 理想交易行情分数【评估当前行情是否有利于低吸策略取得更高抓板率的分数(是否是理想的交易行情)】 |
| | | 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() |
| | |
| | | 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']['说明']}") |