add fx strentth

This commit is contained in:
jackyu66git
2025-05-23 21:19:50 +08:00
parent a1e033432b
commit a9d24233b0
14 changed files with 2067 additions and 399 deletions
+378 -1
View File
@@ -1130,4 +1130,381 @@ class ChanKLC():
else:
features['klc_star_pattern'] = 0
return features
# ===== 分型强度特征 =====
# 添加分型强度相关特征
features['klc_fx_strength'] = self.calculate_fx_strength()
features['klc_fx_strength_level'] = self.get_fx_strength_level()
features['klc_is_strong_fx'] = 1 if self.is_strong_fx() else 0
# 分型强度分类特征
fx_strength = features['klc_fx_strength']
features['klc_fx_strength_extreme'] = 1 if fx_strength >= 80 else 0 # 极强分型
features['klc_fx_strength_strong'] = 1 if 60 <= fx_strength < 80 else 0 # 强分型
features['klc_fx_strength_medium'] = 1 if 40 <= fx_strength < 60 else 0 # 中等分型
features['klc_fx_strength_weak'] = 1 if 20 <= fx_strength < 40 else 0 # 弱分型
features['klc_fx_strength_very_weak'] = 1 if fx_strength < 20 else 0 # 极弱分型
return features
def calculate_fx_strength(self):
"""
基于专业缠论理论的分型强度评估体系
返回值:0-100的强度分数,数值越大表示分型越强
评分卡系统(总分29分,转换为100分制):
- 振幅比例:25%权重,最高5分
- 量能配合:20%权重,最高5分
- 均线位置:15%权重,最高5分
- 形成速度:10%权重,最高4分
- 次级别确认:30%权重,最高10分
"""
if self.fx == Chan_FX_TYPE.UNKNOWN or not self.pre or not self.next:
return 0
# ===== 一、基础要素确认(先决条件) =====
if not self._verify_basic_fx_structure():
return 0
total_score = 0
max_score = 29 # 5+5+5+4+10
# ===== 二、振幅比例评估 (25%权重,最高5分) =====
amplitude_score = self._calculate_amplitude_score()
total_score += amplitude_score
# ===== 三、量能配合评估 (20%权重,最高5分) =====
volume_score = self._calculate_volume_score()
total_score += volume_score
# ===== 四、均线位置评估 (15%权重,最高5分) =====
ma_score = self._calculate_ma_position_score()
total_score += ma_score
# ===== 五、形成速度评估 (10%权重,最高4分) =====
speed_score = self._calculate_formation_speed_score()
total_score += speed_score
# ===== 六、次级别确认评估 (30%权重,最高10分) =====
confirmation_score = self._calculate_confirmation_score()
total_score += confirmation_score
# 转换为100分制
final_score = (total_score / max_score) * 100
return round(final_score, 2)
def _verify_basic_fx_structure(self):
"""
验证基础分型要素(先决条件)
只验证最核心的分型定义,避免过度严格
"""
if not self.pre or not self.next:
return False
if self.fx == Chan_FX_TYPE.TOP:
# 顶分型核心要素:中间K线高点必须严格高于两侧
if not (self.high > self.pre.high and self.high > self.next.high):
return False
elif self.fx == Chan_FX_TYPE.BOTTOM:
# 底分型核心要素:中间K线低点必须严格低于两侧
if not (self.low < self.pre.low and self.low < self.next.low):
return False
return True
def _calculate_amplitude_score(self):
"""
计算振幅比例得分 (最高5分)
强势分型:分型区间振幅>近期平均振幅的150% = 5分
标准分型:介于80%-150%之间 = 3分
弱势分型:<80% = 1分
"""
score = 0
# 计算分型区间振幅
if self.fx == Chan_FX_TYPE.TOP:
fx_amplitude = self.high - min(self.pre.low, self.next.low)
# 加分项:右侧K线低点低于左侧K线低点(经典缠论强势特征)
if self.next.low < self.pre.low:
score += 1
else: # BOTTOM
fx_amplitude = max(self.pre.high, self.next.high) - self.low
# 加分项:右侧K线高点高于左侧K线高点(经典缠论强势特征)
if self.next.high > self.pre.high:
score += 1
# 计算近期平均振幅(前10根K线的ATR)
avg_amplitude = self._calculate_recent_atr(lookback=10)
if avg_amplitude <= 0:
return max(1, score) # 确保至少有基础分
amplitude_ratio = fx_amplitude / avg_amplitude
if amplitude_ratio >= 1.5: # >150%
score += 4 # 基础4分 + 可能的经典形态1分 = 最高5分
elif amplitude_ratio >= 1.0: # 100%-150%
score += 2 + int((amplitude_ratio - 1.0) * 4) # 2-4分线性插值
elif amplitude_ratio >= 0.8: # 80%-100%
score += 1 + int((amplitude_ratio - 0.8) * 5) # 1-2分线性插值
else: # <80%
score += 1
return min(5, score)
def _calculate_volume_score(self):
"""
计算量能配合得分 (最高5分)
顶分型:第二根K线放量滞涨为强烈信号
底分型:第三根K线放量回升为有效确认
"""
# 计算前5根K线平均成交量
avg_volume = self._calculate_average_volume(lookback=5)
if avg_volume <= 0:
return 1
if self.fx == Chan_FX_TYPE.TOP:
# 顶分型:检查第二根K线(当前)是否放量滞涨
volume_ratio = self.volume / avg_volume
# 判断是否滞涨:收盘价位于K线下半部分
price_position = (self.close - self.low) / (self.high - self.low) if self.high > self.low else 0.5
if volume_ratio >= 2.0 and price_position <= 0.4: # 放量+滞涨
return 5
elif volume_ratio >= 1.5 and price_position <= 0.5:
return 4
elif volume_ratio >= 1.2:
return 3
else:
return 1
else: # BOTTOM
# 底分型:检查第三根K线是否放量回升
next_volume_ratio = self.next.volume / avg_volume if hasattr(self.next, 'volume') else 1
# 判断是否回升:第三根K线收盘价相对位置较高
if self.next.high > self.next.low:
next_price_position = (self.next.close - self.next.low) / (self.next.high - self.next.low)
else:
next_price_position = 0.5
if next_volume_ratio >= 2.0 and next_price_position >= 0.6: # 放量+回升
return 5
elif next_volume_ratio >= 1.5 and next_price_position >= 0.5:
return 4
elif next_volume_ratio >= 1.2:
return 3
else:
return 1
def _calculate_ma_position_score(self):
"""
计算均线位置得分 (最高5分)
强势顶分型需在5/10均线乖离率>5%时出现
有效底分型常伴随MACD底背离
"""
score = 0
# 获取均线数据
klu_features = self.cal_klu_features()
if self.fx == Chan_FX_TYPE.TOP:
# 顶分型:检查与5日和10日均线的乖离率
ma5_bias = 0
ma10_bias = 0
if 'klu_ma5' in klu_features and klu_features['klu_ma5'] > 0:
ma5_bias = (self.close - klu_features['klu_ma5']) / klu_features['klu_ma5']
if 'klu_ma10' in klu_features and klu_features['klu_ma10'] > 0:
ma10_bias = (self.close - klu_features['klu_ma10']) / klu_features['klu_ma10']
# 乖离率>5%为强势信号
if ma5_bias > 0.05 or ma10_bias > 0.05:
score += 3
elif ma5_bias > 0.03 or ma10_bias > 0.03:
score += 2
elif ma5_bias > 0 or ma10_bias > 0:
score += 1
else: # BOTTOM
# 底分型:检查MACD背离和均线支撑
# 简化处理:检查价格是否在均线附近或下方
ma5_support = False
ma10_support = False
if 'klu_ma5' in klu_features and klu_features['klu_ma5'] > 0:
ma5_bias = (self.close - klu_features['klu_ma5']) / klu_features['klu_ma5']
if ma5_bias >= -0.05: # 在5日均线附近或上方
ma5_support = True
if 'klu_ma10' in klu_features and klu_features['klu_ma10'] > 0:
ma10_bias = (self.close - klu_features['klu_ma10']) / klu_features['klu_ma10']
if ma10_bias >= -0.05: # 在10日均线附近或上方
ma10_support = True
if ma5_support and ma10_support:
score += 3
elif ma5_support or ma10_support:
score += 2
else:
score += 1
# 检查MACD状态
if hasattr(self, 'macdhist'):
if self.fx == Chan_FX_TYPE.BOTTOM and self.macdhist > 0:
score += 2 # MACD金叉附近的底分型加分
elif self.fx == Chan_FX_TYPE.TOP and self.macdhist < 0:
score += 2 # MACD死叉附近的顶分型加分
return min(5, score)
def _calculate_formation_speed_score(self):
"""
计算形成速度得分 (最高4分)
强势特征:分型形成时间小于对应级别平均周期的1/3
弱势特征:形成时间超过平均周期2倍
"""
# 简化处理:基于分型K线的收敛程度
# 分型区间内的价格收敛速度越快,形成速度越快
if self.fx == Chan_FX_TYPE.TOP:
# 顶分型:检查左右两根K线相对于中间K线的收敛程度
left_convergence = (self.high - self.pre.high) / self.high if self.high > 0 else 0
right_convergence = (self.high - self.next.high) / self.high if self.high > 0 else 0
else: # BOTTOM
left_convergence = (self.pre.low - self.low) / self.low if self.low > 0 else 0
right_convergence = (self.next.low - self.low) / self.low if self.low > 0 else 0
avg_convergence = (left_convergence + right_convergence) / 2
if avg_convergence >= 0.03: # 快速形成
return 4
elif avg_convergence >= 0.02:
return 3
elif avg_convergence >= 0.01:
return 2
else:
return 1
def _calculate_confirmation_score(self):
"""
计算次级别确认得分 (最高10分)
- 笔破坏检测:真实强势分型会破坏前一笔的趋势
- 观察分型后3根K线能否站稳分型区间1/2以上
- 结合技术指标确认
"""
score = 0
# 1. 检查分型后确认(如果有next的next数据)
if hasattr(self.next, 'next'):
next2 = self.next.next
if next2:
if self.fx == Chan_FX_TYPE.TOP:
# 顶分型:检查后续2根K线是否持续走弱
fx_mid_level = (self.high + min(self.pre.low, self.next.low)) / 2
if self.next.close < fx_mid_level and next2.close < fx_mid_level:
score += 5 # 强确认
elif self.next.close < fx_mid_level:
score += 3 # 中等确认
else: # BOTTOM
# 底分型:检查后续2根K线是否持续走强
fx_mid_level = (max(self.pre.high, self.next.high) + self.low) / 2
if self.next.close > fx_mid_level and next2.close > fx_mid_level:
score += 5 # 强确认
elif self.next.close > fx_mid_level:
score += 3 # 中等确认
# 2. 技术指标确认
if hasattr(self, 'rsi'):
if self.fx == Chan_FX_TYPE.TOP and self.rsi > 70:
score += 2 # 超买区顶分型
elif self.fx == Chan_FX_TYPE.BOTTOM and self.rsi < 30:
score += 2 # 超卖区底分型
# 3. 分型强度自身确认(K线形态)
if self.fx == Chan_FX_TYPE.TOP:
# 长上影线确认
upper_shadow = self.high - max(self.open, self.close)
candle_range = self.high - self.low
if candle_range > 0 and upper_shadow / candle_range > 0.5:
score += 2
else: # BOTTOM
# 长下影线确认
lower_shadow = min(self.open, self.close) - self.low
candle_range = self.high - self.low
if candle_range > 0 and lower_shadow / candle_range > 0.5:
score += 2
# 4. 与前一个分型的关系
if self.pre and hasattr(self.pre, 'fx') and self.pre.fx != Chan_FX_TYPE.UNKNOWN:
# 检查是否形成有效的笔结构
if self.fx != self.pre.fx: # 分型类型相反
score += 1
return min(10, score)
def _calculate_recent_atr(self, lookback=10):
"""
计算近期ATR(平均真实波动范围)
"""
tr_values = []
temp = self
for i in range(lookback):
if temp and temp.pre:
tr = max(
temp.high - temp.low,
abs(temp.high - temp.pre.close),
abs(temp.low - temp.pre.close)
)
tr_values.append(tr)
temp = temp.pre
else:
break
return sum(tr_values) / len(tr_values) if tr_values else 0
def _calculate_average_volume(self, lookback=5):
"""
计算平均成交量
"""
volumes = []
temp = self.pre # 从前一根K线开始计算
for i in range(lookback):
if temp:
volumes.append(temp.volume)
temp = temp.pre
else:
break
return sum(volumes) / len(volumes) if volumes else 0
def get_fx_strength_level(self):
"""
获取分型强度等级
根据专业评分标准:≥80分为有效强势分型,≤40分建议忽略
"""
strength = self.calculate_fx_strength()
if strength >= 80:
return "极强"
elif strength >= 65:
return ""
elif strength >= 50:
return "中等"
elif strength >= 40:
return ""
else:
return "极弱"
def is_strong_fx(self, threshold=65):
"""
判断是否为强分型
根据专业标准调整阈值为65分
"""
return self.calculate_fx_strength() >= threshold