优化熊市

This commit is contained in:
zhangkun9038@dingtalk.com 2025-06-07 02:59:31 +08:00
parent abf92b10e1
commit 018328efd1
4 changed files with 613 additions and 12 deletions

543
chat/result15.md Normal file
View File

@ -0,0 +1,543 @@
> 当前策略的config, freqai部分, 如何调整配置能提升策略表现
>
你当前的 FreqAI 配置已经非常完整,涵盖了数据预处理、特征工程、模型训练、异常检测等多个方面。
---
## ✅ 当前配置亮点
| 模块 | 说明 |
|------|------|
| 多时间帧特征 | `include_timeframes`: ["3m", "15m", "1h"] |
| 相关币种特征 | 使用 BTC/USDT 和 SOL/USDT 做相关性分析 |
| 标签周期 | `label_period_candles`: 24预测未来 24 根 K 线) |
| 特征选择 | 使用递归消除法recursive_elimination |
| 异常检测 | 使用 IsolationForest + SVM 过滤异常值 |
| 模型参数 | LightGBMRegressorn_estimators=400 |
---
## 🚀 如何优化 FreqAI 配置以提升策略表现?
以下是 **6 个关键优化方向**,每个都附有建议配置和理由:
---
### ✅ 1. **增加标签周期长度**
> 当前:`label_period_candles: 24`
#### 🔧 建议:
```json
"label_period_candles": 48
```
#### 📌 理由:
- 更长的标签周期可以让模型学习更远期的趋势
- 对于中长期趋势策略更有帮助
- 可结合 ROI 设置进行匹配
---
### ✅ 2. **使用 PCA 降维Principal Component Analysis**
> 当前:`principal_component_analysis`: false
#### 🔧 建议:
```json
"principal_component_analysis": true
```
#### 📌 理由:
- 减少冗余特征,提高模型泛化能力
- 对抗过拟合
- 尤其适用于多时间帧 + 多币种场景
---
### ✅ 3. **调整模型训练参数LightGBM**
> 当前:`n_estimators`: 400, `learning_rate`: 0.01
#### 🔧 建议:
```json
"model_training_parameters": {
"n_estimators": 600,
"learning_rate": 0.005,
"num_leaves": 40,
"max_depth": 10,
"min_data_in_leaf": 20,
"feature_fraction": 0.8,
"bagging_fraction": 0.8,
"bagging_freq": 5
}
```
#### 📌 理由:
- 更多迭代次数 + 更低学习率 = 更稳定收敛
- 增加叶子数和深度可以捕捉更复杂的模式
- 添加正则化项防止过拟合
---
### ✅ 4. **增加更多相关币种用于特征提取**
> 当前:`include_corr_pairlist`: ["BTC/USDT", "SOL/USDT"]
#### 🔧 建议:
```json
"include_corr_pairlist": ["BTC/USDT", "ETH/USDT", "SOL/USDT", "XRP/USDT"]
```
#### 📌 理由:
- 不同币种之间存在联动效应
- 增加更多主流币种可以增强市场状态识别能力
- 尤其在牛市或熊市中效果显著
---
### ✅ 5. **启用增量训练Incremental Training**
> 当前未启用
#### 🔧 建议:
```json
"incremental_train": true
```
#### 📌 理由:
- 在 live trading 中持续更新模型,而不是完全重训练
- 提高模型对最新市场的适应速度
- 减少 retrain 时间开销
---
### ✅ 6. **调整 outlier_protection_percentage**
> 当前:`outlier_protection_percentage`: 0.1
#### 🔧 建议:
```json
"outlier_protection_percentage": 0.15
```
#### 📌 理由:
- 市场波动剧烈时,适当放宽异常值过滤范围
- 防止误删极端行情下的有效信号
- 可结合 volatility_forecast 动态调整
---
## ✅ 推荐的优化后 FreqAI 配置(只展示修改部分)
```json
"freqai": {
"enabled": true,
"identifier": "test58",
"train_period_days": 7,
"backtest_period_days": 1,
"live_retrain_hours": 2,
"purge_old_models": 2,
"feature_parameters": {
"include_timeframes": ["3m", "15m", "1h"],
"include_corr_pairlist": ["BTC/USDT", "ETH/USDT", "SOL/USDT", "XRP/USDT"],
"label_period_candles": 48,
"include_shifted_candles": 3,
"DI_threshold": 0.7,
"weight_factor": 0.9,
"principal_component_analysis": true,
"use_SVM_to_remove_outliers": true,
"indicator_periods_candles": [10, 20, 50],
"plot_feature_importances": 10,
"outlier_protection_percentage": 0.15
},
"data_split_parameters": {
"test_size": 0.2,
"shuffle": false
},
"model_training_parameters": {
"n_estimators": 600,
"learning_rate": 0.005,
"num_leaves": 40,
"max_depth": 10,
"min_data_in_leaf": 20,
"feature_fraction": 0.8,
"bagging_fraction": 0.8,
"bagging_freq": 5,
"verbose": -1
},
"incremental_train": true
}
```
---
## ✅ 总结:推荐优化一览表
| 优化点 | 是否推荐 | 描述 |
|--------|----------|------|
| 增加 label_period_candles | ✅ 是 | 学习更远期趋势 |
| 启用 PCA 降维 | ✅ 是 | 减少冗余特征 |
| 调整 LightGBM 参数 | ✅ 是 | 提高模型性能 |
| 增加相关币种 | ✅ 是 | 增强市场感知 |
| 启用增量训练 | ✅ 是 | 提升实时适应性 |
| 放宽异常值过滤 | ✅ 是 | 避免误删极端行情 |
---
🎯 **下一步建议:**
你可以先尝试以下组合进行 backtest 测试:
```bash
freqtrade backtesting --strategy freqaiprimer --config config_examples/freqaiprimer.json --timerange 20240101-20250101 --freqaimodel LightGBMMultiTargetRegressor
```
如果你希望我帮你:
- 实现动态调整 label_period_candles
- 加入模型漂移检测
- 自动调整 outlier_protection_percentage
请告诉我你想优先实现哪个功能,我可以为你定制这部分逻辑。
------
- Datetime: 2025-06-07 02:11:35
- Model: _qwen3/qwen-plus-latest
- Selected files:
- result/backtest-result-2025-06-06_17-55-14.json
- result/analytic.log
- result/backtest-result-2025-06-06_17-55-14.meta.json
- result/backtest-result-2025-06-06_17-55-14_FreqaiPrimer.json
- result/backtest-result-2025-06-06_17-55-14_FreqaiPrimer.py
- result/backtest-result-2025-06-06_17-55-14_config.json
- result/backtest_trades.csv
- result/output.log
> 在下行行情下,这个策略会亏损严重, 请给分析原因和解决策略
你当前的策略在**下行行情中表现不佳,亏损严重**,这是一个非常典型的问题。我们来从多个角度分析原因,并提出针对性的优化建议。
---
## 📉 一、回测结果总结(关键数据)
| 指标 | 数值 | 说明 |
|------|------|------|
| 总交易数 | 10 | 少量交易但亏损集中 |
| 胜率 | 20% | 非常低,仅 2 赢5 输 |
| 平均盈利 | -1.96% | 所有交易平均亏损近 2% |
| 最大单笔亏损 | -5.15%TRUMP/USDT | 单笔最大亏损超过 5% |
| ROI 设置 | `{"0": 0.028, "12": 0.016, "48": 0.009, "120": 0}` | 初始目标为 2.8%,但未达成 |
| Trailing Stop 设置 | `trailing_stop_positive = 0.237` | 追踪止损偏高,可能无法及时止盈 |
---
## 🔍 二、亏损原因分析
### ✅ 1. **趋势判断滞后 + 止损设置不合理**
- 策略使用了 EMA200 和价格背离作为主要信号
- 在下行行情中:
- EMA200 反应慢,导致入场点位滞后
- 价格背离信号容易“假突破”,造成频繁误判
- 当前 trailing stop 设置为 `0.237`,但在下跌行情中根本无法触发,反而被提前止损
#### 📌 示例:
```json
"trailing_stop_positive": 0.237,
"trailing_stop_positive_offset": 0.318,
```
这意味着只有当价格反弹到比最低价高出 23.7% 才会开始追踪,这在下跌趋势中几乎不可能实现。
---
### ✅ 2. **模型预测偏差 + 动态阈值失效**
你的策略依赖 FreqAI 的 `&-price_value_divergence` 来判断买卖点,但在下行行情中:
- 模型输出的 `labels_mean``labels_std` 偏移较大
- 动态阈值计算逻辑过于简单,没有考虑市场状态变化
- 导致买入信号过早触发,卖出信号延迟或缺失
#### 📌 示例代码段:
```python
self.buy_threshold = labels_mean - k_buy * labels_std
self.sell_threshold = labels_mean + k_sell * labels_std
```
在下行行情中,`labels_mean` 下降,但 `k_buy * labels_std` 仍保持不变,导致买点不准确。
---
### ✅ 3. **缺乏空头保护机制**
你的策略是纯多头策略(`is_short: false`),但在下跌行情中:
- 没有做空机制
- 没有对冲手段
- 没有根据大盘走势动态调整仓位或暂停交易
#### 📌 回测日志显示:
```log
Market change: -6.96%
```
大盘整体下跌近 7%,而你的策略仍然坚持做多,导致系统性亏损。
---
### ✅ 4. **入场条件过于宽松**
你的入场条件包括:
```python
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold)
cond2 = (dataframe["volume_z_score"] > 1.5)
cond3 = (dataframe["rsi"] < 40)
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"])
buy_condition = cond1 & cond2 & cond3 & cond4
```
这些条件在下跌行情中很容易满足,尤其是 RSI < 40 close 在布林下轨以下容易形成抄底陷阱
---
### ✅ 5. **出场逻辑单一 + ROI 不灵活**
- ROI 设置为固定时间衰减曲线,但在下跌行情中需要更激进的止损
- trailing stop 设置过高,无法有效锁定利润
- sell_condition 中只有一个 RSI > 75 的条件,太弱
---
## 🚀 三、解决方案与优化建议
### ✅ 1. **加入大盘趋势过滤器Market Trend Filter**
你可以通过 BTC/USDT 或 ETH/USDT 的趋势来判断是否开启交易。
#### 🔧 修改 `populate_indicators()`
```python
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 获取 BTC/USDT 的趋势
btc_df = self.dp.get_pair_dataframe("BTC/USDT", self.timeframe)
dataframe["btc_ema200"] = ta.EMA(btc_df, timeperiod=200)
dataframe["btc_trend"] = (btc_df["close"] > dataframe["btc_ema200"]).astype(int)
# 如果 BTC 处于下降趋势,则禁止交易
if dataframe["btc_trend"].iloc[-1] == 0:
logger.info(f"[{metadata['pair']}] BTC 处于下降趋势,暂停交易")
dataframe["enter_long"] = 0
return dataframe
# 否则继续执行原有逻辑...
```
---
### ✅ 2. **动态调整 trailing stop 参数**
在下跌行情中,适当降低 trailing stop 的距离,提高退出速度。
#### 🔧 修改 `adjust_trade_position()`
```python
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float,
min_roi: Dict[float, float], max_profit: float):
hold_time = (current_time - trade.open_date_utc).total_seconds() / 60
if hold_time < 15:
return None
profit_ratio = (current_rate - trade.open_rate) / trade.open_rate
# 如果大盘处于下跌趋势,缩短 trailing stop 距离
market_trend = self.get_market_trend()
if market_trend == 'bear':
self.trailing_stop_distance = 0.005 # 更快退出
self.trailing_stop_start = 0.01
else:
self.trailing_stop_distance = 0.01
self.trailing_stop_start = 0.03
if profit_ratio >= self.trailing_stop_start and not self.trailing_stop_enabled:
self.trailing_stop_enabled = True
trade.adjust_max_rate(current_rate)
if self.trailing_stop_enabled:
max_rate = trade.max_rate
trailing_stop_price = max_rate * (1 - self.trailing_stop_distance)
if current_rate < trailing_stop_price:
return -1
trade.adjust_max_rate(current_rate)
if hold_time > 30:
return -1
return None
```
---
### ✅ 3. **优化入场条件:增加趋势确认机制**
避免在下跌趋势中盲目抄底。
#### 🔧 修改 `populate_entry_trend()`
```python
if "&-price_value_divergence" in dataframe.columns:
# 新增:只在价格高于短期均线时才允许入场
dataframe["ema20"] = ta.EMA(dataframe, timeperiod=20)
cond5 = (dataframe["close"] > dataframe["ema20"])
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold)
cond2 = (dataframe["volume_z_score"] > 1.5)
cond3 = (dataframe["rsi"] < 40)
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"])
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5
```
---
### ✅ 4. **动态调整 ROI 目标**
在下跌行情中ROI 应该更快衰减,甚至设为负值以强制止损。
#### 🔧 修改 `generate_roi_table()`
```python
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
market_trend = self.get_market_trend()
if market_trend == 'bear':
roi_table = {
"0": -0.01, # 强制止损
"5": 0.005, # 极端情况下微利退出
"15": 0.01,
"30": 0.015
}
else:
roi_table = {
"0": params.get("roi_t0", 0.02),
"30": params.get("roi_t1", 0.01),
"60": params.get("roi_t2", 0.0),
}
return roi_table
```
---
### ✅ 5. **加入大盘联动因子Pair Correlation**
你可以利用 BTC/USDT 的波动率来动态调整其他币种的止损幅度。
#### 🔧 示例逻辑:
```python
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# 获取 BTC 波动率
btc_df = self.dp.get_pair_dataframe("BTC/USDT", self.timeframe)
volatility = (btc_df["close"].pct_change(24)).abs().mean()
base_stop = -0.05 # 基础止损
adjusted_stop = base_stop * (1 + volatility * 2) # 波动越大,止损越紧
return max(adjusted_stop, -0.1) # 最大不超过 -10%
```
---
### ✅ 6. **加入“市场状态识别”模块**
你可以使用 RSI + ADX + Volatility 综合判断市场状态。
#### 🔧 示例逻辑:
```python
def get_market_trend(self, dataframe: DataFrame) -> str:
rsi = dataframe["rsi"].iloc[-1]
adx = dataframe["adx"].iloc[-1]
trend_strength = abs(dataframe["trend_strength"].iloc[-1])
if adx > 25 and trend_strength < -0.01:
return "bear"
elif adx > 25 and trend_strength > 0.01:
return "bull"
else:
return "sideways"
```
然后在 `populate_entry_trend()``custom_stoploss()` 中使用这个状态。
---
## ✅ 四、推荐配置修改config.json
```json
{
"stoploss": -0.1,
"minimal_roi": {
"0": -0.01,
"5": 0.005,
"15": 0.01,
"30": 0.015
},
"trailing_stop": true,
"trailing_stop_positive": 0.01,
"trailing_stop_positive_offset": 0.02,
"trailing_only_offset_is_reached": true
}
```
---
## ✅ 五、总结:亏损原因 & 对策一览表
| 问题 | 原因 | 解决方案 |
|------|------|----------|
| 趋势判断滞后 | 使用 EMA200 + price divergence | 加入 BTC 趋势过滤器 |
| 动态阈值失效 | 没有考虑市场状态 | 根据市场状态调整 buy/sell threshold |
| 止损设置不合理 | trailing_stop_positive 过高 | 动态调整 trailing stop |
| 入场条件宽松 | 容易抄底失败 | 加入 EMA20 过滤 |
| 缺乏空头保护 | 没有做空机制 | 加入大盘趋势过滤器 |
| ROI 设置不合理 | 固定衰减,未适应下跌行情 | 动态 ROI 表 |
| 模型漂移 | labels_mean/std 偏移 | 加入 Z-score 标准化 |
---
🎯 **下一步建议:**
你可以优先实现以下功能之一,我为你定制具体代码:
| 功能 | 推荐指数 | 描述 |
|------|----------|------|
| BTC 趋势过滤器 | ⭐⭐⭐⭐⭐ | 防止在熊市中盲目做多 |
| 动态 trailing stop | ⭐⭐⭐⭐ | 提高退出效率 |
| 动态 ROI 表 | ⭐⭐⭐⭐ | 自适应不同市场环境 |
| 市场状态识别 | ⭐⭐⭐ | 提升策略鲁棒性 |
| 模型漂移检测 | ⭐⭐⭐ | 防止模型退化 |
---
如果你希望我帮你实现其中某一个功能,请告诉我你想优先实现哪个功能,我可以为你生成完整代码。
------

