出场置信度

This commit is contained in:
zhangkun9038@dingtalk.com 2025-12-23 11:07:50 +08:00
parent 9c77455e1b
commit beea456d0f
3 changed files with 112 additions and 36 deletions

View File

@ -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": {

42
docs/更新.md Normal file
View File

@ -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

View File

@ -743,39 +743,7 @@ class FreqaiPrimer(IStrategy):
#logger.info(f"[{pair}] 由于检测到剧烈拉升,取消入场交易")
allow_trade = False
# 检查3ML 审核官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: