add more to klu and klc
This commit is contained in:
+225
-1
@@ -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是否包含klu2(klu3的高点≥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,返回基础分
|
||||
|
||||
Reference in New Issue
Block a user