diff --git a/config_freqai_primer.json b/config_freqai_primer.json index 3d7dc5b3..5166d02b 100644 --- a/config_freqai_primer.json +++ b/config_freqai_primer.json @@ -57,14 +57,28 @@ "enabled": true, "identifier": "freqai_primer_mixed", "model": "LightGBMRegressor", + "purge_old_models": 2, + "train_period_days": 15, + "backtest_period_days": 3, "feature_parameters": { "include_timeframes": ["3m", "15m", "1h"], "include_shifted_candles": 2, - "label_period_candles": 12 + "label_period_candles": 12, + "include_corr_pairlist": [], + "DI_threshold": 0.9, + "weight_factor": 0.9, + "principal_component_analysis": false, + "use_SVM_to_remove_outliers": true, + "svm_params": { + "shuffle": false, + "nu": 0.1 + }, + "use_DBSCAN_to_remove_outliers": false }, "data_split_parameters": { - "test_size": 0.2, - "shuffle": false + "test_size": 0.25, + "shuffle": false, + "random_state": 1 }, "model_training_parameters": { "price_value_divergence": { diff --git a/docs/更新.md b/docs/更新.md new file mode 100644 index 00000000..5d5e5d09 --- /dev/null +++ b/docs/更新.md @@ -0,0 +1,42 @@ +# FreqAI Primer 策略更新日志 + +## 2025-12-23: ML 审核官逻辑优化 + +### 核心变更 +将 ML 审核官(exit_signal 置信度判断)从 **入场过滤** 改为 **出场过滤**,实现更激进的持仓策略。 + +### 具体改动 + +#### 1. 移除入场阶段的 ML 审核官 +- **旧逻辑**:在 `confirm_trade_entry` 中,若 `exit_signal` 概率高(容易下跌),则拒绝入场 +- **问题**:这会错过很多有效入场机会,因为短期波动不代表整体趋势 + +#### 2. 新增出场阶段的 ML 审核官 +- **新逻辑**:在 `confirm_trade_exit` 中,只有当 `exit_signal` 概率 **>=** 阈值时才允许出场 +- **效果**: + - 防止止盈过早,让利润充分增长 + - 在 AI 判断上涨概率高时强制继续持仓 + - 只在 AI 确认下跌信号强烈时才出场 + +#### 3. 参数说明 +- 使用现有 hyperopt 参数:`ml_exit_signal_threshold`(默认 0.65) +- **入场时**(已移除):exit_prob > 0.65 拒绝入场 +- **出场时**(新增):exit_prob < 0.65 拒绝出场(继续持仓) + +### 设计理念 +符合"让利润奔跑,截断亏损"的交易哲学: +- 入场:依赖传统技术指标,保证信号充足 +- 出场:由 AI 审核,确保真正的趋势反转才离场 + +### 日志输出 +``` +[BTC/USDT] ML 审核官拒绝出场: exit_signal 概率 0.35 < 阈值 0.65(上涨概率高,继续持仓), 出场原因: roi +[ETH/USDT] ML 审核官允许出场: exit_signal 概率 0.78 >= 阈值 0.65, 出场原因: sell_signal +``` + +--- + +## 使用建议 +1. 回测时观察是否会导致持仓时间过长 +2. 如果发现过度持仓,可以降低 `ml_exit_signal_threshold` 阈值(如 0.55) +3. 如果出场过于频繁,可以提高阈值(如 0.75) \ No newline at end of file diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index ee40c324..f274da85 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -743,39 +743,7 @@ class FreqaiPrimer(IStrategy): #logger.info(f"[{pair}] 由于检测到剧烈拉升,取消入场交易") allow_trade = False - # 检查3:ML 审核官(FreqAI 过滤低质量入场) - # 逻辑:用 exit_signal 概率来判断——若"退出概率高"说明价格容易跌,则拒绝入场 - if allow_trade: - try: - df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) - if len(df) > 0: - last_row = df.iloc[-1] - exit_prob = None - - # 优先使用 FreqAI 的 exit_signal 预测列(例如 &-exit_signal_prob 或 &-exit_signal) - if '&-exit_signal_prob' in df.columns: - exit_prob = float(last_row['&-exit_signal_prob']) - elif '&-s-exit_signal_prob' in df.columns: - exit_prob = float(last_row['&-s-exit_signal_prob']) - elif '&-exit_signal' in df.columns: - val = last_row['&-exit_signal'] - if isinstance(val, (int, float)): - exit_prob = float(val) - else: - # 文本标签时,简单映射为 0/1 - exit_prob = 1.0 if str(val).lower() in ['exit', 'sell', '1'] else 0.0 - - if exit_prob is not None: - # 阈值:如果"应该退出"的概率 > 阈值,说明价格很可能下跌,拒绝入场 - # 使用 hyperopt 参数,默认 0.65(比之前的 0.5 更宽松) - exit_threshold = self.ml_exit_signal_threshold.value - if exit_prob > exit_threshold: - logger.info(f"[{pair}] ML 审核官拒绝入场: exit_signal 概率 {exit_prob:.2f} > 阈值 {exit_threshold:.2f}(容易下跌,不宜入场)") - allow_trade = False - # else: - # logger.info(f"[{pair}] ML 审核官允许入场: exit_signal 概率 {exit_prob:.2f} <= {exit_threshold:.2f}") - except Exception as e: - logger.warning(f"[{pair}] ML 审核官检查失败,忽略 ML 过滤: {e}") + # 注:ML 审核官逻辑已移动到 confirm_trade_exit 中,用于过滤出场 # 如果允许交易,更新最后一次入场时间并输出价格信息 if allow_trade: @@ -788,6 +756,58 @@ class FreqaiPrimer(IStrategy): # 如果没有阻止因素,允许交易 return allow_trade + + def confirm_trade_exit( + self, + pair: str, + trade: 'Trade', + order_type: str, + amount: float, + rate: float, + time_in_force: str, + exit_reason: str, + current_time: datetime, + **kwargs, + ) -> bool: + """ + 交易卖出前的确认函数,用于最终决定是否执行出场 + 此处使用 ML 审核官(exit_signal 置信度)过滤出场 + """ + # 默认允许出场 + allow_exit = True + + try: + df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) + if len(df) > 0: + last_row = df.iloc[-1] + exit_prob = None + + # 优先使用 FreqAI 的 exit_signal 预测列 + if '&-exit_signal_prob' in df.columns: + exit_prob = float(last_row['&-exit_signal_prob']) + elif '&-s-exit_signal_prob' in df.columns: + exit_prob = float(last_row['&-s-exit_signal_prob']) + elif '&-exit_signal' in df.columns: + val = last_row['&-exit_signal'] + if isinstance(val, (int, float)): + exit_prob = float(val) + else: + # 文本标签时,简单映射为 0/1 + exit_prob = 1.0 if str(val).lower() in ['exit', 'sell', '1'] else 0.0 + + if exit_prob is not None: + # ML 审核官逻辑:只有当 exit_signal 概率足够高时才允许出场 + # 使用 hyperopt 参数,默认 0.65 + exit_threshold = self.ml_exit_signal_threshold.value + if exit_prob < exit_threshold: + logger.info(f"[{pair}] ML 审核官拒绝出场: exit_signal 概率 {exit_prob:.2f} < 阈值 {exit_threshold:.2f}(上涨概率高,继续持仓), 出场原因: {exit_reason}") + allow_exit = False + else: + logger.info(f"[{pair}] ML 审核官允许出场: exit_signal 概率 {exit_prob:.2f} >= 阈值 {exit_threshold:.2f}, 出场原因: {exit_reason}") + except Exception as e: + logger.warning(f"[{pair}] ML 审核官出场检查失败,允许出场: {e}") + + return allow_exit def custom_stoploss(self, pair: str, trade: 'Trade', current_time, current_rate: float, current_profit: float, **kwargs) -> float: