#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ KLU与KLC分型强度算法一致性测试 验证两种算法在相同数据下是否产生一致的结果 """ from ChanKLU import ChanKLU from ChanKLC import ChanKLC from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR import pandas as pd from datetime import datetime, timedelta def create_test_data(): """创建测试用的K线数据""" test_cases = [ # 测试用例1:标准顶分型 { 'name': '标准顶分型', 'data': [ {'open': 100, 'high': 102, 'low': 99, 'close': 101, 'volume': 1000}, # K1 {'open': 101, 'high': 105, 'low': 100, 'close': 103, 'volume': 1500}, # K2 (顶分型中心) {'open': 103, 'high': 104, 'low': 98, 'close': 99, 'volume': 1200}, # K3 ] }, # 测试用例2:标准底分型 { 'name': '标准底分型', 'data': [ {'open': 100, 'high': 102, 'low': 99, 'close': 101, 'volume': 1000}, # K1 {'open': 101, 'high': 103, 'low': 95, 'close': 97, 'volume': 1500}, # K2 (底分型中心) {'open': 97, 'high': 104, 'low': 96, 'close': 102, 'volume': 1200}, # K3 ] }, # 测试用例3:强势顶分型(放量+下影线) { 'name': '强势顶分型', 'data': [ {'open': 100, 'high': 102, 'low': 99, 'close': 101, 'volume': 1000}, # K1 {'open': 101, 'high': 108, 'low': 100, 'close': 102, 'volume': 2500}, # K2 (强顶分型) {'open': 102, 'high': 103, 'low': 95, 'close': 96, 'volume': 1800}, # K3 (大阴线确认) ] } ] return test_cases def setup_klu_chain(data_list): """设置KLU链""" klus = [] base_time = datetime.now() for i, data in enumerate(data_list): time_str = (base_time + timedelta(minutes=i)).strftime("%Y-%m-%d %H:%M:%S") klu = ChanKLU(time_str, data['open'], data['high'], data['low'], data['close'], data['volume']) klu.set_idx(i) # 设置基础技术指标 indicators = { 'ma5': data['close'] + (i-1) * 0.1, 'ma10': data['close'] + (i-1) * 0.05, 'rsi': 50 + (i % 3 - 1) * 15, 'macd': (i % 3 - 1) * 0.01, 'macdhist': (i % 2) * 0.005, 'volume_ratio': 1.0 + (i % 2) * 0.3 } klu.set_indicators(indicators) klus.append(klu) # 建立前后关系 for i in range(len(klus)): if i > 0: klus[i].set_pre(klus[i-1]) if i < len(klus) - 1: klus[i].set_next(klus[i+1]) return klus def setup_klc_chain(data_list): """设置KLC链(基于KLU)""" klus = setup_klu_chain(data_list) klcs = [] # 为简化测试,假设每个KLU对应一个KLC(无包含关系处理) for i, klu in enumerate(klus): klc = ChanKLC(klu, i, Chan_KLINE_DIR.UP) klc.set_end_klu(klu) klcs.append(klc) # 建立前后关系 for i in range(len(klcs)): if i > 0: klcs[i].set_pre(klcs[i-1]) if i < len(klcs) - 1: klcs[i].set_next(klcs[i+1]) # 设置分型类型 if len(klcs) >= 3: middle_klc = klcs[1] if (middle_klc.high > klcs[0].high and middle_klc.high > klcs[2].high): middle_klc.set_fx(Chan_FX_TYPE.TOP) elif (middle_klc.low < klcs[0].low and middle_klc.low < klcs[2].low): middle_klc.set_fx(Chan_FX_TYPE.BOTTOM) return klcs def compare_algorithms(test_cases): """对比KLU和KLC算法""" print("=" * 80) print("KLU与KLC分型强度算法一致性测试") print("=" * 80) for case in test_cases: print(f"\n🔍 测试用例: {case['name']}") print("-" * 50) # 准备数据 klus = setup_klu_chain(case['data']) klcs = setup_klc_chain(case['data']) if len(klus) >= 3 and len(klcs) >= 3: middle_klu = klus[1] middle_klc = klcs[1] # KLU分析 middle_klu.update_realtime_analysis() klu_fx_type = middle_klu.fx_type klu_strength = middle_klu.fx_strength klu_confirmed = middle_klu.fx_confirmed # KLC分析 klc_fx_type = middle_klc.fx klc_strength_raw = middle_klc.cal_fx_strength() # -3到3 klc_strength_converted = int((klc_strength_raw + 3) * 100 / 6) # 转换为0-100 # 输出对比结果 print(f"K线数据: {case['data'][1]}") print(f"\nKLU算法结果:") print(f" 分型类型: {klu_fx_type}") print(f" 分型强度: {klu_strength}") print(f" 是否确认: {klu_confirmed}") print(f"\nKLC算法结果:") print(f" 分型类型: {klc_fx_type}") print(f" 分型强度(原始): {klc_strength_raw}") print(f" 分型强度(转换): {klc_strength_converted}") # 一致性检查 type_consistent = (klu_fx_type == klc_fx_type) strength_diff = abs(klu_strength - klc_strength_converted) strength_consistent = strength_diff <= 10 # 允许10分以内的差异 print(f"\n一致性检查:") print(f" 分型类型一致: {'✅' if type_consistent else '❌'}") print(f" 强度差异: {strength_diff}分 {'✅' if strength_consistent else '❌'}") if not type_consistent or not strength_consistent: print(f" ⚠️ 算法结果不一致!") else: print(f" ✅ 算法结果一致") else: print("❌ 数据不足,无法进行对比") def detailed_strength_analysis(): """详细的强度分析对比""" print("\n" + "=" * 80) print("详细强度分析对比") print("=" * 80) # 创建一个明确的强分型案例 strong_top_data = [ {'open': 100, 'high': 101, 'low': 99, 'close': 100, 'volume': 1000}, {'open': 100, 'high': 110, 'low': 99, 'close': 102, 'volume': 3000}, # 强顶分型 {'open': 102, 'high': 103, 'low': 92, 'close': 93, 'volume': 2000}, # 强确认 {'open': 93, 'high': 94, 'low': 90, 'close': 91, 'volume': 1500}, # 继续下跌 {'open': 91, 'high': 92, 'low': 88, 'close': 89, 'volume': 1200}, # 进一步确认 ] klus = setup_klu_chain(strong_top_data) if len(klus) >= 5: target_klu = klus[1] # 目标分型K线 print(f"分析目标: 第2根K线 (索引1)") print(f"K线数据: {strong_top_data[1]}") # 更新分析 target_klu.update_realtime_analysis() print(f"\n分型检测结果:") print(f" 分型类型: {target_klu.fx_type}") print(f" 分型确认: {target_klu.fx_confirmed}") print(f" 最终强度: {target_klu.fx_strength}") # 显示中间计算过程(需要重新调用以获取详细信息) if target_klu.fx_confirmed: print(f"\n强度计算过程:") is_bi_end = target_klu._check_if_bi_ending_fx() post_confirmation = target_klu._check_post_fx_confirmation() fx_quality = target_klu._check_fx_quality() print(f" 笔终结判断: {is_bi_end}") print(f" 后续确认: {post_confirmation}") print(f" 分型质量: {fx_quality}") raw_score = is_bi_end + post_confirmation + fx_quality final_raw = max(-3, min(3, raw_score)) converted_score = int((final_raw + 3) * 100 / 6) print(f" 原始总分: {raw_score} -> {final_raw}") print(f" 转换分数: {converted_score}") if __name__ == "__main__": # 运行测试 test_cases = create_test_data() compare_algorithms(test_cases) # 详细分析 detailed_strength_analysis() print("\n" + "=" * 80) print("测试完成!") print("=" * 80)