添加分型强弱计算,可以直接跑服务了

This commit is contained in:
Porter
2025-05-24 22:42:35 +08:00
parent a9d24233b0
commit cdc40f795c
13 changed files with 365 additions and 13 deletions
+347 -3
View File
@@ -49,6 +49,7 @@ class ChanKLC():
self.volume_ratio = self.volume_ratio / len(self.klus)
self.volume = self.volume / len(self.klus)
self.macdhist = self.macdhist / len(self.klus)
def set_next(self, klc):
self.next = klc
def set_pre(self, klc):
@@ -1132,7 +1133,7 @@ class ChanKLC():
# ===== 分型强度特征 =====
# 添加分型强度相关特征
features['klc_fx_strength'] = self.calculate_fx_strength()
features['klc_fx_strength'] = self.cal_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
@@ -1146,6 +1147,269 @@ class ChanKLC():
return features
def cal_fx_strength(self):
"""
用self.pre和self.next实现分型强弱判断
核心缠论原理:
- 强分型:出现在笔的末端,能够终结当前笔,标志着趋势转折
- 弱分型:出现在笔的中间,是中继性质,笔还会继续延伸
返回值:
3: 极强分型(笔终结+强确认)
2: 强分型(笔终结)
1: 偏强分型(可能终结笔)
0: 中性分型
-1: 偏弱分型(中继特征明显)
-2: 弱分型(明显中继)
-3: 极弱分型(无效分型)
"""
# 检查是否为分型,且有前后K线数据
if self.fx == Chan_FX_TYPE.UNKNOWN:
return 0
if not self.pre or not self.next:
return 100
# === 核心判断:分型在笔中的位置 ===
# 1. 检查这个分型是否能够终结当前笔
is_bi_end = self._check_if_bi_ending_fx()
# 2. 检查分型的后续走势确认
post_fx_confirmation = self._check_post_fx_confirmation()
# 3. 检查分型的标准性和强度
fx_quality = self._check_fx_quality()
# === 综合评分 ===
base_score = 0
# 笔位置是最重要的判断标准
if is_bi_end == 2: # 强烈确认笔终结
base_score = 2
elif is_bi_end == 1: # 可能笔终结
base_score = 1
elif is_bi_end == -1: # 明显中继
base_score = -2
elif is_bi_end == -2: # 强烈中继特征
base_score = -3
else: # 不确定
base_score = 0
# 后续确认调整
base_score += post_fx_confirmation
# 分型质量调整
base_score += fx_quality
print(self.start_time, base_score, is_bi_end, post_fx_confirmation, fx_quality)
# 限制在-3到3范围内
return max(-3, min(3, base_score))
def _check_if_bi_ending_fx(self):
"""
检查分型是否为笔终结分型
返回值:
2: 强烈确认笔终结
1: 可能笔终结
0: 不确定
-1: 明显中继
-2: 强烈中继特征
"""
# 检查是否有足够的后续数据来判断
if not self.next or not hasattr(self.next, 'next'):
return 0
# 获取分型后的几根K线数据
subsequent_klcs = []
temp = self.next
for i in range(5): # 检查后续5根K线
if temp:
subsequent_klcs.append(temp)
temp = temp.next if hasattr(temp, 'next') else None
else:
break
if len(subsequent_klcs) < 2:
return 0
if self.fx == Chan_FX_TYPE.TOP:
return self._check_top_bi_ending(subsequent_klcs)
else: # BOTTOM
return self._check_bottom_bi_ending(subsequent_klcs)
def _check_top_bi_ending(self, subsequent_klcs):
"""检查顶分型是否为笔终结"""
# 强烈笔终结特征:
# 1. 后续K线持续下跌,且跌破关键位置
# 2. 没有新的更高的高点出现
broken_key_levels = 0
new_highs = 0
downward_trend = 0
# 检查关键价位突破
first_low = self.pre.low
middle_low = self.low
key_support = min(first_low, middle_low)
for i, klc in enumerate(subsequent_klcs):
# 检查是否跌破关键支撑
if klc.low < key_support:
broken_key_levels += 1
# 检查是否出现新高
if klc.high > self.high:
new_highs += 1
# 检查下跌趋势
if i > 0 and klc.close < subsequent_klcs[i-1].close:
downward_trend += 1
# 强烈笔终结:跌破关键位且无新高
if broken_key_levels >= 1 and new_highs == 0 and downward_trend >= 2:
return 2
# 可能笔终结:部分条件满足
if (broken_key_levels >= 1 and new_highs <= 1) or (new_highs == 0 and downward_trend >= 3):
return 1
# 明显中继:出现新高且未跌破关键位
if new_highs >= 2 and broken_key_levels == 0:
return -2
# 中继倾向:出现新高
if new_highs >= 1:
return -1
return 0
def _check_bottom_bi_ending(self, subsequent_klcs):
"""检查底分型是否为笔终结"""
# 强烈笔终结特征:
# 1. 后续K线持续上涨,且突破关键位置
# 2. 没有新的更低的低点出现
broken_key_levels = 0
new_lows = 0
upward_trend = 0
# 检查关键价位突破
first_high = self.pre.high
middle_high = self.high
key_resistance = max(first_high, middle_high)
for i, klc in enumerate(subsequent_klcs):
# 检查是否突破关键阻力
if klc.high > key_resistance:
broken_key_levels += 1
# 检查是否出现新低
if klc.low < self.low:
new_lows += 1
# 检查上涨趋势
if i > 0 and klc.close > subsequent_klcs[i-1].close:
upward_trend += 1
# 强烈笔终结:突破关键位且无新低
if broken_key_levels >= 1 and new_lows == 0 and upward_trend >= 2:
return 2
# 可能笔终结:部分条件满足
if (broken_key_levels >= 1 and new_lows <= 1) or (new_lows == 0 and upward_trend >= 3):
return 1
# 明显中继:出现新低且未突破关键位
if new_lows >= 2 and broken_key_levels == 0:
return -2
# 中继倾向:出现新低
if new_lows >= 1:
return -1
return 0
def _check_post_fx_confirmation(self):
"""
检查分型后的走势确认
返回值:-1到1的调整分数
"""
if not self.next:
return 0
score = 0
# 检查第三根K线的确认
third_klc = self.next
if self.fx == Chan_FX_TYPE.TOP:
# 顶分型:第三根K线应该走弱
middle_price = (self.high + self.low) / 2
if third_klc.close < middle_price:
score += 0.5
if third_klc.low < self.pre.low: # 跌破第一根K线低点
score += 0.5
if third_klc.close < third_klc.open and abs(third_klc.close - third_klc.open) > abs(self.close - self.open) * 0.5:
score += 0.3 # 明显阴线
else: # BOTTOM
# 底分型:第三根K线应该走强
middle_price = (self.high + self.low) / 2
if third_klc.close > middle_price:
score += 0.5
if third_klc.high > self.pre.high: # 突破第一根K线高点
score += 0.5
if third_klc.close > third_klc.open and abs(third_klc.close - third_klc.open) > abs(self.close - self.open) * 0.5:
score += 0.3 # 明显阳线
return min(1, max(-1, score))
def _check_fx_quality(self):
"""
检查分型本身的质量
返回值:-1到1的调整分数
"""
score = 0
# 检查分型的标准性
if self.fx == Chan_FX_TYPE.TOP:
# 高点突出程度
high_diff1 = (self.high - self.pre.high) / self.high if self.high > 0 else 0
high_diff2 = (self.high - self.next.high) / self.high if self.high > 0 else 0
min_diff = min(high_diff1, high_diff2)
if min_diff > 0.03: # 非常突出
score += 0.5
elif min_diff > 0.01: # 比较突出
score += 0.2
elif min_diff < 0.003: # 不够突出
score -= 0.5
else: # BOTTOM
# 低点突出程度
low_diff1 = (self.pre.low - self.low) / self.pre.low if self.pre.low > 0 else 0
low_diff2 = (self.next.low - self.low) / self.next.low if self.next.low > 0 else 0
min_diff = min(low_diff1, low_diff2)
if min_diff > 0.03: # 非常突出
score += 0.5
elif min_diff > 0.01: # 比较突出
score += 0.2
elif min_diff < 0.003: # 不够突出
score -= 0.5
# 检查量价配合
avg_volume = self._calculate_average_volume(lookback=5)
if avg_volume > 0:
volume_ratio = self.volume / avg_volume
if volume_ratio > 1.5:
score += 0.3
elif volume_ratio < 0.7:
score -= 0.2
return min(1, max(-1, score))
def calculate_fx_strength(self):
"""
基于专业缠论理论的分型强度评估体系
@@ -1490,7 +1754,7 @@ class ChanKLC():
根据专业评分标准:≥80分为有效强势分型,≤40分建议忽略
"""
strength = self.calculate_fx_strength()
return ""
if strength >= 80:
return "极强"
elif strength >= 65:
@@ -1507,4 +1771,84 @@ class ChanKLC():
判断是否为强分型
根据专业标准调整阈值为65分
"""
return self.calculate_fx_strength() >= threshold
return self.calculate_fx_strength() >= threshold
def _default_top_strength_judgment(self, first_info, middle_info, last_info, first_kline, middle_kline, last_kline):
"""
顶分型默认强弱判断
当不满足特定强弱条件时的保底判断
"""
# 严格的强分型判断条件
strong_signals = 0
# 判断条件1:成交量显著放大(提高标准)
avg_volume = self._calculate_average_volume(lookback=5)
volume_significantly_amplified = middle_kline.volume > avg_volume * 2.0 if avg_volume > 0 else False
if volume_significantly_amplified:
strong_signals += 1
# 判断条件2:中间K线有长上影线(提高标准)
has_long_upper_shadow = middle_info['upper_shadow_ratio'] > 0.6 # 从0.3提高到0.6
if has_long_upper_shadow:
strong_signals += 1
# 判断条件3:后续K线收盘明显偏低(更严格)
middle_range = middle_kline.high - middle_kline.low
last_close_position = (last_kline.close - middle_kline.low) / middle_range if middle_range > 0 else 0.5
close_significantly_low = last_close_position < 0.3 # 从0.6提高到0.3
if close_significantly_low:
strong_signals += 1
# 判断条件4:最后一根K线是明显的阴线且跌幅较大
is_significant_bearish = (last_info['is_bearish'] and
last_info['body_size'] > last_info['total_range'] * 0.5)
if is_significant_bearish:
strong_signals += 1
# 判断条件5:跌破前一根K线重要价位
breaks_important_level = last_kline.low < first_kline.low
if breaks_important_level:
strong_signals += 1
# 需要至少4个强信号才判断为强分型,否则为弱分型
return 1 if strong_signals >= 4 else -1
def _default_bottom_strength_judgment(self, first_info, middle_info, last_info, first_kline, middle_kline, last_kline):
"""
底分型默认强弱判断
当不满足特定强弱条件时的保底判断
"""
# 严格的强分型判断条件
strong_signals = 0
# 判断条件1:成交量显著放大(提高标准)
avg_volume = self._calculate_average_volume(lookback=5)
volume_significantly_amplified = middle_kline.volume > avg_volume * 2.0 if avg_volume > 0 else False
if volume_significantly_amplified:
strong_signals += 1
# 判断条件2:中间K线有长下影线(提高标准)
has_long_lower_shadow = middle_info['lower_shadow_ratio'] > 0.6 # 从0.3提高到0.6
if has_long_lower_shadow:
strong_signals += 1
# 判断条件3:后续K线收盘明显偏高(更严格)
middle_range = middle_kline.high - middle_kline.low
last_close_position = (last_kline.close - middle_kline.low) / middle_range if middle_range > 0 else 0.5
close_significantly_high = last_close_position > 0.7 # 从0.4降低到0.7
if close_significantly_high:
strong_signals += 1
# 判断条件4:最后一根K线是明显的阳线且涨幅较大
is_significant_bullish = (last_info['is_bullish'] and
last_info['body_size'] > last_info['total_range'] * 0.5)
if is_significant_bullish:
strong_signals += 1
# 判断条件5:突破前一根K线重要价位
breaks_important_level = last_kline.high > first_kline.high
if breaks_important_level:
strong_signals += 1
# 需要至少4个强信号才判断为强分型,否则为弱分型
return 1 if strong_signals >= 4 else -1