入场出场置信度根据市场状态动态调整

This commit is contained in:
zhangkun9038@dingtalk.com 2026-01-08 17:14:36 +08:00
parent c173c8277b
commit 182d5d8a65

View File

@ -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}")