View File

@ -81,15 +81,15 @@
"feature_parameters": {
"include_timeframes": [
"3m",
"15m",
"1h"
"1h",
"12h",
],
"include_corr_pairlist": [
"BTC/USDT",
"SOL/USDT"
],
"outlier_protection_percentage": 0.1,
"label_period_candles": 24,
"label_period_candles": 8,
"include_shifted_candles": 3,
"DI_threshold": 0.7,
"weight_factor": 0.9,

View File

@ -16,21 +16,21 @@
},
"protection": {},
"roi": {
"0": 0.167,
"24": 0.036000000000000004,
"55": 0.012,
"119": 0
"0": 0.028,
"12": 0.016,
"48": 0.009,
"120": 0
},
"stoploss": {
"stoploss": -0.057
"stoploss": -0.279
},
"trailing": {
"trailing_stop": true,
"trailing_stop_positive": 0.148,
"trailing_stop_positive_offset": 0.189,
"trailing_only_offset_is_reached": true
"trailing_stop_positive": 0.237,
"trailing_stop_positive_offset": 0.318,
"trailing_only_offset_is_reached": false
}
},
"ft_stratparam_v": 1,
"export_time": "2025-06-06 02:05:54.035420+00:00"
"export_time": "2025-06-06 14:26:19.180290+00:00"
}

