添加新的bb2633,笔识别改回去了

This commit is contained in:
jackyu66git
2026-02-24 01:01:19 +08:00
parent 85609d2758
commit 377f23a9ec
6 changed files with 1595 additions and 1726 deletions
+24 -5
View File
@@ -61,8 +61,9 @@ class ChanKLC():
# 向后兼容:保留 ema52_status 和 ema52_pos
self.ema52_status = 0
self.ema52_pos = Chan_EMA_POS.UNKNOWN
self.cal_all_ema_status()
self.bb2633upper = klu.bb2633upper
self.bb2633lower = klu.bb2633lower
self.bb2633middle = klu.bb2633middle
# ==================== EMA 通用计算方法 ====================
@staticmethod
@@ -278,13 +279,19 @@ class ChanKLC():
# 向后兼容
self.ema52_pos = self.ema_status['ema52']['pos']
self.ema52_status = ChanKLC.semantic_to_int(self.ema_status['ema52']['semantic'])
def get_ema_pos(self, ema_name):
"""获取指定EMA的客观位置,如 klc.get_ema_pos('ema24')"""
if ema_name in self.ema_status:
return self.ema_status[ema_name]['pos']
return Chan_EMA_POS.UNKNOWN
def check_ema_pos(self):
if len(self.ema_status) > 0:
for ema_name, pos in self.ema_status.items():
#print(self.end_time, ema_name, pos['pos'])
if ((self.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc_fx_type == Chan_KLC_FX.TOP2) and pos['pos'] == Chan_EMA_POS.CROSS_CLOSE_BELOW) or ((self.klc_fx_type == Chan_KLC_FX.BOTTOM1 or self.klc_fx_type == Chan_KLC_FX.BOTTOM2) and pos['pos'] == Chan_EMA_POS.CROSS_CLOSE_ABOVE):
#print("---------------------")
return ema_name
return None
def get_ema_semantic(self, ema_name):
"""获取指定EMA的语义状态,如 klc.get_ema_semantic('ema52')"""
if ema_name in self.ema_status:
@@ -303,7 +310,12 @@ class ChanKLC():
#print(self.start_time, klc_fx_type, self.get_feature_data()['klu_macd'], self.get_feature_data()['klu_macdhist'], self.get_feature_data()['klu_rsi'])
self.klc_fx_type = klc_fx_type
#self.cal_fx()
self.cal_bb_out()
ema_name = self.check_ema_pos()
hist_div = abs(self.macdhist - self.next.macdhist)
#print(self.end_time, self.dir, abs(self.macdhist), hist_div)
#if ema_name:
#print(self.end_time, ema_name, self.ema_status[ema_name]['semantic'], hist_div)
#self.cal_bb_out()
def add_klu(self, klu):
self.klu_list.append(klu)
def set_end_klu(self, klu):
@@ -323,6 +335,7 @@ class ChanKLC():
klu.set_klc(self)
self.klc_dir = Chan_KLINE_DIR.UP if self.close > self.open else Chan_KLINE_DIR.DOWN
self.cal_indicators()
self.cal_all_ema_status()
def cal_fx(self):
if self.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc_fx_type == Chan_KLC_FX.TOP2:
#print(self.end_time, self.fx, self.macd, self.macdhist, len(self.klu_list))
@@ -368,6 +381,9 @@ class ChanKLC():
self.ema104 += self.klu_list[index].ema104
self.ema156 += self.klu_list[index].ema156
self.ema208 += self.klu_list[index].ema208
self.bb2633upper += self.klu_list[index].bb2633upper
self.bb2633lower += self.klu_list[index].bb2633lower
self.bb2633middle += self.klu_list[index].bb2633middle
if self.ema_dir != self.klu_list[index].ema_dir:
self.ema_dir = 0
n = len(self.klu_list)
@@ -380,6 +396,9 @@ class ChanKLC():
self.ema104 = self.ema104 / n
self.ema156 = self.ema156 / n
self.ema208 = self.ema208 / n
self.bb2633upper = self.bb2633upper / n
self.bb2633lower = self.bb2633lower / n
self.bb2633middle = self.bb2633middle / n
if len(self.klu_list) > 0:
self.macd = self.klu_list[-1].macd
self.signal = self.klu_list[-1].signal
+36 -3
View File
@@ -71,6 +71,9 @@ class ChanKLU:
self.div_score = 0.0 # 背离强度(0-100)
self.ema_dir = 0
self.get_ema_dir()
self.bb2633upper = 0
self.bb2633lower = 0
self.bb2633middle = 0
#print(self.open, self.close, self.high, self.low, self.candle_dir, self.strength)
def set_macd_state(self, state):
self.macd_state = state
@@ -90,9 +93,37 @@ class ChanKLU:
self.trend = trend
def set_separate_div(self, separate_div):
self.separate_div = separate_div
bb2633_status = self.check_bb2633()
if self.klc and self.klc.pre and self.klc.next:
if self.klc.klc_fx_type != Chan_KLC_FX.UNKNOWN or self.klc.pre.klc_fx_type != Chan_KLC_FX.UNKNOWN or self.klc.next.klc_fx_type != Chan_KLC_FX.UNKNOWN:
self.separate_div = 99
fx = self.check_fx_dir(self.klc.pre, self.klc.next)
if fx == Chan_FX_TYPE.TOP:
if self.macdhist > 0:
self.separate_div = separate_div
else:
self.separate_div = 0
elif fx == Chan_FX_TYPE.BOTTOM:
if self.macdhist < 0:
self.separate_div = separate_div
else:
self.separate_div = 0
if bb2633_status == 0:
self.separate_div = 0
def check_bb2633(self, threadhold=300):
#print(self.time, self.high, self.bb2633upper, self.low, self.bb2633lower)
if abs(self.high - self.bb2633upper) < threadhold:
print(self.time, self.high, self.bb2633upper)
return 1
if abs(self.low - self.bb2633lower) < threadhold:
print(self.time, self.low, self.bb2633lower)
return -1
return 0
def check_fx_dir(self, pre, next):
fx = Chan_FX_TYPE.UNKNOWN
if pre.klc_fx_type == Chan_KLC_FX.TOP1 or pre.klc_fx_type == Chan_KLC_FX.TOP2 or next.klc_fx_type == Chan_KLC_FX.TOP1 or next.klc_fx_type == Chan_KLC_FX.TOP2 or self.klc.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc.klc_fx_type == Chan_KLC_FX.TOP2:
fx = Chan_FX_TYPE.TOP
elif pre.klc_fx_type == Chan_KLC_FX.BOTTOM1 or pre.klc_fx_type == Chan_KLC_FX.BOTTOM2 or next.klc_fx_type == Chan_KLC_FX.BOTTOM1 or next.klc_fx_type == Chan_KLC_FX.BOTTOM2 or self.klc.klc_fx_type == Chan_KLC_FX.BOTTOM1 or self.klc.klc_fx_type == Chan_KLC_FX.BOTTOM2:
fx = Chan_FX_TYPE.BOTTOM
return fx
def set_next(self, next):
self.next = next
#if self.fx_type != Chan_FX_TYPE.UNKNOWN and self.fx_strength > 1:
@@ -151,7 +182,9 @@ class ChanKLU:
self.volume_ratio = float(item['volume_ratio']) if 'volume_ratio' in item and item['volume_ratio'] else 0
self.bb52upper = float(item['bb52upper']) if 'bb52upper' in item and item['bb52upper'] else 0
self.bb52lower = float(item['bb52lower']) if 'bb52lower' in item and item['bb52lower'] else 0
self.bb2633upper = float(item['bb2633upper']) if 'bb2633upper' in item and item['bb2633upper'] else 0
self.bb2633lower = float(item['bb2633lower']) if 'bb2633lower' in item and item['bb2633lower'] else 0
self.bb2633middle = float(item['bb2633middle']) if 'bb2633middle' in item and item['bb2633middle'] else 0
def cal_macd_state(self):
# 按定义精简实现:优先级 CROSS0 > 位置(HIGH/HE/RETURN_ZERO) > NEAR0 > UNKNOWN
# 首条或缺前一根
-2
View File
@@ -151,8 +151,6 @@ class ChanLun():
return self.tf_df.check_bottom_fx(last_top, klc)
def cal_bi_list(self, klc_list):
return self.tf_df.cal_bi_list(klc_list)
def cal_bi_list_chanlun(self, klc_list):
return self.tf_df.cal_bi_list_chanlun(klc_list)
def find_first_bsp(self, bi_list, bi_zs_list):
return self.tf_df.find_first_bsp(bi_list, bi_zs_list)
def find_second_bsp(self, bi_list, first_bsp_list):
+13 -199
View File
@@ -81,6 +81,7 @@ class TF_DF():
bb302 = ta.BBANDS(df, timeperiod=41, nbdevup=2.0, nbdevdn=2.0, matype=0)
bb30 = ta.BBANDS(df, timeperiod=20, nbdevup=2.0, nbdevdn=2.0, matype=0)
bb302 = ta.BBANDS(df, timeperiod=20, nbdevup=2.0, nbdevdn=2.0, matype=0)
bb2633 = ta.BBANDS(df, timeperiod=26, nbdevup=3.0, nbdevdn=3.0, matype=0)
# 计算布林带中轨(移动平均线)
bb30_middle = ta.SMA(df, timeperiod=90)
@@ -90,6 +91,11 @@ class TF_DF():
bbp120 = (df['close'] - bb120['lowerband']) / (bb120['upperband'] - bb120['lowerband'])
bbp30 = (df['close'] - bb30['lowerband']) / (bb30['upperband'] - bb30['lowerband'])
bbp302 = (df['close'] - bb302['lowerband']) / (bb302['upperband'] - bb302['lowerband'])
bbp2633 = (df['close'] - bb2633['lowerband']) / (bb2633['upperband'] - bb2633['lowerband'])
df['bb2633upper'] = bb2633['upperband']
df['bb2633lower'] = bb2633['lowerband']
df['bbp2633'] = bbp2633
df['bb2633middle'] = bb2633['middleband']
df['atr'] = ta.ATR(df, timeperiod=14)
df['bbup365'] = bb365['upperband']
df['bblow365'] = bb365['lowerband']
@@ -114,6 +120,7 @@ class TF_DF():
df['ema104'] = ta.EMA(df, timeperiod=104)
df['ema156'] = ta.EMA(df, timeperiod=156)
df['ema208'] = ta.EMA(df, timeperiod=208)
df['ema26'] = ta.EMA(df, timeperiod=26)
df['rsi'] = ta.RSI(df, timeperiod=14)
df['volume_ratio'] = self.cal_volume_ratio(df)
return df
@@ -872,11 +879,11 @@ class TF_DF():
last_bottom = None
for klc in klc_list:
fx = self.check_fx(klc)
if fx == Chan_FX_TYPE.TOP and False:
if fx == Chan_FX_TYPE.TOP:
if last_bottom:
if self.check_top_fx(last_bottom, klc) == False:
fx = Chan_FX_TYPE.UNKNOWN
if fx == Chan_FX_TYPE.BOTTOM and False:
if fx == Chan_FX_TYPE.BOTTOM:
if last_top:
if self.check_bottom_fx(last_top, klc) == False:
#print(klc.end_time, last_top.end_time, "---")
@@ -1198,200 +1205,6 @@ class TF_DF():
return False
return True
def check_fx_chanlun(self, klc):
"""标准缠论分型:仅用高低点,不用 MACD,不要求整根 K 线包在左右内。"""
if klc.pre is None or klc.next is None:
return Chan_FX_TYPE.UNKNOWN
# 顶分型:中间 K 线高点最高
if klc.high > klc.pre.high and klc.high > klc.next.high:
klc.set_fx(Chan_FX_TYPE.TOP)
return Chan_FX_TYPE.TOP
# 底分型:中间 K 线低点最低
if klc.low < klc.pre.low and klc.low < klc.next.low:
klc.set_fx(Chan_FX_TYPE.BOTTOM)
return Chan_FX_TYPE.BOTTOM
return Chan_FX_TYPE.UNKNOWN
def cal_bi_list_chanlun(self, klc_list):
"""
cal_bi_list 逻辑完全一致仅分型用 check_fx_chanlun标准缠论分型不看 MACD
"""
bi_list = []
last_top = None
last_bottom = None
for klc in klc_list:
fx = self.check_fx_chanlun(klc)
if fx == Chan_FX_TYPE.TOP:
if last_bottom:
if self.check_top_fx(last_bottom, klc) == False:
fx = Chan_FX_TYPE.UNKNOWN
if fx == Chan_FX_TYPE.BOTTOM:
if last_top:
if self.check_bottom_fx(last_top, klc) == False:
fx = Chan_FX_TYPE.UNKNOWN
if fx == Chan_FX_TYPE.UNKNOWN:
if len(bi_list) > 0:
bi_list[-1].add_klc(klc)
continue
if len(bi_list) > 0 and klc.end_klu:
last_bi = bi_list[-1]
if last_top and last_bi.dir == Chan_BI_DIR.DOWN:
if last_bottom and klc.high > last_bi.high:
last_bi.set_end_klc(last_bottom, klc)
bi = ChanBI(last_bottom, len(bi_list), Chan_BI_DIR.UP)
last_bi.set_next(bi)
bi.set_pre(last_bi)
for klc_index in range(last_bi.end_klc.index, len(klc_list)):
bi.add_klc(klc_list[klc_index])
bi_list.append(bi)
last_top = klc
klc.set_bi(bi)
else:
if last_bottom and last_bi.dir == Chan_BI_DIR.UP:
if last_top and klc.low < last_bi.low:
last_bi.set_end_klc(last_top, klc)
bi = ChanBI(last_top, len(bi_list), Chan_BI_DIR.DOWN)
last_bi.set_next(bi)
bi.set_pre(last_bi)
for klc_index in range(last_bi.end_klc.index, len(klc_list)):
bi.add_klc(klc_list[klc_index])
bi_list.append(bi)
last_bottom = klc
klc.set_bi(bi)
else:
if fx == Chan_FX_TYPE.TOP:
if last_top:
if last_bottom:
if last_bottom.index < last_top.index:
if last_top.high > klc.high:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_top = klc
klc.set_klc_fx_type(Chan_KLC_FX.TOP1)
self.check_fx_pattern(klc)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_bottom.index + 4 > klc.index:
if last_top.high > klc.high:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_top.index + 4 < klc.index and len(bi_list) > 1:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
klc.set_fx(Chan_FX_TYPE.PTOP)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_bi = bi_list[-1]
if not last_bi.is_sure:
last_bi.set_end_klc(last_bottom, klc)
bi = ChanBI(last_bottom, len(bi_list), Chan_BI_DIR.UP)
last_bi.set_next(bi)
bi.set_pre(last_bi)
bi.add_klc(klc)
bi_list.append(bi)
last_top = klc
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
self.check_fx_pattern(klc)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_top.high < klc.high:
last_bi = bi_list[-1]
last_bi.set_start_klc(klc, Chan_BI_DIR.DOWN)
last_top = klc
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
klc.set_fx(Chan_FX_TYPE.TT)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_bottom:
if last_bottom.index + 4 > klc.index:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_top = klc
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_top = klc
bi = ChanBI(klc, len(bi_list), Chan_BI_DIR.DOWN)
bi_list.append(bi)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_bottom:
if last_top:
if last_top.index < last_bottom.index:
if last_bottom.low < klc.low:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_bottom = klc
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM1)
self.check_fx_pattern(klc)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_top.index + 4 > klc.index:
if last_bottom.low < klc.low:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_bottom.index + 4 < klc.index and len(bi_list) > 1:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_bi = bi_list[-1]
if not last_bi.is_sure:
last_bi.set_end_klc(last_top, klc)
bi = ChanBI(last_top, len(bi_list), Chan_BI_DIR.DOWN)
last_bi.set_next(bi)
bi.set_pre(last_bi)
bi.add_klc(klc)
bi_list.append(bi)
last_bottom = klc
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2)
self.check_fx_pattern(klc)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_bottom.low > klc.low:
last_bi = bi_list[-1]
last_bi.set_start_klc(klc, Chan_BI_DIR.UP)
last_bottom = klc
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
klc.set_fx(Chan_FX_TYPE.BB)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_top:
if last_top.index + 4 > klc.index:
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_bottom = klc
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
last_bottom = klc
bi = ChanBI(klc, len(bi_list), Chan_BI_DIR.UP)
bi_list.append(bi)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
return bi_list
def cal_bi_zs(self, seg_list):
bi_zs_list = []
for seg in seg_list:
@@ -1453,7 +1266,7 @@ class TF_DF():
Chan_BSP_DIR.SELL,
leave_bi.sure_time,
zs.index+1, zs, None
)
)
leave_bi.end_klc.set_bsp_type(Chan_BSP_TYPE.S1)
bsp_list.append(bsp)
# 回拉笔
@@ -1496,7 +1309,7 @@ class TF_DF():
Chan_BSP_DIR.BUY,
leave_bi.sure_time,
zs.index+1, zs, None
)
)
leave_bi.end_klc.set_bsp_type(Chan_BSP_TYPE.B1)
bsp_list.append(bsp)
# 反弹笔
@@ -1713,7 +1526,8 @@ class TF_DF():
bsp_list.append(bsp)
return bsp_list
def calculate_zs(self, bi_list, seg_list):
return self.get_zs_list(bi_list, seg_list)
def get_zs_list(self, bi_list, seg_list):
zs_list = []
bsp_list = []
+1 -1
View File
@@ -136,7 +136,7 @@ class ChanLun_BTC_30(IStrategy):
#state_list = self.chan.get_klu_state(dataframe_1d)
#dataframe_1d['state'] = state_list
if self.last_time + timedelta(minutes=1) < datetime.now():
print("-------------------------------------------------------------------------------")
#print("-------------------------------------------------------------------------------")
self.last_time = datetime.now()
#dataframe = resampled_merge(dataframe, dataframe_3)
dataframe = resampled_merge(dataframe, dataframe_5)
+1424 -1419
View File
File diff suppressed because it is too large Load Diff