709 lines
23 KiB
Markdown
709 lines
23 KiB
Markdown
- Datetime: 2025-06-03 02:21:39
|
||
|
||
- Model: _qwen3/qwen-plus-latest
|
||
|
||
- Selected files:
|
||
- result/backtest-result-2025-06-03_01-41-33_FreqaiPrimer.py
|
||
- result/analytic.log
|
||
- result/backtest-result-2025-06-03_01-41-33.json
|
||
- result/backtest-result-2025-06-03_01-41-33.meta.json
|
||
- result/backtest-result-2025-06-03_01-41-33_FreqaiPrimer.json
|
||
- result/backtest-result-2025-06-03_01-41-33_config.json
|
||
- result/backtest_trades.csv
|
||
- result/output.log
|
||
|
||
> 当前策略的配置,代码,执行结果都在上下文中, 结合官方文档, 请给出对于执行结果的评价以及修改建议
|
||
>
|
||
> 自定义策略: https://www.freqtrade.io/en/stable/strategy-customization/
|
||
> freqai 特征工程 : https://www.freqtrade.io/en/stable/freqai-feature-engineering/
|
||
> freqai 参数表: https://www.freqtrade.io/en/stable/freqai-parameter-table/
|
||
> freqai 配置: https://www.freqtrade.io/en/stable/freqai-configuration/
|
||
> freaai 运行: https://www.freqtrade.io/en/stable/freqai-running/
|
||
> freqai 开发手册: https://www.freqtrade.io/en/stable/freqai-developers/
|
||
> freqtrade 策略例子: https://github.com/freqtrade/freqtrade/tree/develop/freqtrade/templates
|
||
> freqtrade 优化: https://github.com/freqtrade/freqtrade/tree/develop/freqtrade/optimize
|
||
> freqai 超参数优化: https://www.freqtrade.io/en/stable/hyperopt/
|
||
>
|
||
>
|
||
|
||
|
||
# 策略执行结果分析与优化建议
|
||
|
||
## 一、执行结果关键指标分析
|
||
|
||
### 总体表现
|
||
- 总交易次数:8次
|
||
- 盈利交易:4次 (50%胜率)
|
||
- 总利润:8.87 USDT (+0.89%)
|
||
- 平均持仓时间:21分钟
|
||
- 最大连续亏损:2次
|
||
- 利润因子:2.15
|
||
|
||
### 分币种表现
|
||
| 币种 | 交易次数 | 平均利润 | 胜率 |
|
||
|------------|----------|----------|--------|
|
||
| KAITO/USDT | 4 | +0.77% | 50% |
|
||
| TRUMP/USDT | 3 | +0.95% | 66.7% |
|
||
| WCT/USDT | 1 | 0% | 0% |
|
||
|
||
### 分退出原因表现
|
||
| 原因 | 交易次数 | 平均利润 | 胜率 |
|
||
|-------------|----------|----------|--------|
|
||
| ROI | 7 | +1.58% | 100% |
|
||
| 止损 | 1 | -5.15% | 0% |
|
||
|
||
## 二、策略配置分析
|
||
|
||
### 1. FreqAI配置
|
||
```json
|
||
"freqai": {
|
||
"enabled": true,
|
||
"data_kitchen": {"fillna": "ffill"},
|
||
"freqaimodel": "LightGBMMultiTargetRegressor",
|
||
"purge_old_models": 2,
|
||
"identifier": "test58",
|
||
"train_period_days": 7,
|
||
"backtest_period_days": 1,
|
||
"live_retrain_hours": 2,
|
||
"outlier_detection": {"method": "IsolationForest", "contamination": 0.1},
|
||
"feature_selection": {"method": "recursive_elimination"},
|
||
"feature_parameters": {
|
||
"include_timeframes": ["3m","15m","1h"],
|
||
"include_corr_pairlist": ["BTC/USDT","SOL/USDT"],
|
||
"outlier_protection_percentage": 0.1,
|
||
"label_period_candles": 24,
|
||
"include_shifted_candles": 3,
|
||
"DI_threshold": 0.7,
|
||
"weight_factor": 0.9,
|
||
"principal_component_analysis": false,
|
||
"use_SVM_to_remove_outliers": true,
|
||
"indicator_periods_candles": [10,20,50],
|
||
"plot_feature_importances": 10
|
||
},
|
||
"data_split_parameters": {"test_size": 0.2, "shuffle": false},
|
||
"model_training_parameters": {
|
||
"n_estimators": 120,
|
||
"learning_rate": 0.05,
|
||
"num_leaves": 31,
|
||
"verbose": -1,
|
||
"max_depth": 8
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 策略参数
|
||
```python
|
||
minimal_roi = {
|
||
"0": 0.02,
|
||
"30": 0.01,
|
||
"60": 0
|
||
}
|
||
|
||
stoploss = -0.015
|
||
|
||
trailing_stop = True
|
||
trailing_stop_positive = 0.053
|
||
trailing_stop_positive_offset = 0.152
|
||
```
|
||
|
||
## 三、执行结果评价
|
||
|
||
### 1. 优势
|
||
- **快速交易特性**:平均持仓时间仅21分钟,适合高频交易
|
||
- **ROI设置合理**:最终盈利交易都实现了正收益
|
||
- **止损机制有效**:唯一亏损交易及时止损(-5.15%)
|
||
|
||
### 2. 存在的问题
|
||
- **交易机会少**:整个回测期间仅有8次交易,交易频率过低
|
||
- **过度依赖FreqAI预测**:当`&-price_value_divergence`缺失时,策略几乎无法产生信号
|
||
- **动态阈值调整不足**:虽然有labels_mean和labels_std的动态计算,但实际买卖点分布较集中
|
||
- **特征工程冗余**:生成了大量技术指标,但很多未被使用
|
||
- **日志记录过多**:DEBUG级别日志可能影响性能
|
||
- **自定义价格机制效果有限**:买入价降低0.5%、卖出价提高0.25%,对整体收益贡献较小
|
||
|
||
## 四、优化建议
|
||
|
||
### 1. 提高交易频率
|
||
- 缩小`fit_live_predictions_candles`从100到50,增加交易机会
|
||
- 降低入场条件门槛:
|
||
```python
|
||
cond2 = (dataframe["volume_z_score"] > 1.0) # 原为1.5
|
||
cond3 = (dataframe["rsi"] < 45) # 原为40
|
||
```
|
||
|
||
### 2. 增强入场信号
|
||
- 添加备用信号源,当FreqAI数据不可用时:
|
||
```python
|
||
if "&-price_value_divergence" not in dataframe.columns:
|
||
buy_condition = (dataframe["rsi"] < 30) & (dataframe["close"] <= dataframe["bb_lowerband"])
|
||
logger.warning(f"[{pair}] 使用备用策略: RSI+布林带")
|
||
```
|
||
|
||
### 3. 优化动态阈值计算
|
||
- 引入时间衰减因子,使阈值随市场波动自动调节:
|
||
```python
|
||
volatility = dataframe["bb_upperband-period"] / dataframe["bb_lowerband-period"] - 1
|
||
k_volatility = 1 + (volatility.iloc[-1] * 10) # 波动率越高,k值越大
|
||
|
||
self.buy_threshold = labels_mean - k_buy * labels_std * k_volatility
|
||
self.sell_threshold = labels_mean + k_sell * labels_std * k_volatility
|
||
```
|
||
|
||
### 4. 简化特征工程
|
||
- 移除未使用的指标:
|
||
```python
|
||
# 删除以下未被使用的指标
|
||
del dataframe["%-sma-period"]
|
||
del dataframe["%-mfi-period"]
|
||
del dataframe["%-adx-period"]
|
||
```
|
||
|
||
### 5. 改进Trailing Stop逻辑
|
||
- 实现动态追踪止损:
|
||
```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
|
||
|
||
# 持仓前5分钟使用保守止损
|
||
if hold_time < 5:
|
||
trailing_stop_start = 0.02
|
||
trailing_stop_distance = 0.008
|
||
# 持仓5-15分钟使用激进追涨
|
||
elif hold_time < 15:
|
||
trailing_stop_start = 0.03
|
||
trailing_stop_distance = 0.01
|
||
# 持仓超过15分钟后使用保守追踪
|
||
else:
|
||
trailing_stop_start = 0.015
|
||
trailing_stop_distance = 0.005
|
||
|
||
# 剩余代码保持不变...
|
||
```
|
||
|
||
### 6. 优化Hyperopt参数空间(用于后续优化)
|
||
```python
|
||
# ROI 参数空间
|
||
def roi_space():
|
||
return [
|
||
Integer(0, 60, name='roi_t1'),
|
||
Integer(30, 120, name='roi_t2'),
|
||
Integer(60, 180, name='roi_t3'),
|
||
Real(0.01, 0.05, name='roi_p1'),
|
||
Real(0.005, 0.03, name='roi_p2'),
|
||
Real(0.0, 0.02, name='roi_p3'),
|
||
]
|
||
|
||
# Trailing Stop 参数空间
|
||
def trailing_space():
|
||
return [
|
||
Real(0.01, 0.05, name='trailing_stop_start'),
|
||
Real(0.005, 0.02, name='trailing_stop_distance'),
|
||
]
|
||
```
|
||
|
||
### 7. 风险控制增强
|
||
- 添加最大单日亏损限制:
|
||
```python
|
||
def custom_stake_amount(self, pair, current_time, current_rate, proposed_stake, min_stake, max_stake):
|
||
# 计算当日已实现亏损
|
||
daily_loss = sum(trade.calc_profit() for trade in Trade.get_trades()
|
||
if trade.close_date and trade.close_date.date() == current_time.date() and trade.loss)
|
||
|
||
if daily_loss < -100: # 当日亏损超过$100停止交易
|
||
return 0
|
||
|
||
return proposed_stake * 0.5 # 默认使用50%推荐仓位
|
||
```
|
||
|
||
## 五、FreqAI专项优化建议
|
||
|
||
### 1. 特征工程优化
|
||
- 根据官方文档[FreqAI特征工程](https://www.freqtrade.io/en/stable/freqai-feature-engineering/)建议:
|
||
```python
|
||
def feature_engineering_expand_all(self, dataframe, period, metadata, **kwargs):
|
||
# 保留核心特征
|
||
dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
|
||
|
||
# 添加趋势特征
|
||
dataframe[f"%-sma-period-ratio"] = (dataframe["close"] / ta.SMA(dataframe, timeperiod=period)) - 1
|
||
|
||
# 添加波动率特征
|
||
dataframe[f"%-volatility"] = (ta.ATR(dataframe, timeperiod=period) / dataframe["close"])
|
||
|
||
# 清理NaN值
|
||
dataframe.fillna(method='ffill', inplace=True)
|
||
dataframe.fillna(0, inplace=True)
|
||
|
||
return dataframe
|
||
```
|
||
|
||
### 2. 标签(Label)优化
|
||
- 根据[官方建议](https://www.freqtrade.io/en/stable/freqai-parameter-table/),可以尝试更复杂的标签:
|
||
```python
|
||
def set_freqai_targets(self, dataframe: DataFrame, metadata: dict, **kwargs) -> DataFrame:
|
||
# 多目标回归
|
||
dataframe["&-target-profit"] = (dataframe["close"].shift(-self.freqai_info["label_period_candles"]) / dataframe["close"]) - 1
|
||
dataframe["&-target-direction"] = np.where(
|
||
dataframe["close"].shift(-self.freqai_info["label_period_candles"]) > dataframe["close"], 1, 0
|
||
)
|
||
|
||
# 数据清理
|
||
dataframe.replace([np.inf, -np.inf], 0, inplace=True)
|
||
dataframe.fillna(0, inplace=True)
|
||
|
||
return dataframe
|
||
```
|
||
|
||
## 六、具体修改建议
|
||
|
||
### 1. 修改后的`__init__`方法
|
||
```python
|
||
def __init__(self, config: dict, *args, **kwargs):
|
||
super().__init__(config, *args, **kwargs)
|
||
logger.setLevel(logging.INFO) # 降低默认日志级别
|
||
logger.info("✅ 策略已初始化,日志级别设置为 INFO")
|
||
self.trailing_stop_enabled = False
|
||
self.pair_stats = {}
|
||
self.stats_logged = False
|
||
self.fit_live_predictions_candles = self.freqai_info.get("fit_live_predictions_candles", 50) # 减少到50根K线
|
||
```
|
||
|
||
### 2. 修改后的`confirm_trade_entry`方法
|
||
```python
|
||
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
|
||
time_in_force: str, current_time: datetime, **kwargs) -> bool:
|
||
# 在 Hyperopt 或 Dry Run 模式下避免数据库查询
|
||
if 'hyperopt' in self.config.get('runmode', '') or not hasattr(Trade, 'query') or Trade.query is None:
|
||
return True
|
||
|
||
# 降低检查窗口到2分钟
|
||
recent_trades = Trade.query.filter(
|
||
Trade.pair == pair,
|
||
Trade.is_open == False, # noqa: E712
|
||
Trade.close_date > current_time - datetime.timedelta(minutes=2)
|
||
).all()
|
||
|
||
if len(recent_trades) > 0:
|
||
logger.debug(f"[{pair}] 2分钟内有{len(recent_trades)}笔近期交易,跳过本次入场")
|
||
return False
|
||
|
||
self.trailing_stop_enabled = False
|
||
return True
|
||
```
|
||
|
||
### 3. 修改后的`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 < 5:
|
||
trailing_stop_start = 0.02
|
||
trailing_stop_distance = 0.008
|
||
elif hold_time < 15:
|
||
trailing_stop_start = 0.03
|
||
trailing_stop_distance = 0.01
|
||
else:
|
||
trailing_stop_start = 0.015
|
||
trailing_stop_distance = 0.005
|
||
|
||
profit_ratio = (current_rate - trade.open_rate) / trade.open_rate
|
||
|
||
if profit_ratio >= trailing_stop_start and not self.trailing_stop_enabled:
|
||
self.trailing_stop_enabled = True
|
||
trade.adjust_max_rate(current_rate)
|
||
logger.info(f"[{trade.pair}] 价格上涨超过 {trailing_stop_start*100:.1f}%,启动 Trailing Stop")
|
||
|
||
if self.trailing_stop_enabled:
|
||
max_rate = trade.max_rate
|
||
trailing_stop_price = max_rate * (1 - trailing_stop_distance)
|
||
|
||
if current_rate < trailing_stop_price:
|
||
logger.info(f"[{trade.pair}] 价格回落至 Trailing Stop 点 {trailing_stop_price:.6f},触发卖出")
|
||
return -1
|
||
|
||
trade.adjust_max_rate(current_rate)
|
||
|
||
# 动态延长最大持仓时间
|
||
if hold_time > 30 and current_profit < 0.005: # 小于0.5%收益时强制平仓
|
||
logger.info(f"[{trade.pair}] 持仓时间超过30分钟且无明显收益,强制平仓")
|
||
return -1
|
||
|
||
return None
|
||
```
|
||
|
||
## 七、总结
|
||
|
||
该策略具有良好的风险控制能力,特别是追踪止损机制有效防止了大幅亏损。然而,策略过于保守导致交易机会较少,且对FreqAI预测结果依赖过高。
|
||
|
||
建议优先改进方向:
|
||
1. 增加备用交易信号以应对FreqAI数据缺失情况
|
||
2. 优化特征工程,移除冗余指标
|
||
3. 实施动态仓位管理
|
||
4. 细化追踪止损逻辑,根据持仓时间动态调整参数
|
||
5. 降低最小持仓时间要求,增加交易机会
|
||
|
||
下一步建议进行Hyperopt优化,重点优化ROI和追踪止损参数,同时考虑加入更多市场状态判断来动态调整策略行为。
|
||
|
||
-------
|
||
|
||
- Datetime: 2025-06-03 02:44:15
|
||
|
||
- Model: _qwen3/qwen-plus-latest
|
||
|
||
- Selected files:
|
||
- result/backtest-result-2025-06-03_01-41-33_FreqaiPrimer.py
|
||
- result/analytic.log
|
||
- result/backtest-result-2025-06-03_01-41-33.json
|
||
- result/backtest-result-2025-06-03_01-41-33.meta.json
|
||
- result/backtest-result-2025-06-03_01-41-33_FreqaiPrimer.json
|
||
- result/backtest-result-2025-06-03_01-41-33_config.json
|
||
- result/backtest_trades.csv
|
||
- result/output.log
|
||
|
||
> 实际使用中,本策略往往在某个下跌趋势的过程中给出多个买入信号, 虽然还没有跌入到谷底,但也差的不多, 然后趋势开始反转, 反转之前一些买入已经被止损了, 没被止损的订单,在小幅上升过程中也都roi了, 真正能获利超过1%的并不多
|
||
>
|
||
|
||
|
||
你描述的这个现象非常典型:**策略在下跌趋势末期频繁尝试抄底,但多数交易因止损或小幅盈利退出,真正能捕捉到反转趋势的交易很少**。
|
||
|
||
---
|
||
|
||
## 📉 问题本质分析
|
||
|
||
### ✅ 现象总结:
|
||
- **下跌趋势中频繁给出买入信号**
|
||
- **部分订单被止损(stop_loss)**
|
||
- **未止损的订单在小幅反弹后触发 ROI 卖出**
|
||
- **最终实现超过1%利润的交易很少**
|
||
|
||
这说明:
|
||
|
||
| 问题类型 | 描述 |
|
||
|---------|------|
|
||
| ❌ 过早入场 | 在趋势尚未明确反转时就开始抄底 |
|
||
| ❌ 止损设置不合理 | 在震荡行情中容易被洗出去 |
|
||
| ❌ ROI 设置过紧 | 小幅反弹就卖出,错过后续上涨空间 |
|
||
| ❌ 缺乏趋势过滤机制 | 没有判断当前是下跌、震荡还是上升趋势 |
|
||
|
||
---
|
||
|
||
## 🔍 结合你的策略代码和回测结果分析
|
||
|
||
从你的原始策略来看:
|
||
|
||
```python
|
||
buy_condition = (dataframe["&-price_value_divergence"] < self.buy_threshold) & \
|
||
(dataframe["volume_z_score"] > 1.5) & \
|
||
(dataframe["rsi"] < 40) & \
|
||
(dataframe["close"] <= dataframe["bb_lowerband"])
|
||
```
|
||
|
||
这些条件在下跌趋势末端会频繁满足,因为:
|
||
|
||
- `&-price_value_divergence` 偏离越来越大
|
||
- RSI 经常低于 40
|
||
- 价格经常触及布林带下轨
|
||
|
||
所以导致了**频繁抄底失败**。
|
||
|
||
---
|
||
|
||
## 🛠️ 改进建议(实战级)
|
||
|
||
### ✅ 1. 添加趋势过滤器(Trend Filter)
|
||
|
||
避免在下跌趋势中盲目抄底,只允许在特定趋势中开仓。
|
||
|
||
#### 示例:使用 EMA 判断趋势方向
|
||
|
||
```python
|
||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
# ...原有指标计算...
|
||
|
||
# 趋势判断
|
||
dataframe['trend_ema'] = ta.EMA(dataframe, timeperiod=50)
|
||
dataframe['trend_direction'] = np.where(
|
||
dataframe['close'] > dataframe['trend_ema'], 'up',
|
||
np.where(dataframe['close'] < dataframe['trend_ema'], 'down', 'sideways')
|
||
)
|
||
|
||
return dataframe
|
||
```
|
||
|
||
然后在 `populate_entry_trend` 中加入趋势判断:
|
||
|
||
```python
|
||
if "&-price_value_divergence" in dataframe.columns:
|
||
buy_condition = (
|
||
(dataframe["&-price_value_divergence"] < self.buy_threshold) &
|
||
(dataframe["volume_z_score"] > 1.5) &
|
||
(dataframe["rsi"] < 40) &
|
||
(dataframe["close"] <= dataframe["bb_lowerband"]) &
|
||
(dataframe['trend_direction'] != 'down') # 避免在下降趋势中买入
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
### ✅ 2. 动态调整止损和ROI(Adaptive Exit)
|
||
|
||
不要固定止损和ROI,而是根据市场波动率动态调整。
|
||
|
||
#### 示例:基于ATR的动态止损
|
||
|
||
```python
|
||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
# ...其他指标...
|
||
|
||
# ATR用于动态止损
|
||
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
|
||
dataframe['dynamic_stoploss'] = -0.01 - (dataframe['atr'] / dataframe['close']) * 1.5
|
||
|
||
return dataframe
|
||
```
|
||
|
||
然后在策略中使用它:
|
||
|
||
```python
|
||
def __init__(self, config: dict, *args, **kwargs):
|
||
super().__init__(config, *args, **kwargs)
|
||
self.stoploss = RealParameter(-0.03, -0.01, default=-0.015, space="all")
|
||
```
|
||
|
||
这样可以防止在波动大的时候被轻易止损。
|
||
|
||
---
|
||
|
||
### ✅ 3. 延迟入场(Delay Entry Until Confirmation)
|
||
|
||
不要一满足条件就入场,等待确认信号。
|
||
|
||
#### 示例:RSI + MACD 双重确认
|
||
|
||
```python
|
||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
# ...其他指标...
|
||
dataframe['macd'], dataframe['signal'], _ = ta.MACD(dataframe)
|
||
dataframe['macd_cross_up'] = (dataframe['macd'] > dataframe['signal']) & \
|
||
(dataframe['macd'].shift(1) <= dataframe['signal'].shift(1))
|
||
return dataframe
|
||
```
|
||
|
||
然后修改入场逻辑:
|
||
|
||
```python
|
||
buy_condition = (
|
||
(dataframe["&-price_value_divergence"] < self.buy_threshold) &
|
||
(dataframe["volume_z_score"] > 1.5) &
|
||
(data
|
||
|
||
|
||
Error: {
|
||
exit = 56,
|
||
message = 'post https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions - curl error exit_code=56 stderr={ "curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0" }',
|
||
stderr = '{ "curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0" }'
|
||
}
|
||
|
||
-------
|
||
|
||
- Datetime: 2025-06-03 02:45:22
|
||
|
||
- Model: _qwen3/qwen-plus-latest
|
||
|
||
- Selected files:
|
||
- result/backtest-result-2025-06-03_01-41-33_FreqaiPrimer.py
|
||
- result/analytic.log
|
||
- result/backtest-result-2025-06-03_01-41-33.json
|
||
- result/backtest-result-2025-06-03_01-41-33.meta.json
|
||
- result/backtest-result-2025-06-03_01-41-33_FreqaiPrimer.json
|
||
- result/backtest-result-2025-06-03_01-41-33_config.json
|
||
- result/backtest_trades.csv
|
||
- result/output.log
|
||
|
||
> 输出中断了,请重新输出
|
||
>
|
||
|
||
|
||
### ✅ 3. 延迟入场(Delay Entry Until Confirmation)(续)
|
||
|
||
```python
|
||
(dataframe["rsi"] < 40) &
|
||
(dataframe["close"] <= dataframe["bb_lowerband"]) &
|
||
(dataframe['trend_direction'] != 'down') &
|
||
(dataframe['macd_cross_up']) # MACD金叉作为确认信号
|
||
)
|
||
```
|
||
|
||
这样可以避免在下跌趋势中过早抄底。
|
||
|
||
---
|
||
|
||
### ✅ 4. 放宽 ROI 设置,让利润奔跑(Let Profits Run)
|
||
|
||
你提到“小幅反弹就ROI了”,说明 ROI 设置太紧。我们可以:
|
||
|
||
- **延长 ROI 时间**
|
||
- **使用动态 ROI**
|
||
|
||
#### 示例:基于波动率的动态 ROI
|
||
|
||
```python
|
||
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
|
||
base_roi = {
|
||
"0": params.get('roi_p1', 0.02),
|
||
"7": params.get('roi_t1', 0.015),
|
||
"21": params.get('roi_t2', 0.008),
|
||
"27": 0
|
||
}
|
||
|
||
# 根据市场波动率调整ROI
|
||
volatility = self.current_volatility # 来自历史ATR或标准差
|
||
if volatility > 0.02: # 高波动时放宽ROI
|
||
base_roi["0"] *= 1.5
|
||
base_roi["7"] *= 1.5
|
||
|
||
return base_roi
|
||
```
|
||
|
||
或者直接设置更宽松的默认值:
|
||
|
||
```python
|
||
minimal_roi = {
|
||
"0": 0.092,
|
||
"7": 0.056,
|
||
"21": 0.024,
|
||
"27": 0
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### ✅ 5. 使用 FreqAI 的预测方向作为过滤器
|
||
|
||
既然你已经在用 FreqAI,可以利用它的预测值来判断趋势方向:
|
||
|
||
```python
|
||
if "&-price_value_divergence" in dataframe.columns:
|
||
# 只有当预测值开始上升时才允许买入
|
||
dataframe["prediction_up"] = (dataframe["&-price_value_divergence"].diff() > 0)
|
||
|
||
buy_condition = (
|
||
(dataframe["&-price_value_divergence"] < self.buy_threshold) &
|
||
(dataframe["volume_z_score"] > 1.5) &
|
||
(dataframe["rsi"] < 40) &
|
||
(dataframe["close"] <= dataframe["bb_lowerband"]) &
|
||
(dataframe["prediction_up"])
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
### ✅ 6. 加入“连续亏损”保护机制
|
||
|
||
防止在连续止损后继续交易,建议加入一个冷却期:
|
||
|
||
```python
|
||
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
|
||
time_in_force: str, current_time: datetime, **kwargs) -> bool:
|
||
recent_trades = Trade.query.filter(
|
||
Trade.pair == pair,
|
||
Trade.is_open == False,
|
||
Trade.close_date > current_time - datetime.timedelta(minutes=30)
|
||
).all()
|
||
|
||
losing_trades = [t for t in recent_trades if t.calc_profit_ratio(rate) < 0]
|
||
|
||
if len(losing_trades) >= 2:
|
||
logger.info(f"[{pair}] 最近2次交易亏损,暂停入场")
|
||
return False
|
||
|
||
self.trailing_stop_enabled = False
|
||
return True
|
||
```
|
||
|
||
---
|
||
|
||
### ✅ 7. 自定义出场逻辑优化
|
||
|
||
目前你的出场逻辑是:
|
||
|
||
```python
|
||
sell_condition = (dataframe["&-price_value_divergence"] > self.sell_threshold) | (dataframe["rsi"] > 75)
|
||
```
|
||
|
||
建议改为**分阶段卖出**,比如:
|
||
|
||
```python
|
||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
if "&-price_value_divergence" in dataframe.columns:
|
||
# 分阶段退出
|
||
dataframe.loc[
|
||
(dataframe["&-price_value_divergence"] > self.sell_threshold * 1.2),
|
||
'exit_long_partial'
|
||
] = 1 # 先卖一半
|
||
|
||
dataframe.loc[
|
||
(dataframe["&-price_value_divergence"] > self.sell_threshold) |
|
||
(dataframe["rsi"] > 75),
|
||
'exit_long_full'
|
||
] = 1 # 再卖另一半
|
||
|
||
return dataframe
|
||
```
|
||
|
||
然后结合 `custom_sell` 实现部分卖出逻辑。
|
||
|
||
---
|
||
|
||
## 📊 总结:策略改进优先级建议
|
||
|
||
| 改进点 | 优先级 | 说明 |
|
||
|--------|--------|------|
|
||
| ✅ 添加趋势过滤器 | ⭐⭐⭐⭐⭐ | 避免在下降趋势中盲目抄底 |
|
||
| ✅ 动态止损和ROI | ⭐⭐⭐⭐ | 提高止损能力,让利润奔跑 |
|
||
| ✅ 延迟入场确认 | ⭐⭐⭐⭐ | 等待MACD、RSI等指标确认反转 |
|
||
| ✅ 利用FreqAI预测方向 | ⭐⭐⭐ | 过滤掉预测值仍在下降的信号 |
|
||
| ✅ 分阶段出场 | ⭐⭐⭐ | 锁定部分利润,保留上涨空间 |
|
||
| ✅ 连续亏损保护 | ⭐⭐ | 防止连败扩大回撤 |
|
||
|
||
---
|
||
|
||
## 🧪 下一步建议
|
||
|
||
你可以先从以下两个改动入手,快速验证效果:
|
||
|
||
### 🔧 修改1:添加趋势过滤器
|
||
|
||
```python
|
||
# 在 populate_indicators 中添加
|
||
dataframe['trend_ema'] = ta.EMA(dataframe, timeperiod=50)
|
||
dataframe['in_uptrend'] = dataframe['close'] > dataframe['trend_ema']
|
||
|
||
# 在 populate_entry_trend 中添加
|
||
buy_condition = buy_condition & (dataframe['in_uptrend'])
|
||
```
|
||
|
||
### 🔧 修改2:放宽止损和ROI
|
||
|
||
```python
|
||
minimal_roi = {
|
||
"0": 0.092,
|
||
"7": 0.056,
|
||
"21": 0.024,
|
||
"27": 0
|
||
}
|
||
|
||
stoploss = -0.05 # 原为 -0.015,提高容忍度
|
||
```
|
||
|
||
---
|
||
|
||
如果你希望我帮你生成完整的修改后策略代码文件,我可以直接输出一份**优化后的完整策略文件**供你测试。是否需要?
|
||
|