View File

@ -390,6 +390,29 @@ class FreqaiPrimer(IStrategy):
return None
profit_ratio = (current_rate - trade.open_rate) / trade.open_rate
# 获取市场趋势并分别处理
market_trend = self.get_market_trend()
# 👇 分别处理 bull、bear、sideways 三种情况
if market_trend == 'bull':
# 牛市:放宽 trailing stop允许更多利润积累
self.trailing_stop_distance = 0.015
self.trailing_stop_start = 0.04
logger.debug(f"[{trade.pair}] 当前为牛市,设置 trailing_stop_distance={self.trailing_stop_distance}, start={self.trailing_stop_start}")
elif market_trend == 'bear':
# 熊市:收紧 trailing stop快速止盈
self.trailing_stop_distance = 0.005
self.trailing_stop_start = 0.01
logger.debug(f"[{trade.pair}] 当前为熊市,设置 trailing_stop_distance={self.trailing_stop_distance}, start={self.trailing_stop_start}")
elif market_trend == 'sideways':
# 震荡市:保持默认值
self.trailing_stop_distance = 0.01
self.trailing_stop_start = 0.03
logger.debug(f"[{trade.pair}] 当前为震荡市,使用默认 trailing_stop 参数")
if profit_ratio >= self.trailing_stop_start and not self.trailing_stop_enabled:
self.trailing_stop_enabled = True
trade.adjust_max_rate(current_rate)
@ -405,6 +428,7 @@ class FreqaiPrimer(IStrategy):
if hold_time > 30:
logger.info(f"[{trade.pair}] 持仓时间超过30分钟强制平仓")
return -1
return None
@ -455,3 +479,37 @@ class FreqaiPrimer(IStrategy):
adjusted_rate = proposed_rate * (1 + 0.0025)
logger.debug(f"[{pair}] 自定义卖出价:{adjusted_rate:.6f}(原价:{proposed_rate:.6f}")
return adjusted_rate
def get_market_trend(self, dataframe: DataFrame = None) -> str:
"""
使用 BTC/USDT EMA200 判断大盘趋势
返回值: 'bull'牛市'bear'熊市'sideways'震荡
"""
try:
# 获取 BTC/USDT 的数据
btc_df = self.dp.get_pair_dataframe("BTC/USDT", self.timeframe)
if len(btc_df) < 200:
logger.warning("BTC 数据不足返回默认趋势sideways")
return "sideways"
# 计算 EMA200
btc_df["ema200"] = ta.EMA(btc_df, timeperiod=200)
# 当前价格与 EMA200 的关系
price_above_ema = (btc_df["close"].iloc[-1] > btc_df["ema200"].iloc[-1])
# 近期趋势强度(过去 50 根 K 线的平均涨跌幅)
trend_strength = btc_df["close"].pct_change(50).iloc[-1]
# 判断市场状态
if price_above_ema and trend_strength > 0.03:
return "bull"
elif not price_above_ema and trend_strength < -0.03:
return "bear"
else:
return "sideways"
except Exception as e:
logger.error(f"获取市场趋势失败:{e}", exc_info=True)
return "sideways"