add more to klu and klc

This commit is contained in:
jackyu66git
2025-06-03 23:40:19 +08:00
parent ec46febceb
commit 872eec8100
4 changed files with 512 additions and 11 deletions
+225 -1
View File
@@ -135,6 +135,229 @@ class ChanKLC():
self.bi = bi
self.distance = self.index - bi.start_klc.index
#print(self.start_time, self.distance, bi.index, bi.dir)
def cal_fx(self):
"""
根据缠论分型强弱判断规则计算分型强度
返回值:
- 0: 不是分型或无效分型
- 1-100: 分型强度,数值越大表示分型越强
"""
# 检查基本条件:必须是分型且有前后KLC
if (self.fx == Chan_FX_TYPE.UNKNOWN or
self.pre is None or self.next is None or
self.next.end_klu is None):
return 0
# 获取分型的三根K线(KLC
klc1 = self.pre # 第1条
klc2 = self # 第2条(分型中心)
klc3 = self.next # 第3条
if self.fx == Chan_FX_TYPE.TOP:
return self._calculate_top_fx_strength(klc1, klc2, klc3)
elif self.fx == Chan_FX_TYPE.BOTTOM:
return self._calculate_bottom_fx_strength(klc1, klc2, klc3)
else:
return 0
def _calculate_top_fx_strength(self, klc1, klc2, klc3):
"""
计算顶分型强度
"""
strength = 50 # 基础分数
# 1. 检查包含关系(规则1
has_inclusion = self._has_inclusion_relationship(klc1, klc2, klc3)
if not has_inclusion:
strength += 20 # 没有包含关系加分
else:
strength -= 10 # 有包含关系减分
# 检查最坏的包含关系(规则4
if self._is_worst_inclusion_for_top(klc2, klc3):
strength -= 20 # 第3条大阴线"吃掉"第2条阳线
# 2. 检查第1条K线是否为大阳线,第2、3条为小K线(规则2)
if self._is_big_bullish_followed_by_small(klc1, klc2, klc3):
strength -= 25 # 中继顶分型可能性大
# 3. 检查第2条K线形态和第3条K线位置(规则3)
if self._has_strong_top_pattern(klc2, klc3):
strength += 25 # 力度比较大的分型
# 4. 检查第3条K线是否跌破第1条K线(规则5)
if self._breaks_first_klc_bottom_for_top(klc1, klc3):
strength -= 15 # 较弱的顶分型
# 5. 成交量确认
volume_factor = self._get_volume_factor(klc2)
strength += volume_factor
return max(0, min(100, strength))
def _calculate_bottom_fx_strength(self, klc1, klc2, klc3):
"""
计算底分型强度
"""
strength = 50 # 基础分数
# 1. 检查包含关系
has_inclusion = self._has_inclusion_relationship(klc1, klc2, klc3)
if not has_inclusion:
strength += 20 # 没有包含关系加分
else:
strength -= 10 # 有包含关系减分
# 2. 检查第3条K线高点与第1条K线高点的关系(规则1-3)
high_relationship = self._analyze_bottom_high_relationship(klc1, klc3)
if high_relationship == "strong": # 第3条高点远高于第1条
strength += 25
elif high_relationship == "normal": # 第3条高点接近第1条
strength += 5
else: # 第3条高点低于第1条
strength -= 15
# 3. 检查后续K线确认(规则4
if self._has_follow_through_for_bottom():
strength += 15
# 4. 成交量确认
volume_factor = self._get_volume_factor(klc2)
strength += volume_factor
return max(0, min(100, strength))
def _has_inclusion_relationship(self, klc1, klc2, klc3):
"""
检查构成分型的三根原始K线(KLU)是否存在包含关系
"""
# 检查任意两根KLU之间是否存在包含关系
return (klc1.start_klu.index - klc1.end_klu.index != 0 or klc2.start_klu.index - klc2.end_klu.index != 0 or klc3.start_klu.index - klc3.end_klu.index != 0)
def _is_worst_inclusion_for_top(self, klc2, klc3):
"""
检查是否为最坏的包含关系:第3根KLU大阴线"吃掉"第2根KLU阳线
"""
# 获取代表性的KLU
# 第2根KLU:取klc2的最后一根KLU
klu2 = klc2.end_klu if klc2.end_klu else klc2.start_klu
# 第3根KLU:取klc3的第一根KLU
klu3 = klc3.start_klu
if not klu2 or not klu3:
return False
# 检查klu2是否为阳线
klu2_is_bullish = klu2.close > klu2.open
# 检查klu3是否为大阴线(实体占总区间70%以上)
klu3_range = klu3.high - klu3.low
klu3_body = abs(klu3.close - klu3.open)
klu3_is_big_bearish = (klu3.close < klu3.open and
klu3_range > 0 and
klu3_body > klu3_range * 0.7)
# 检查klu3是否包含klu2klu3的高点≥klu2的高点 且 klu3的低点≤klu2的低点)
klu3_contains_klu2 = (klu3.high >= klu2.high and klu3.low <= klu2.low)
return klu2_is_bullish and klu3_is_big_bearish and klu3_contains_klu2
def _is_big_bullish_followed_by_small(self, klc1, klc2, klc3):
"""
检查第1条是否为大阳线,第2、3条为小K线
"""
# 第1条为大阳线
klc1_big_bullish = (klc1.close > klc1.open and
abs(klc1.close - klc1.open) > (klc1.high - klc1.low) * 0.6)
# 第2、3条为小K线
klc2_small = abs(klc2.close - klc2.open) < (klc2.high - klc2.low) * 0.4
klc3_small = abs(klc3.close - klc3.open) < (klc3.high - klc3.low) * 0.4
return klc1_big_bullish and klc2_small and klc3_small
def _has_strong_top_pattern(self, klc2, klc3):
"""
检查是否有强力度的顶分型模式
"""
# 第2条K线有长上影线或为大阴线
klc2_range = klc2.high - klc2.low
if klc2_range > 0:
upper_shadow_ratio = (klc2.high - max(klc2.open, klc2.close)) / klc2_range
has_long_upper_shadow = upper_shadow_ratio > 0.3
else:
has_long_upper_shadow = False
klc2_big_bearish = (klc2.close < klc2.open and
abs(klc2.close - klc2.open) > klc2_range * 0.6)
klc2_strong = has_long_upper_shadow or klc2_big_bearish
# 第3条K线不能以阳线收在第2条K线区间的一半之上
klc2_mid = (klc2.high + klc2.low) / 2
klc3_weak_position = (klc3.close <= klc2_mid or klc3.close < klc3.open)
return klc2_strong and klc3_weak_position
def _breaks_first_klc_bottom_for_top(self, klc1, klc3):
"""
检查第3条是否跌破第1条K线底部且不能高于第1条区间一半之上
"""
breaks_bottom = klc3.low < klc1.low
klc1_mid = (klc1.high + klc1.low) / 2
below_mid = klc3.close <= klc1_mid
return breaks_bottom and below_mid
def _analyze_bottom_high_relationship(self, klc1, klc3):
"""
分析底分型中第3条K线高点与第1条K线高点的关系
"""
high_diff_ratio = (klc3.high - klc1.high) / klc1.high if klc1.high > 0 else 0
if high_diff_ratio > 0.02: # 高出2%以上
return "strong"
elif high_diff_ratio >= -0.01: # 接近或略高
return "normal"
else: # 明显低于
return "weak"
def _has_follow_through_for_bottom(self):
"""
检查底分型后续是否有确认
"""
# 检查后续第1条K线的低点是否高于底分型的上边沿
if self.next and self.next.next:
follow_klc = self.next.next
bottom_fx_top = max(self.pre.high, self.high, self.next.high)
return follow_klc.low > bottom_fx_top
return False
def _get_volume_factor(self, klc):
"""
获取成交量因子
"""
avg_volume = self._calculate_average_volume(lookback=5)
if avg_volume > 0:
volume_ratio = klc.volume / avg_volume
if volume_ratio > 2.0:
return 10 # 大量确认
elif volume_ratio > 1.5:
return 5 # 放量
elif volume_ratio < 0.5:
return -5 # 缩量
return 0
def check_pre_has_fx(self):
if self.pre:
return self.pre.fx != Chan_FX_TYPE.UNKNOWN
elif self.pre.pre:
return self.pre.pre.fx != Chan_FX_TYPE.UNKNOWN
elif self.pre.pre.pre:
return self.pre.pre.pre.fx != Chan_FX_TYPE.UNKNOWN
elif self.pre.pre.pre.pre:
return self.pre.pre.pre.pre.fx != Chan_FX_TYPE.UNKNOWN
else:
return False
def cal_klu_features(self):
features = dict()
feature_sums = dict()
@@ -1162,8 +1385,9 @@ class ChanKLC():
Returns:
int: 强度评分 15-80分
"""
return self.cal_fx()
# 如果不是分型,返回0
if self.fx == Chan_FX_TYPE.UNKNOWN:
if self.fx == Chan_FX_TYPE.UNKNOWN or self.pre == None or self.next == None or self.next.end_klu == None:
return 0
# 如果没有前一个KLC,返回基础分