From 497ff3813302ce52526736915d98e9bce5edc6c1 Mon Sep 17 00:00:00 2001 From: "zhangkun9038@dingtalk.com" Date: Fri, 15 Aug 2025 13:25:54 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=80=E5=87=BA=E6=9D=A1=E4=BB=B6=E9=98=88?= =?UTF-8?q?=E5=80=BC=E7=94=A8hyperopt=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + freqtrade/templates/freqaiprimer.py | 100 ++++++++++++++++++++++------ 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 39abf1aa..d0f76970 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,4 @@ data/ tools/.env output.log result/ +user_data.tar.gz diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index 8856e15b..492c3967 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -48,6 +48,37 @@ class FreqaiPrimer(IStrategy): # Hyperopt 可优化参数 trend_final_bullish_threshold = IntParameter(40, 90, default=55, space="buy", optimize=True, load=True) trend_final_bearish_threshold = IntParameter(10, 40, default=13, space="buy", optimize=True, load=True) + + # 出场策略相关参数 + exit_divergence_multiplier = DecimalParameter(1.0, 1.3, default=1.06, space="sell", optimize=True, load=True) + exit_adx_threshold = IntParameter(15, 35, default=20, space="sell", optimize=True, load=True) + exit_rsi_threshold = IntParameter(55, 75, default=65, space="sell", optimize=True, load=True) + exit_stochrsi_threshold = IntParameter(60, 80, default=70, space="sell", optimize=True, load=True) + exit_adx_threshold_overbought = IntParameter(20, 35, default=25, space="sell", optimize=True, load=True) + exit_min_profit_threshold = DecimalParameter(0.005, 0.05, default=0.02, space="sell", optimize=True, load=True) + exit_rapid_rise_bull = DecimalParameter(1.5, 4.0, default=2.0, space="sell", optimize=True, load=True) + exit_rapid_rise_bear = DecimalParameter(2.5, 5.0, default=3.5, space="sell", optimize=True, load=True) + exit_stochrsi_rapid = IntParameter(65, 85, default=70, space="sell", optimize=True, load=True) + exit_volume_threshold = DecimalParameter(0.5, 2.0, default=1.0, space="sell", optimize=True, load=True) + + # 趋势状态相关出场参数 + exit_bullish_trend_score_max = IntParameter(90, 98, default=95, space="sell", optimize=True, load=True) + exit_bullish_divergence_mult = DecimalParameter(1.1, 1.3, default=1.15, space="sell", optimize=True, load=True) + exit_bullish_rsi = IntParameter(70, 85, default=75, space="sell", optimize=True, load=True) + exit_bullish_stochrsi = IntParameter(80, 90, default=85, space="sell", optimize=True, load=True) + exit_bullish_adx = IntParameter(25, 40, default=30, space="sell", optimize=True, load=True) + exit_bullish_return = DecimalParameter(3.0, 7.0, default=5.0, space="sell", optimize=True, load=True) + exit_bullish_stochrsi_rapid = IntParameter(80, 90, default=85, space="sell", optimize=True, load=True) + + exit_bearish_divergence_mult = DecimalParameter(0.8, 1.0, default=0.9, space="sell", optimize=True, load=True) + exit_bearish_rsi = IntParameter(55, 65, default=60, space="sell", optimize=True, load=True) + exit_bearish_stochrsi = IntParameter(65, 75, default=70, space="sell", optimize=True, load=True) + exit_bearish_adx = IntParameter(15, 25, default=20, space="sell", optimize=True, load=True) + exit_bearish_return = DecimalParameter(1.0, 3.0, default=1.5, space="sell", optimize=True, load=True) + exit_bearish_stochrsi_rapid = IntParameter(70, 85, default=75, space="sell", optimize=True, load=True) + + exit_ranging_trend_score_max = IntParameter(95, 99, default=98, space="sell", optimize=True, load=True) + exit_ranging_trend_score_threshold = IntParameter(80, 90, default=85, space="sell", optimize=True, load=True) # --- 🛠️ 固定配置参数 --- stoploss = -0.15 @@ -601,26 +632,26 @@ class FreqaiPrimer(IStrategy): # 条件 1:高阈值 &-price_value_divergence cond1 = ( - (dataframe["&-price_value_divergence"] > self.sell_threshold * 1.06) & # 提高到 1.06 - (dataframe["adx"] > 20) # 趋势强度过滤 + (dataframe["&-price_value_divergence"] > self.sell_threshold * self.exit_divergence_multiplier) & + (dataframe["adx"] > self.exit_adx_threshold) # 趋势强度过滤 ) # 条件 2:超买信号 cond2 = ( - (dataframe["rsi"] > 65) & - (dataframe["stochrsi_k"] > 70) & # StochRSI 超买 - (dataframe["adx"] > 25) # 趋势强度 + (dataframe["rsi"] > self.exit_rsi_threshold) & + (dataframe["stochrsi_k"] > self.exit_stochrsi_threshold) & # StochRSI 超买 + (dataframe["adx"] > self.exit_adx_threshold_overbought) # 趋势强度 ) # 条件 3:快速拉升退出 - # 检测最近 5 根 K 线(约 15 分钟)涨幅超过 3%,且有最低 2% 利润,结合 StochRSI 超买 - min_profit = 0.02 # 最低利润 2% - rapid_rise_threshold = self.linear_map(trend_score, 0, 100, 3.5, 2) # 熊市 4%,牛市 2.5% + # 检测最近 5 根 K 线(约 15 分钟)涨幅超过阈值,且有最低利润要求 + min_profit = self.exit_min_profit_threshold # 最低利润要求 + rapid_rise_threshold = self.linear_map(trend_score, 0, 100, self.exit_rapid_rise_bear, self.exit_rapid_rise_bull) cond3 = ( (dataframe["short_term_return"] > rapid_rise_threshold) & # 短期快速拉升 (dataframe["close"] / dataframe["close"].shift(5) - 1 > min_profit) & # 确保最低利润 - (dataframe["stochrsi_k"] > 70) & # 超买确认 - (dataframe["volume_z_score"] > 1.0) + (dataframe["stochrsi_k"] > self.exit_stochrsi_rapid) & # 超买确认 + (dataframe["volume_z_score"] > self.exit_volume_threshold) ) # 检测趋势状态 @@ -629,36 +660,34 @@ class FreqaiPrimer(IStrategy): # 根据趋势状态调整出场策略 if trend_status == "bullish": # 上涨趋势:严格出场条件,让利润奔跑 - if trend_score > 95: + if trend_score > self.exit_bullish_trend_score_max: logger.info(f"[{pair}] 🚀 强劲上涨趋势,拒绝卖出") return dataframe # 上涨趋势下需要更强的卖出信号 - bullish_sell_threshold = 90 - cond1_bullish = (dataframe["&-price_value_divergence"] > self.sell_threshold * 1.15) # 更严格的阈值 - cond2_bullish = (dataframe["rsi"] > 75) & (dataframe["stochrsi_k"] > 85) & (dataframe["adx"] > 30) - cond3_bullish = (dataframe["short_term_return"] > 5.0) & (dataframe["stochrsi_k"] > 85) # 更高的涨幅要求 + cond1_bullish = (dataframe["&-price_value_divergence"] > self.sell_threshold * self.exit_bullish_divergence_mult) + cond2_bullish = (dataframe["rsi"] > self.exit_bullish_rsi) & (dataframe["stochrsi_k"] > self.exit_bullish_stochrsi) & (dataframe["adx"] > self.exit_bullish_adx) + cond3_bullish = (dataframe["short_term_return"] > self.exit_bullish_return) & (dataframe["stochrsi_k"] > self.exit_bullish_stochrsi_rapid) sell_condition = (cond1_bullish & cond2_bullish) | (cond1_bullish & cond3_bullish) | (cond2_bullish & cond3_bullish) logger.info(f"[{pair}] 🚀 上涨趋势策略:严格出场条件") elif trend_status == "bearish": # 下跌趋势:宽松出场条件,快速止盈止损 - cond1_bearish = (dataframe["&-price_value_divergence"] > self.sell_threshold * 0.9) # 更宽松的阈值 - cond2_bearish = (dataframe["rsi"] > 60) & (dataframe["stochrsi_k"] > 70) & (dataframe["adx"] > 20) - cond3_bearish = (dataframe["short_term_return"] > 1.5) & (dataframe["stochrsi_k"] > 75) # 较低的涨幅要求 + cond1_bearish = (dataframe["&-price_value_divergence"] > self.sell_threshold * self.exit_bearish_divergence_mult) + cond2_bearish = (dataframe["rsi"] > self.exit_bearish_rsi) & (dataframe["stochrsi_k"] > self.exit_bearish_stochrsi) & (dataframe["adx"] > self.exit_bearish_adx) + cond3_bearish = (dataframe["short_term_return"] > self.exit_bearish_return) & (dataframe["stochrsi_k"] > self.exit_bearish_stochrsi_rapid) sell_condition = cond1_bearish | cond2_bearish | cond3_bearish # 任一条件即可卖出 logger.info(f"[{pair}] 📉 下跌趋势策略:宽松出场条件") else: # ranging # 震荡趋势:使用原策略 - if trend_score > 98: + if trend_score > self.exit_ranging_trend_score_max: logger.info(f"[{pair}] ⚖️ 震荡趋势但得分较高,拒绝卖出") return dataframe - trend_sell_threshold = 85 - if trend_score > trend_sell_threshold: + if trend_score > self.exit_ranging_trend_score_threshold: sell_condition = (cond1 & cond2) | (cond1 & cond3) | (cond2 & cond3) # 中等趋势,至少两个条件满足 logger.info(f"[{pair}] ⚖️ 震荡趋势策略:标准出场条件") else: @@ -702,7 +731,34 @@ class FreqaiPrimer(IStrategy): return [ DecimalParameter(0.001, 0.02, name="sell_threshold_min"), DecimalParameter(0.02, 0.1, name="sell_threshold_max"), - DecimalParameter(0.2, 0.7, name="exit_position_ratio", default=0.5) + DecimalParameter(0.2, 0.7, name="exit_position_ratio", default=0.5), + # 出场策略参数 + DecimalParameter(1.0, 1.3, name="exit_divergence_multiplier"), + IntParameter(15, 35, name="exit_adx_threshold"), + IntParameter(55, 75, name="exit_rsi_threshold"), + IntParameter(60, 80, name="exit_stochrsi_threshold"), + IntParameter(20, 35, name="exit_adx_threshold_overbought"), + DecimalParameter(0.005, 0.05, name="exit_min_profit_threshold"), + DecimalParameter(1.5, 4.0, name="exit_rapid_rise_bull"), + DecimalParameter(2.5, 5.0, name="exit_rapid_rise_bear"), + IntParameter(65, 85, name="exit_stochrsi_rapid"), + DecimalParameter(0.5, 2.0, name="exit_volume_threshold"), + # 趋势状态相关出场参数 + IntParameter(90, 98, name="exit_bullish_trend_score_max"), + DecimalParameter(1.1, 1.3, name="exit_bullish_divergence_mult"), + IntParameter(70, 85, name="exit_bullish_rsi"), + IntParameter(80, 90, name="exit_bullish_stochrsi"), + IntParameter(25, 40, name="exit_bullish_adx"), + DecimalParameter(3.0, 7.0, name="exit_bullish_return"), + IntParameter(80, 90, name="exit_bullish_stochrsi_rapid"), + IntParameter(95, 99, name="exit_ranging_trend_score_max"), + IntParameter(80, 90, name="exit_ranging_trend_score_threshold"), + DecimalParameter(0.8, 1.0, name="exit_bearish_divergence_mult"), + IntParameter(55, 65, name="exit_bearish_rsi"), + IntParameter(65, 75, name="exit_bearish_stochrsi"), + IntParameter(15, 25, name="exit_bearish_adx"), + DecimalParameter(1.0, 3.0, name="exit_bearish_return"), + IntParameter(70, 85, name="exit_bearish_stochrsi_rapid") ] def adjust_trade_position(self, trade: Trade, current_time: datetime,