From fb2104edf392787cbbd69a2ebb185b8337952be4 Mon Sep 17 00:00:00 2001 From: Porter Date: Sun, 25 May 2025 12:15:16 +0800 Subject: [PATCH] Add strength list to check the bsp --- ChanKLC.py | 2 +- ChanLun.py | 25 +++++ __pycache__/ChanKLC.cpython-312.pyc | Bin 72403 -> 72324 bytes __pycache__/ChanLun.cpython-312.pyc | Bin 110786 -> 112141 bytes config/ChanLun_SOL.json | 2 +- strategies/ChanLun_SOL_5.py | 165 ++++++---------------------- 6 files changed, 62 insertions(+), 132 deletions(-) diff --git a/ChanKLC.py b/ChanKLC.py index 35d88f4..98e3074 100644 --- a/ChanKLC.py +++ b/ChanKLC.py @@ -1200,7 +1200,7 @@ class ChanKLC(): # 分型质量调整 base_score += fx_quality - print(self.start_time, base_score, is_bi_end, post_fx_confirmation, 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)) diff --git a/ChanLun.py b/ChanLun.py index d5712d3..838f985 100644 --- a/ChanLun.py +++ b/ChanLun.py @@ -137,6 +137,31 @@ class ChanLun(): for index in range(0, len(dataframe)): state_list.append("00") return state_list + def get_klc_strength_list(self, dataframe): + klc_list = self.get_klc_list(dataframe) + bi_list = self.cal_bi_list(klc_list) + klc_strength_list = [] + klc_index = 0 + fx_list = [] + for index in range(0, len(dataframe)): + if klc_index == len(klc_list): + klc_index = len(klc_list) - 1 + klc = klc_list[klc_index] + if klc.end_klu and klc.end_klu.idx == index: + klc_index += 1 + if klc.klc_fx_type == Chan_KLC_FX.TOP1 or klc.klc_fx_type == Chan_KLC_FX.TOP2: + fx_list.append(1) + elif klc.klc_fx_type == Chan_KLC_FX.BOTTOM1 or klc.klc_fx_type == Chan_KLC_FX.BOTTOM2: + fx_list.append(-1) + else: + fx_list.append(0) + klc_strength_list.append(klc.cal_fx_strength()) + #if klc.klc_fx_type != Chan_KLC_FX.UNKNOWN and klc.cal_fx_strength() > 1: + #print(klc.start_time, klc.end_time, klc.cal_fx_strength(), klc.klc_fx_type, fx_list[-1], klc_strength_list[-1]) + else: + klc_strength_list.append(0) + fx_list.append(0) + return klc_strength_list, fx_list def get_all_state(self, df_list): state_list = [] for df in df_list: diff --git a/__pycache__/ChanKLC.cpython-312.pyc b/__pycache__/ChanKLC.cpython-312.pyc index 79c6bf665f8f94649b979dea528ff6f1bc7d6c04..34916fdf9c08521304089416110349c0b017250c 100644 GIT binary patch delta 77 zcmV-T0J8tnwFHE<1P#j#4GI7N0092qF=%|T4Mn;FSOJp}%o?+9x*h=pWCwH;v%Jlz_TfxbwS)4qEF$CFRLv<37A01y+i8^E|)JTe`L delta 134 zcmZqK%5r%t3-4)OUM>b8u%2L;QN5AZbr)mT diff --git a/__pycache__/ChanLun.cpython-312.pyc b/__pycache__/ChanLun.cpython-312.pyc index 550c702b4f34956cdb352e4074b1dd2694c13091..e5b56c4d89cfadbb8bfd3fec087f02e307bbe858 100644 GIT binary patch delta 4548 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 rX9SOEm-FYbd;tl^=zf^h0+!YczEH^E+A?g> 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 0.5 and (klc.klc_fx_type == Chan_KLC_FX.BOTTOM1 or klc.klc_fx_type == Chan_KLC_FX.BOTTOM2) and features['klc_rsi'] < 40: - print(klc.end_time, klc.fx, self.classifier.predict(klc), features['klc_volume_ratio'], features['klc_macdhist'], features['klc_rsi']) - bottom_avg += self.classifier.predict(klc) - bottom_count += 1 - if self.classifier.predict(klc) > 0.5 and (klc.klc_fx_type == Chan_KLC_FX.TOP1 or klc.klc_fx_type == Chan_KLC_FX.TOP2) and features['klc_rsi'] > 50: - print(klc.end_time, klc.fx, self.classifier.predict(klc), features['klc_volume_ratio'], features['klc_macdhist'], features['klc_rsi']) - top_avg += self.classifier.predict(klc) - top_count += 1 - if bottom_count > 0: - bottom_avg /= bottom_count - if top_count > 0: - top_avg /= top_count - print('Bottom:', bottom_avg, 'Top:', top_avg) - print("-------------------------------------------------------------------------------") - - """ - self.print_xgb(dataframe, "1m_model") - self.print_xgb(dataframe_5, "5m_model") - self.print_xgb(dataframe_30, "30m_model") - self.print_xgb(dataframe_60, "1h_model") - self.print_xgb(dataframe_4h, "4h_model") - print("-------------------------------------------------------------------------------") - """ - - - #classifier.train_model(use_cv=False) - #classifier.validate_model(dataframe) - #self.chan.get_bsp_list(dataframe) - #dataframe_5['state'] = self.chan.cal_klu_state(dataframe_5) - #dataframe_15['state'] = self.chan.cal_klu_state(dataframe_15) - #dataframe_30['state'] = self.chan.cal_klu_state(dataframe_30) - #dataframe_60['state'] = self.chan.cal_klu_state(dataframe_60) - #dataframe_4h['state'] = self.chan.resample_klc_list(dataframe_4h) - #self.print_bi_klc_fx(dataframe_60, "60m_model") #self.chan.plot_dual(dataframe_5, dataframe_30) dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) - #self.print_macd_div_list(dataframe) - #self.print_resample_df(dataframe, 1, 50) - #self.chan.get_bi_list(dataframe_30) - if self.last_time + timedelta(minutes=1) < datetime.now() and False: - #print(informative.iloc[-1]) - #self.print_klc(dataframe, "1m: ") - #self.print_klc(dataframe_5, "5m: ") - #self.print_klc(dataframe_30, "30m:") - #self.log_macd_div_list(dataframe) - self.print_xgb(dataframe, "1m_model") - self.print_xgb(dataframe_5, "5m_model") - self.print_xgb(dataframe_30, "30m_model") - self.print_xgb(dataframe_60, "60m_model") - self.print_xgb(dataframe_4h, "4h_model") - #self.print_xgb(dataframe_1d, "1d_model") + + state_list, fx_list = self.chan.get_klc_strength_list(dataframe_15) + dataframe_15['state'] = state_list + dataframe_15['fx'] = fx_list + klc_list = self.chan.get_klc_list(dataframe_15) + bi_list = self.chan.cal_bi_list(klc_list) + if self.last_time + timedelta(minutes=1) < datetime.now(): + print(state_list[-1], state_list[-2], state_list[-3], state_list[-4], state_list[-5]) + print(fx_list[-1], fx_list[-2], fx_list[-3], fx_list[-4], fx_list[-5]) + print(klc_list[-1].klc_fx_type, klc_list[-2].klc_fx_type, klc_list[-3].klc_fx_type, klc_list[-4].klc_fx_type, klc_list[-5].klc_fx_type) 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_bi_klc_fx(self, dataframe, model_name): @@ -284,7 +216,7 @@ class ChanLun_SOL_5(IStrategy): print(model_name, klc1.start_time, klc1.fx, self.classifier.predict(klc1)) print(model_name, klc2.end_time, klc2.fx, self.classifier.predict(klc2)) print(model_name, klc3.end_time, klc3.fx, self.classifier.predict(klc3)) - def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, + def custom_stake_amount1(self, pair: str, current_time: datetime, current_rate: float, proposed_stake: float, min_stake: float | None, max_stake: float, leverage: float, entry_tag: str | None, side: str, **kwargs) -> float: @@ -292,7 +224,7 @@ class ChanLun_SOL_5(IStrategy): # We need to leave most of the funds for possible further DCA orders # This also applies to fixed stakes return proposed_stake / self.max_dca_multiplier - def adjust_trade_position(self, trade: Trade, current_time: datetime, + def adjust_trade_position1(self, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, min_stake: float | None, max_stake: float, current_entry_rate: float, current_exit_rate: float, @@ -364,16 +296,16 @@ class ChanLun_SOL_5(IStrategy): stake_amount = stake_amount * (1 + (count_of_entries * 0.5)) dataframe_date = dataframe.iloc[-1]['date'] #print(stake_amount, "---------------------------------------------------") - if last_entry.order_filled_utc + timedelta(minutes=self.time5*6) < dataframe_date: - if dataframe.iloc[-self.time5]['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)] == "-10" and last_entry.side == "buy": + #if last_entry.order_filled_utc + timedelta(minutes=self.time5) < dataframe_date: + #if dataframe.iloc[-self.time5*2]['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)] > 1 and last_entry.side == "buy": + #print(dataframe.iloc[-self.time5*2]) + #print(stake_amount) + #return stake_amount, "1/3rd_increase" + #if last_entry.order_filled_utc + timedelta(minutes=self.time5*6) < dataframe_date: + #if dataframe.iloc[-self.time5*2]['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)] == "10" and last_entry.side == "sell": #print(dataframe.iloc[-self.time5]) #print(stake_amount) - return stake_amount, "1/3rd_increase" - if last_entry.order_filled_utc + timedelta(minutes=self.time5*6) < dataframe_date: - if dataframe.iloc[-self.time5]['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)] == "10" and last_entry.side == "sell": - #print(dataframe.iloc[-self.time5]) - #print(stake_amount) - return stake_amount, "1/3rd_increase" + #return stake_amount, "1/3rd_increase" return None def log_macd_div_list(self, dataframe): bi_macd_div_list, bi_list, seg_macd_div_list, seg_list = self.chan.get_macd_div_list(dataframe) @@ -472,58 +404,31 @@ class ChanLun_SOL_5(IStrategy): # (1,1) = 1, (1,0) = 2, (-1,1) = 3, (-1, 0) = 4, (0,0) = 0 def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: state_str = 'resample_{}_state'.format(self.get_ticker_indicator()*self.time5) - close_str = 'resample_{}_close'.format(self.get_ticker_indicator()*self.time5) - volume_str = 'resample_{}_volume'.format(self.get_ticker_indicator()*self.time5) + fx_str = 'resample_{}_fx'.format(self.get_ticker_indicator()*self.time5) dataframe.loc[ ( #(dataframe['state'] == "-30") - (dataframe[state_str].shift(self.time5) == "-10") & - (dataframe[close_str].pct_change().abs() < 0.05) & - (dataframe[close_str] > dataframe[close_str].shift(self.time5)) & - (dataframe[volume_str] > dataframe[volume_str].rolling(window=20).mean()) + (dataframe[state_str].shift(self.time5*2) > 1.0) & + (dataframe[fx_str].shift(self.time5*2) == -1) #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") & #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") & #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") #(qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) ), ['enter_long', 'enter_tag']] = (1, 'long_signal_chan') - dataframe.loc[ - ( - #(dataframe['state'] == "30") - (dataframe[state_str].shift(self.time5) == "10") & - (dataframe[close_str].pct_change().abs() < 0.05) & - (dataframe[close_str] < dataframe[close_str].shift(self.time5)) & - (dataframe[volume_str] > dataframe[volume_str].rolling(window=20).mean()) - #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "10") & - #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") & - #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "10") - #(qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) - ), - ['enter_short', 'enter_tag']] = (1, 'short_signal_chan') return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: state_str = 'resample_{}_state'.format(self.get_ticker_indicator()*self.time5) - close_str = 'resample_{}_close'.format(self.get_ticker_indicator()*self.time5) + fx_str = 'resample_{}_fx'.format(self.get_ticker_indicator()*self.time5) dataframe.loc[ ( #(dataframe['state']== "30") - (dataframe[state_str].shift(self.time5) == "10") | - (dataframe[close_str] < dataframe[close_str].rolling(window=20).min()) | - (dataframe[close_str] > dataframe[close_str].rolling(window=20).max()*1.05) + (dataframe[state_str].shift(self.time5*2) > 1.0) & + (dataframe[fx_str].shift(self.time5*2) == 1) #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") & #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "10") ), ['exit_long', 'exit_tag']] = (1, 'long_close_signal_chan') - dataframe.loc[ - ( - #(dataframe['state'] == "-30") - (dataframe[state_str].shift(self.time5) == "-10") | - (dataframe[close_str] > dataframe[close_str].rolling(window=20).max()) | - (dataframe[close_str] < dataframe[close_str].rolling(window=20).min()*0.95) - #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") & - #(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "-10") - ), - ['exit_short', 'exit_tag']] = (1, 'short_close_signal_chan') return dataframe def leverage(self, pair: str, current_time: datetime, current_rate: float, proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], side: str,