From 182d5d8a65c3019b54d93ec624cd6725a63e47d2 Mon Sep 17 00:00:00 2001 From: "zhangkun9038@dingtalk.com" Date: Thu, 8 Jan 2026 17:14:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E5=9C=BA=E5=87=BA=E5=9C=BA=E7=BD=AE?= =?UTF-8?q?=E4=BF=A1=E5=BA=A6=E6=A0=B9=E6=8D=AE=E5=B8=82=E5=9C=BA=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8A=A8=E6=80=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- freqtrade/templates/freqaiprimer.py | 49 +++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index 75c697a1..18d26e08 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -227,11 +227,9 @@ class FreqaiPrimer(IStrategy): # 入场间隔控制参数(分钟) entry_interval_minutes = IntParameter(20, 200, default=42, optimize=True, load=True, space='buy') - # ML 审核官:entry_signal 拒绝入场的阈值(越高越宽松,越低越严格) - ml_entry_signal_threshold = DecimalParameter(0.05, 0.85, decimals=2, default=0.78, optimize=True, load=True, space='buy') - - # ML 审核官:exit_signal 拒绝出场的阈值(越高越宽松,越低越严格) - ml_exit_signal_threshold = DecimalParameter(0.05, 0.85, decimals=2, default=0.68, optimize=True, load=True, space='buy') + # ML 审核官阈值已改为根据市场状态动态调整,不再使用固定参数 + # strong_bull: 入场0.15/出场0.85, weak_bull: 0.325/0.675, neutral: 0.50/0.50 + # weak_bear: 0.675/0.325, strong_bear: 0.85/0.15 # FreqAI 标签定义:entry_signal 的洛底上涨幅度(%) freqai_entry_up_percent = DecimalParameter(0.3, 2.0, decimals=2, default=0.5, optimize=True, load=True, space='buy') @@ -809,6 +807,31 @@ class FreqaiPrimer(IStrategy): except Exception as e: logger.error(f"[{pair}] 剧烈拉升检测过程中发生错误: {str(e)}") return False + + def get_ml_threshold_by_market_state(self, market_state: str, threshold_type: str = 'entry') -> float: + """ + 根据市场状态动态获取 ML 审核官阈值 + + Args: + market_state: 市场状态 (strong_bull, weak_bull, neutral, weak_bear, strong_bear) + threshold_type: 阈值类型 ('entry' 或 'exit') + + Returns: + float: 动态计算的阈值 + """ + # 市场状态到阈值的映射 + thresholds_map = { + 'strong_bull': {'entry': 0.15, 'exit': 0.85}, + 'weak_bull': {'entry': 0.325, 'exit': 0.675}, + 'neutral': {'entry': 0.50, 'exit': 0.50}, + 'weak_bear': {'entry': 0.675, 'exit': 0.325}, + 'strong_bear': {'entry': 0.85, 'exit': 0.15} + } + + # 默认值(如果市场状态未知) + default_threshold = 0.50 + + return thresholds_map.get(market_state, {}).get(threshold_type, default_threshold) def confirm_trade_entry( self, @@ -916,12 +939,13 @@ class FreqaiPrimer(IStrategy): if entry_prob is not None: # 确保概率在 [0, 1] 范围内(分类器输出可能有浮点误差) entry_prob = max(0.0, min(1.0, entry_prob)) - entry_threshold = self.ml_entry_signal_threshold.value + # 根据市场状态动态获取入场阈值 + entry_threshold = self.get_ml_threshold_by_market_state(market_state, 'entry') if entry_prob < entry_threshold: - self.strategy_log(f"[{pair}] ML 审核官拒绝入场: entry_signal 概率 {entry_prob:.2f} < 阈值 {entry_threshold:.2f}(上涨概率低,不宜入场)") + self.strategy_log(f"[{pair}] ML 审核官拒绝入场: entry_signal 概率 {entry_prob:.2f} < 阈值 {entry_threshold:.2f}(市场: {market_state})") allow_trade = False else: - self.strategy_log(f"[{pair}] ML 审核官允许入场: entry_signal 概率 {entry_prob:.2f} >= 阈值 {entry_threshold:.2f}") + self.strategy_log(f"[{pair}] ML 审核官允许入场: entry_signal 概率 {entry_prob:.2f} >= 阈值 {entry_threshold:.2f}(市场: {market_state})") except Exception as e: logger.warning(f"[{pair}] ML 审核官检查失败,忽略 ML 过滤: {e}") return allow_trade @@ -989,9 +1013,12 @@ class FreqaiPrimer(IStrategy): # 从 kwargs 获取当前利润,freqtrade 会传入 current_profit current_profit = float(kwargs.get('current_profit', 0.0)) + + # 获取市场状态 + market_state = str(last_row.get('market_state', 'neutral')) - # 获取出场一字基础阈值 - base_threshold = self.ml_exit_signal_threshold.value + # 根据市场状态动态获取出场阈值 + base_threshold = self.get_ml_threshold_by_market_state(market_state, 'exit') # 计算持仓时长(分钟) try: @@ -1041,6 +1068,7 @@ class FreqaiPrimer(IStrategy): f"[{pair}] ML 审核官拒绝出场: exit_signal 概率 {exit_prob:.2f} < 动态阈值 {dynamic_threshold:.2f}" f" | 原应出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}" f" | 波动率AI: {future_vol_signal if future_vol_signal is not None else 'N/A'}" + f" | 市场: {market_state}" ) allow_exit = False else: @@ -1048,6 +1076,7 @@ class FreqaiPrimer(IStrategy): f"[{pair}] ML 审核官允许出场: exit_signal 概率 {exit_prob:.2f} >= 动态阈值 {dynamic_threshold:.2f}" f" | 出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}" f" | 波动率AI: {future_vol_signal if future_vol_signal is not None else 'N/A'}" + f" | 市场: {market_state}" ) except Exception as e: logger.warning(f"[{pair}] ML 审核官出场检查失败,允许出场: {e}")