From d60805487d829d4798fab3d327f73f4772ff3a94 Mon Sep 17 00:00:00 2001 From: jackyu66git Date: Tue, 8 Jul 2025 02:25:23 +0800 Subject: [PATCH] add bb bb --- ChanKLC.py | 10 ++++++ ChanKLU.py | 7 ++++ ChanLun.py | 14 +++++--- strategies/ChanLun_BTC_30.py | 63 +++++++++++++++++------------------- web/app.py | 24 +++++++------- 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/ChanKLC.py b/ChanKLC.py index 8c20229..27a29dc 100644 --- a/ChanKLC.py +++ b/ChanKLC.py @@ -42,6 +42,7 @@ class ChanKLC(): self.strength = klu.strength self.last_top_klc = None self.last_bottom_klc = None + self.bb_out = False def set_last_top_klu(self, last_top_klc): self.last_top_klc = last_top_klc def set_last_bottom_klc(self, last_bottom_klc): @@ -58,6 +59,15 @@ class ChanKLC(): self.cal_indicators() self.cal_shape_1() self.strength = self.cal_klc_strength() + self.cal_bb_out() + def cal_bb_out(self): + for klu in self.klus: + if self.high >= klu.bbup30 and klu.bbup30 > 0: + self.bb_out = True + break + if self.low <= klu.bblow30 and klu.bblow30 > 0: + self.bb_out = True + break def cal_indicators(self): for index in range(1, len(self.klus)): self.volume += self.klus[index].volume diff --git a/ChanKLU.py b/ChanKLU.py index 2056857..3f102b1 100644 --- a/ChanKLU.py +++ b/ChanKLU.py @@ -582,6 +582,13 @@ class ChanKLU: self.bbp365 = float(item['bbp365']) if 'bbp365' in item and item['bbp365'] else 0 self.bb120 = float(item['bb120']) if 'bb120' in item and item['bb120'] else 0 self.bb365 = float(item['bb365']) if 'bb365' in item and item['bb365'] else 0 + self.bbp30 = float(item['bbp30']) if 'bbp30' in item and item['bbp30'] else 0 + self.bbup30 = float(item['bbup30']) if 'bbup30' in item and item['bbup30'] else 0 + self.bblow30 = float(item['bblow30']) if 'bblow30' in item and item['bblow30'] else 0 + self.bbup120 = float(item['bbup120']) if 'bbup120' in item and item['bbup120'] else 0 + self.bblow120 = float(item['bblow120']) if 'bblow120' in item and item['bblow120'] else 0 + self.bbup365 = float(item['bbup365']) if 'bbup365' in item and item['bbup365'] else 0 + self.bblow365 = float(item['bblow365']) if 'bblow365' in item and item['bblow365'] else 0 # 设置指标后更新实时分析 self.update_realtime_analysis() diff --git a/ChanLun.py b/ChanLun.py index f7d5d1e..cdded05 100644 --- a/ChanLun.py +++ b/ChanLun.py @@ -104,11 +104,17 @@ class ChanLun(): if klc.end_klu: if klc.end_klu.idx == index: klc_index += 1 - if klc.klc_fx_type == Chan_KLC_FX.TOP3: - state_list.append("10") + if klc.klc_fx_type == Chan_KLC_FX.TOP1 or klc.klc_fx_type == Chan_KLC_FX.TOP2: + if klc.bb_out: + state_list.append("10") + else: + state_list.append("00") #print(klc.start_time, klc.end_time, klc.klc_fx_type) - elif klc.klc_fx_type == Chan_KLC_FX.BOTTOM3: - state_list.append("-10") + elif klc.klc_fx_type == Chan_KLC_FX.BOTTOM1 or klc.klc_fx_type == Chan_KLC_FX.BOTTOM2: + if klc.bb_out: + state_list.append("-10") + else: + state_list.append("00") #print(klc.start_time, klc.end_time, klc.klc_fx_type) else: state_list.append("00") diff --git a/strategies/ChanLun_BTC_30.py b/strategies/ChanLun_BTC_30.py index 6eade46..99dc225 100644 --- a/strategies/ChanLun_BTC_30.py +++ b/strategies/ChanLun_BTC_30.py @@ -35,6 +35,7 @@ class ChanLun_BTC_30(IStrategy): # Minimal ROI designed for the strategy. # This attribute will be overridden if the config file contains "minimal_roi" # 30m and 1h + minimal_roi = { "0": 0.60, "360": 0.2, @@ -49,29 +50,29 @@ class ChanLun_BTC_30(IStrategy): "240": 0 } # 15m and 30m - minimal_roi_1 = { + minimal_roi = { "0": 0.1, "240": 0.05, "480": 0.03, "600": 0 } minimal_roi_1 = { - "0": 0.10, - "1200": 0.05, - "2400": 0.025, - "3600": 0 + "0": 1.50, + "120": 0.05, + "240": 0.025, + "360": 0 } can_short = True lev = 1.0 - stoploss = -0.5 - use_custom_stoploss = True + stoploss = -0.01 + #use_custom_stoploss = True trailing_stop = False trailing_stop_positive = 0.025 trailing_stop_positive_offset = 0.045 trailing_only_offset_is_reached = False - position_adjustment_enable = True + #position_adjustment_enable = True startup_candle_count = 780 time5 = 5 @@ -79,7 +80,7 @@ class ChanLun_BTC_30(IStrategy): time30 = 30 time60 = 60 time4h = 240 - time30 = 15 + time30 = 60 last_time = datetime.now() chan = ChanLun() chanpy = ChanPY() @@ -112,10 +113,9 @@ class ChanLun_BTC_30(IStrategy): #self.chan.plot_dual(dataframe_5, dataframe_30) chanpy_state = self.chanpy.get_bsp_state(dataframe_5) dataframe_5['chanpy_state'] = chanpy_state - state_list = self.chan.get_klc_state_list(dataframe_15) - dataframe_15['state'] = state_list - dataframe_15['fx'] = state_list - state_list = self.chan.get_klc_state_list(dataframe_30) + state_list = self.chan.get_klc_state_list(dataframe_60) + dataframe_60['state'] = state_list + dataframe_60['fx'] = state_list #bi_list_1 = self.chan.get_bi_list(dataframe) #bi_list_5 = self.chan.get_bi_list(dataframe_5) #bi_list_15 = self.chan.get_bi_list(dataframe_15) @@ -131,9 +131,9 @@ class ChanLun_BTC_30(IStrategy): print("-------------------------------------------------------------------------------") self.last_time = datetime.now() dataframe = resampled_merge(dataframe, dataframe_5) - dataframe = resampled_merge(dataframe, dataframe_15) + #dataframe = resampled_merge(dataframe, dataframe_15) #dataframe = resampled_merge(dataframe, dataframe_30) - #dataframe = resampled_merge(dataframe, dataframe_60) + dataframe = resampled_merge(dataframe, dataframe_60) #dataframe = resampled_merge(dataframe, dataframe_4h) return dataframe def print_seg(self, dataframe): @@ -155,16 +155,21 @@ class ChanLun_BTC_30(IStrategy): macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period) bb365 = ta.BBANDS(df, timeperiod=365, nbdevup=3.0, nbdevdn=3.0, matype=0) bb120 = ta.BBANDS(df, timeperiod=120, nbdevup=3.0, nbdevdn=3.0, matype=0) - + bb30 = ta.BBANDS(df, timeperiod=90, nbdevup=3.0, nbdevdn=3.0, matype=0) # 手动计算布林带 %B 指标 (BBP) # %B = (Price - Lower Band) / (Upper Band - Lower Band) bbp365 = (df['close'] - bb365['lowerband']) / (bb365['upperband'] - bb365['lowerband']) bbp120 = (df['close'] - bb120['lowerband']) / (bb120['upperband'] - bb120['lowerband']) - - df['bb365'] = bb365['upperband'] + bbp30 = (df['close'] - bb30['lowerband']) / (bb30['upperband'] - bb30['lowerband']) + df['bbup365'] = bb365['upperband'] + df['bblow365'] = bb365['lowerband'] df['bbp365'] = bbp365 - df['bb120'] = bb120['upperband'] + df['bbup120'] = bb120['upperband'] + df['bblow120'] = bb120['lowerband'] df['bbp120'] = bbp120 + df['bbup30'] = bb30['upperband'] + df['bblow30'] = bb30['lowerband'] + df['bbp30'] = bbp30 df['macd'] = macd['macd'] df['macdsignal'] = macd['macdsignal'] df['macdhist'] = macd['macdhist'] @@ -267,7 +272,7 @@ class ChanLun_BTC_30(IStrategy): if last_low and current_rate < last_low: #print(trade.open_date, last_low, current_rate, "Relay Bottom FX exit") return "Relay Bottom FX exit" - def order_filled(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None: + def order_filled1(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None: """ Called right after an order fills. Will be called for all order types (entry, exit, stoploss, position adjustment). @@ -313,17 +318,9 @@ class ChanLun_BTC_30(IStrategy): fx_str = 'resample_{}_fx'.format(self.get_ticker_indicator()*self.time30) #chanpy_state_str = 'resample_{}_chanpy_state'.format(self.get_ticker_indicator()*self.time5) shift_time = self.time30 - strength = 0.9 - ema5 = 'resample_{}_ema5'.format(self.get_ticker_indicator()*self.time30) - ema10 = 'resample_{}_ema10'.format(self.get_ticker_indicator()*self.time30) - ema26 = 'resample_{}_ema26'.format(self.get_ticker_indicator()*self.time30) - ema52 = 'resample_{}_ema52'.format(self.get_ticker_indicator()*self.time30) dataframe.loc[ ( - (dataframe[ema5] > dataframe[ema10]) & - (dataframe[ema10] > dataframe[ema26]) & - (dataframe[ema26] > dataframe[ema52]) & - (dataframe[ema52] > 0) + (dataframe[state_str].shift(shift_time) == "-10") #(dataframe['state'] == "-30") #(dataframe[state_str].shift(shift_time) == "-10") #(dataframe[fx_str].shift(shift_time) == -1) @@ -336,8 +333,7 @@ class ChanLun_BTC_30(IStrategy): ['enter_long', 'enter_tag']] = (1, 'long_signal_chan') dataframe.loc[ ( - #(dataframe['state'] == "-30") - (dataframe[state_str].shift(shift_time) == "101") + (dataframe[state_str].shift(shift_time) == "10") #(dataframe[fx_str].shift(shift_time) == 1) #(dataframe[chanpy_state_str].shift(shift_time+30) == -1) #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") & @@ -352,11 +348,10 @@ class ChanLun_BTC_30(IStrategy): fx_str = 'resample_{}_fx'.format(self.get_ticker_indicator()*self.time30) #chanpy_state_str = 'resample_{}_chanpy_state'.format(self.get_ticker_indicator()*self.time5) shift_time = self.time30 - strength = 0.9 dataframe.loc[ ( #(dataframe['state']== "30") - (dataframe[state_str].shift(shift_time) == "101") + (dataframe[state_str].shift(shift_time) == "10") #(dataframe[fx_str].shift(shift_time) == 1) #(dataframe[chanpy_state_str].shift(shift_time+30) == -1) #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") & @@ -366,7 +361,7 @@ class ChanLun_BTC_30(IStrategy): dataframe.loc[ ( #(dataframe['state']== "30") - (dataframe[state_str].shift(shift_time) == "-101") + (dataframe[state_str].shift(shift_time) == "-10") #(dataframe[fx_str].shift(shift_time) == -1) #(dataframe[chanpy_state_str].shift(shift_time+30) == 1) #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") & diff --git a/web/app.py b/web/app.py index d832c86..d5a79d0 100644 --- a/web/app.py +++ b/web/app.py @@ -274,7 +274,9 @@ def add_indicators(df): df['bb_upper'] = bb['upperband'].fillna(0) df['bb_middle'] = bb['middleband'].fillna(0) df['bb_lower'] = bb['lowerband'].fillna(0) - + bb30 = ta.BBANDS(df, timeperiod=90, nbdevup=3.0, nbdevdn=3.0, matype=0) + df['bbup30'] = bb30['upperband'].fillna(0) + df['bblow30'] = bb30['lowerband'].fillna(0) # 计算次周期布林带 (14周期,2标准差) bb_element = ta.BBANDS(df, timeperiod=14, nbdevup=2.0, nbdevdn=2.0, matype=0) df['element_bb_upper'] = bb_element['upperband'].fillna(0) @@ -377,16 +379,16 @@ def analyze_chan(df): # 如果分型强度小于1,设为0 if fx_strength < 1: fx_strength = 0 - - klc_fx_info.append({ - 'time': klc.end_time, - 'price': klc.low if klc.fx == Chan_FX_TYPE.BOTTOM else klc.high, - 'fx_type': str(klc.klc_fx_type).replace("Chan_KLC_FX.", ""), - 'is_bottom': klc.fx == Chan_FX_TYPE.BOTTOM, - 'fx_strength': fx_strength, # 分型强度分数 (0-100) - 'fx_strength_level': fx_strength_level, # 分型强度等级 (极强/强/中等/弱/极弱) - 'is_strong_fx': is_strong_fx # 是否为强分型 - }) + if klc.bb_out: + klc_fx_info.append({ + 'time': klc.end_time, + 'price': klc.low if klc.fx == Chan_FX_TYPE.BOTTOM else klc.high, + 'fx_type': str(klc.klc_fx_type).replace("Chan_KLC_FX.", ""), + 'is_bottom': klc.fx == Chan_FX_TYPE.BOTTOM, + 'fx_strength': fx_strength, # 分型强度分数 (0-100) + 'fx_strength_level': fx_strength_level, # 分型强度等级 (极强/强/中等/弱/极弱) + 'is_strong_fx': is_strong_fx # 是否为强分型 + }) except Exception as e: # 如果出错,仍然添加基本信息,但分型强度为0 klc_fx_info.append({