diff --git a/ChanKLC.py b/ChanKLC.py index b5934f4..42b742c 100644 --- a/ChanKLC.py +++ b/ChanKLC.py @@ -32,7 +32,7 @@ class ChanKLC(): self.distance = 0 self.klc_fx_type = Chan_KLC_FX.UNKNOWN def set_klc_fx_type(self, klc_fx_type): - 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']) + #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']) if self.check_klc_fx_type(klc_fx_type): self.klc_fx_type = klc_fx_type def check_klc_fx_type(self, klc_fx_type): diff --git a/ChanLun_Classifier.py b/ChanLun_Classifier.py index e088d5b..4f44010 100644 --- a/ChanLun_Classifier.py +++ b/ChanLun_Classifier.py @@ -6,7 +6,7 @@ sys.path.append(os.path.abspath("/Users/jack/Project/freqtrade/user_data/Chan")) import numpy as np from datetime import timedelta from pandas import DataFrame -from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_SEG_DIR, Chan_ZS_DIR, Chan_BSP_DIR, Chan_BSP_TYPE +from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_SEG_DIR, Chan_ZS_DIR, Chan_BSP_DIR, Chan_BSP_TYPE, Chan_KLC_FX from ChanKLU import ChanKLU from ChanKLC import ChanKLC from ChanBI import ChanBI @@ -279,31 +279,24 @@ class ChanLunClassifier: :return: 特征矩阵X和标签y """ # 使用ChanLun获取bi_list - bi_list = self.chan.cal_bi_list(self.chan.get_klc_list(dataframe)) klc_list = self.chan.get_klc_list(dataframe) + bi_list = self.chan.cal_bi_list(klc_list) seg_list = self.chan.get_seg_list(bi_list) # 筛选方向为UP的bi的起始klc feature_data = [] labels = [] - bi_index = 0 + bi_index = 1 sample_list = [] for klc in klc_list: - if klc.pre and klc.next: - if klc.high > klc.pre.high and klc.high > klc.next.high: - klc.set_fx(Chan_FX_TYPE.TOP) - elif klc.low < klc.pre.low and klc.low < klc.next.low: - klc.set_fx(Chan_FX_TYPE.BOTTOM) - else: - klc.set_fx(Chan_FX_TYPE.UNKNOWN) - if klc.fx != Chan_FX_TYPE.UNKNOWN: + if klc.klc_fx_type != Chan_KLC_FX.UNKNOWN: sample_list.append(klc) for klc in sample_list: if bi_index >= len(bi_list): bi_index = len(bi_list) - 1 - bi = bi_list[bi_index] - if klc.end_klu and bi.end_klc and klc.start_klu.index >= bi.start_klc.start_klu.index and klc.end_klu.index <= bi.end_klc.end_klu.index: - klc.set_bi(bi) + #bi = bi_list[bi_index] + #if klc.end_klu and bi.end_klc and klc.start_klu.index >= bi.start_klc.start_klu.index and klc.end_klu.index <= bi.end_klc.end_klu.index: + #klc.set_bi(bi) # 提取特征 features = klc.get_feature_data() @@ -318,17 +311,21 @@ class ChanLunClassifier: # 判断这个bi是否赚钱(这里简单定义为:如果bi的结束价格高于起始价格,则标记为1,否则为0) # 这个标签定义可以根据实际需求修改 - bi = bi_list[bi_index] - if bi.start_klc.index == klc.index: - #if klc.index == seg.start_bi.start_klc.index and seg.dir == Chan_SEG_DIR.UP: - label = 1 - bi_index += 2 - else: + matched = False + for bi in bi_list: + if bi.end_klc and bi.end_klc.index == klc.index: + label = 1 + matched = True + break + if not matched: label = 0 feature_data.append(feature_vec) labels.append(label) - print("Trainning data: ", klc_list[-1].start_time, klc_list[-1].fx) + # 在return前添加 + positive_count = np.sum(labels) + print(f"正样本数量: {positive_count}, 负样本数量: {len(labels) - positive_count}") + print("Trainning data: ", len(feature_data), klc_list[-1].start_time, klc_list[-1].klc_fx_type , "---------------------") return np.array(feature_data), np.array(labels) def get_validate_feature_data(self, dataframe): """ @@ -337,23 +334,16 @@ class ChanLunClassifier: :return: 特征矩阵X和标签y """ # 使用ChanLun获取bi_list - bi_list = self.chan.cal_bi_list(self.chan.get_klc_list(dataframe)) klc_list = self.chan.get_klc_list(dataframe) + bi_list = self.chan.cal_bi_list(klc_list) seg_list = self.chan.get_seg_list(bi_list) # 筛选方向为UP的bi的起始klc feature_data = [] labels = [] - bi_index = 0 + bi_index = 1 sample_list = [] for klc in klc_list: - if klc.pre and klc.next: - if klc.high > klc.pre.high and klc.high > klc.next.high: - klc.set_fx(Chan_FX_TYPE.TOP) - elif klc.low < klc.pre.low and klc.low < klc.next.low: - klc.set_fx(Chan_FX_TYPE.BOTTOM) - else: - klc.set_fx(Chan_FX_TYPE.UNKNOWN) - if klc.fx != Chan_FX_TYPE.UNKNOWN: + if klc.klc_fx_type != Chan_KLC_FX.UNKNOWN: sample_list.append(klc) for klc in sample_list: if bi_index >= len(bi_list): @@ -371,16 +361,18 @@ class ChanLunClassifier: else: feature_vec.append(0) seg = seg_list[bi_index] - if bi.start_klc.index == klc.index: - #if klc.index == seg.start_bi.start_klc.index and seg.dir == Chan_SEG_DIR.UP: - label = 1 - bi_index += 2 - else: + matched = False + for bi in bi_list: + if bi.end_klc and bi.end_klc.index == klc.index: + label = 1 + matched = True + break + if not matched: label = 0 feature_data.append(feature_vec) labels.append(label) - + print("Validating data: ", len(feature_data), klc_list[-1].start_time, klc_list[-1].klc_fx_type , "---------------------") return np.array(feature_data), np.array(labels) def validate_model(self, dataframe=None): """ diff --git a/__pycache__/ChanKLC.cpython-312.pyc b/__pycache__/ChanKLC.cpython-312.pyc index 55ab417..1408a12 100644 Binary files a/__pycache__/ChanKLC.cpython-312.pyc and b/__pycache__/ChanKLC.cpython-312.pyc differ diff --git a/__pycache__/ChanLun.cpython-312.pyc b/__pycache__/ChanLun.cpython-312.pyc index 891bfbb..c1f8b8e 100644 Binary files a/__pycache__/ChanLun.cpython-312.pyc and b/__pycache__/ChanLun.cpython-312.pyc differ diff --git a/__pycache__/ChanLun_Classifier.cpython-312.pyc b/__pycache__/ChanLun_Classifier.cpython-312.pyc index e364a86..93f78e8 100644 Binary files a/__pycache__/ChanLun_Classifier.cpython-312.pyc and b/__pycache__/ChanLun_Classifier.cpython-312.pyc differ diff --git a/config/ChanLun_SOL.json b/config/ChanLun_SOL.json index 7aea049..73e9941 100644 --- a/config/ChanLun_SOL.json +++ b/config/ChanLun_SOL.json @@ -43,7 +43,7 @@ "ccxt_config": {}, "ccxt_async_config": {}, "pair_whitelist": [ - "BTC/USDT:USDT", + "SOL/USDT:USDT", ], "pair_blacklist": [ "BNB/.*" diff --git a/strategies/ChanLun_SOL_5.py b/strategies/ChanLun_SOL_5.py index d63b18c..546aa40 100644 --- a/strategies/ChanLun_SOL_5.py +++ b/strategies/ChanLun_SOL_5.py @@ -21,10 +21,10 @@ logger = logging.getLogger(__name__) ### Now you can use logger.info('asfd') to log # freqtrade plot-dataframe --strategy ChanLun_SOL_5 --datadir user_data/data/binance -c ./user_data/ChanLun_SOL.json --timerange=20250309- -# freqtrade trade -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL_5 --strategy-path ./user_data/strategies -# freqtrade backtesting -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL_5 --strategy-path ./user_data/strategies --timerange=20250416- -# freqtrade download-data -c ./user_data/ChanLun_SOL.json -t 1m --pairs SOL/USDT:USDT --timerange=20250405- -# freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces roi stoploss --strategy ChanLun_SOL_5 --strategy-path ./user_data/strategies -c ./user_data/ChanLun_SOL.json -e 200 --timerange=20250201-20250401 +# freqtrade trade -c ./user_data/Chan/config/ChanLun_SOL.json --strategy ChanLun_SOL_5 --strategy-path ./user_data/Chan/strategies +# freqtrade backtesting -c ./user_data/Chan/config/ChanLun_SOL.json --strategy ChanLun_SOL_5 --strategy-path ./user_data/Chan/strategies --timerange=20250416- +# freqtrade download-data -c ./user_data/Chan/config/ChanLun_SOL.json -t 1m --pairs SOL/USDT:USDT --timerange=20250405- +# freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces roi stoploss --strategy ChanLun_SOL_5 --strategy-path ./user _data/Chan/strategies -c ./user_data/Chan/config/ChanLun_SOL.json -e 200 --timerange=20250201-20250401 # sudo docker compose run --rm chan_btc backtesting -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL --strategy-path ./user_data/strategies --timerange=20250101- # sudo docker compose run --rm chan_btc download-data -c ./user_data/ChanLun_SOL.json --pairs SOL/USDT:USDT -t 1m --timerange 20240101- @@ -118,9 +118,9 @@ class ChanLun_SOL_5(IStrategy): self.classifier.train_model(dataframe_1d, model_name="1d_model") """ - """ + if self.classifier.model is None: - self.classifier.train_model(dataframe_30, model_name="30m_model") + #self.classifier.train_model(dataframe_30, model_name="30m_model") self.classifier.load_model(model_name="30m_model") klc_list = self.chan.get_klc_list(dataframe_30) top_avg = 0 @@ -129,12 +129,12 @@ class ChanLun_SOL_5(IStrategy): bottom_count = 0 for index in range(int(len(klc_list) * 0.8), len(klc_list)): klc = klc_list[index] - if self.classifier.predict(klc) > 0.01 and klc.fx == Chan_FX_TYPE.BOTTOM: + if self.classifier.predict(klc) > 0.45 and klc.fx == Chan_FX_TYPE.BOTTOM: features = klc.get_feature_data() print(klc.end_time, klc.fx, self.classifier.predict(klc), features['klc_macd'], features['klc_macd_hist'], features['klc_rsi'], features['klc_macd_signal']) bottom_avg += self.classifier.predict(klc) bottom_count += 1 - if self.classifier.predict(klc) > 0.05 and klc.fx == Chan_FX_TYPE.TOP: + if self.classifier.predict(klc) > 0.44 and klc.fx == Chan_FX_TYPE.TOP: features = klc.get_feature_data() print(klc.end_time, klc.fx, self.classifier.predict(klc), features['klc_macd'], features['klc_macd_hist'], features['klc_rsi'], features['klc_macd_signal']) top_avg += self.classifier.predict(klc) @@ -143,7 +143,7 @@ class ChanLun_SOL_5(IStrategy): top_avg /= top_count print(bottom_avg, top_avg) print("-------------------------------------------------------------------------------") - """ + """ self.print_xgb(dataframe, "1m_model") self.print_xgb(dataframe_5, "5m_model") @@ -163,11 +163,11 @@ class ChanLun_SOL_5(IStrategy): #dataframe_60['state'] = self.chan.cal_klu_state(dataframe_60) #dataframe_4h['state'] = self.chan.resample_klc_list(dataframe_4h) - self.chan.plot_dual(dataframe_30, dataframe_60) + #self.chan.plot_dual(dataframe_30, dataframe_60) 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) + #self.chan.get_bi_list(dataframe_30) if self.last_time + timedelta(minutes=1) < datetime.now(): #print(informative.iloc[-1]) #self.log_macd_div_list(dataframe)