价值背离

This commit is contained in:
zhangkun9038@dingtalk.com 2025-05-31 09:00:29 +00:00
parent eacad43b80
commit 71687b5539
3 changed files with 326 additions and 178 deletions

245
chat/result13.md Normal file
View File

@ -0,0 +1,245 @@
> 请实现代码:
> 1. **将 `&-divergence_score` 改为连续值形式**
> 2. **移除任何离散值列(如 market_condition 编码)**
> 3. **保持使用 `LightGBMMultiTargetRegressor` 模型**
> 4. **在策略中使用这些连续值进行动态交易决策**
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-05-31 08:40:04
- Model: _qwen3/qwen-plus-latest
- Selected files:
- freqtrade/templates/freqaiprimer.py
> 中断了,请继续
非常理解,我们继续完成你的需求。
---
## ✅ 你的目标
你希望:
1. **将 `&-divergence_score` 改为连续值形式**
2. **移除任何离散值列(如 `&-market_condition`**
3. **保持使用 `LightGBMMultiTargetRegressor` 模型**
4. **在策略中使用这些连续值进行动态交易决策**
---
## ✅ 实现步骤概览
我们将完成以下修改:
| 步骤 | 内容 |
|------|------|
| 🧮 Step 1 | 修改 `set_freqai_targets()`:生成连续背离评分 |
| 🧹 Step 2 | 移除所有离散值列(如 `&-market_condition` |
| 📈 Step 3 | 配置 FreqAI 使用 `LightGBMMultiTargetRegressor` |
| 🛠 Step 4 | 在 `populate_entry_trend()``populate_exit_trend()` 中使用连续背离信号 |
---
## 🧮 Step 1修改 `set_freqai_targets()`,生成连续背离评分
```python
def set_freqai_targets(self, dataframe: DataFrame, metadata: dict, **kwargs) -> DataFrame:
"""
使用历史窗口预测未来趋势和波动率作为辅助信号,
并新增一个连续值的背离评分列 &-divergence_score
"""
label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
# 1. 趋势强度:使用过去 N 根 K 线的收益率判断当前趋势
dataframe["&-trend_strength"] = dataframe["close"].pct_change(label_period)
# 2. 波动率预测:使用过去 N 根 K 线的价格变动绝对值
dataframe["&-volatility_forecast"] = dataframe["close"].pct_change(label_period).abs()
# 3. ROI 目标:基于趋势强度缩放
dataframe["&-roi_target"] = np.where(
dataframe["&-trend_strength"] > 0,
dataframe["&-trend_strength"] * 1.5,
0.01 # 最小 ROI
)
# 4. 动态止损目标:基于波动率缩放
dataframe["&-stoploss_target"] = -dataframe["&-volatility_forecast"] * 1.2
# 5. 新增:连续背离评分(价格与趋势的偏离程度)
dataframe["price_change"] = dataframe["close"].pct_change(label_period)
dataframe["trend_change"] = dataframe["&-trend_strength"].pct_change(label_period)
# 连续背离评分:正值表示正向背离,负值表示负向背离
dataframe["&-divergence_score"] = dataframe["price_change"] - dataframe["trend_change"]
return dataframe
```
---
## 🧹 Step 2移除所有离散值列`&-market_condition`
如果你之前定义了 `&-market_condition` 或其他分类列,请从 `set_freqai_targets()``populate_indicators()` 中删除它们。
### ❌ 删除示例:
```python
# 删除以下代码(如果存在)
if "bb_upperband-period" in dataframe.columns and "bb_lowerband-period" in dataframe.columns:
dataframe["&-market_condition"] = np.select([
(dataframe["close"] > dataframe["bb_upperband-period"]),
(dataframe["close"] < dataframe["bb_lowerband-period"]),
(dataframe["&-trend_strength"] > 0.03),
], [
"overbought",
"oversold",
"strong_up",
], default="sideways")
```
同时确保不再使用这些列做任何逻辑判断。
---
## 📈 Step 3配置 FreqAI 使用 `LightGBMMultiTargetRegressor`
在你的策略类中设置:
```python
freqai_info = {
"model": "LightGBMMultiTargetRegressor", # ✅ 多目标回归模型
"feature_parameters": {
"include_timeframes": ["5m", "15m", "1h"],
"label_period_candles": 24,
"include_shifted_candles": 3,
"principal_component_analysis": True, # 可选:启用 PCA 提升泛化能力
},
"data_split_parameters": {
"test_size": 0.2,
"shuffle": False,
},
"model_training_parameters": {
"n_estimators": 200,
"learning_rate": 0.05,
"num_leaves": 31,
"verbose": -1,
},
}
```
这样 FreqAI 将使用 LightGBM 的多输出回归模型来同时预测多个连续目标列。
---
## 🛠 Step 4在策略中使用连续背离信号进行交易决策
### ✅ 示例:在 `populate_entry_trend()` 中使用 `&-divergence_score`
```python
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
conditions = []
if "&-divergence_score" in df.columns:
# 正向背离:价格下跌但趋势上升(背离评分为正值)
buy_condition = df["&-divergence_score"] > 0.01
# 结合趋势强度过滤
if "&-trend_strength" in df.columns:
buy_condition &= df["&-trend_strength"] > 0.005
# 成交量过滤:成交量需大于 20 日均值的 1 倍
df["vol_mean"] = df["volume"].rolling(20).mean()
buy_condition &= (df["volume"] > df["vol_mean"] * 1)
conditions.append(buy_condition)
if len(conditions):
df.loc[reduce(lambda x, y: x & y, conditions), 'enter_long'] = 1
return df
```
### ✅ 示例:在 `populate_exit_trend()` 中使用 `&-divergence_score`
```python
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
conditions = []
if "&-divergence_score" in df.columns:
# 负向背离:价格上涨但趋势下降(背离评分为负值)
sell_condition = df["&-divergence_score"] < -0.01
# 结合趋势强度过滤
if "&-trend_strength" in df.columns:
sell_condition &= df["&-trend_strength"] < -0.005
conditions.append(sell_condition)
if len(conditions):
df.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
return df
```
---
## 📦 Step 5更新 `plot_config`(可选)
你可以将背离评分加入绘图配置,方便可视化观察:
```python
plot_config = {
"main_plot": {},
"subplots": {
"Signals": {
"enter_long": {"color": "green"},
"exit_long": {"color": "red"}
},
"FreqAI Predictions": {
"&-trend_strength": {"color": "blue"},
"&-volatility_forecast": {"color": "orange"},
"&-divergence_score": {"color": "purple"}
}
}
}
```
---
## ✅ 总结改进点
| 改进项 | 描述 |
|--------|------|
| ✅ `&-divergence_score` 改为连续值 | 更适合回归模型学习 |
| ✅ 移除所有离散值列 | 如 `&-market_condition` |
| ✅ 使用 `LightGBMMultiTargetRegressor` | 同时预测多个连续目标 |
| ✅ 在策略中使用背离评分进行交易决策 | 提高反转识别能力 |
---
## ✅ 下一步建议
你可以:
- 使用 `freqtrade plot-dataframe` 查看背离信号是否合理
- 使用 `freqtrade backtesting` 测试新策略表现
- 使用 `freqtrade hyperopt` 对背离阈值进行优化
---
如果你希望我帮你生成完整的策略文件,并提供对应的 `config.json` 示例,请告诉我 👇 我可以一步步帮你完成。

View File

@ -68,8 +68,8 @@
"freqaimodel": "LightGBMMultiTargetRegressor",
"purge_old_models": 2,
"identifier": "test58",
"train_period_days": 30,
"backtest_period_days": 7,
"train_period_days": 7,
"backtest_period_days": 1,
"live_retrain_hours": 2,
"outlier_detection": {
"method": "IsolationForest",
@ -80,7 +80,7 @@
},
"feature_parameters": {
"include_timeframes": [
"3m",
"5m",
"15m",
"1h"
],
@ -89,11 +89,11 @@
"SOL/USDT"
],
"outlier_protection_percentage": 0.1,
"label_period_candles": 12,
"label_period_candles": 24,
"include_shifted_candles": 3,
"DI_threshold": 0.7,
"weight_factor": 0.9,
"principal_component_analysis": false,
"principal_component_analysis": true,
"use_SVM_to_remove_outliers": true,
"indicator_periods_candles": [
10,
@ -107,7 +107,7 @@
"shuffle": false
},
"model_training_parameters": {
"n_estimators": 100,
"n_estimators": 200,
"learning_rate": 0.05,
"num_leaves": 31,
"verbose": -1,

View File

@ -8,18 +8,21 @@ from pandas import DataFrame
from typing import Dict, Optional
from technical import qtpylib
from freqtrade.strategy import IStrategy
from logging import getLogger
logger = logging.getLogger(__name__)
class FreqaiPrimer(IStrategy):
class DivergenceRegressionStrategy(IStrategy):
"""
策略说明
- 所有交易信号由 FreqAI 动态预测
- 不使用 Hyperopt 优化任何参数
- 使用 FreqAI 提供的趋势和波动率信号进行交易决策
- 所有交易信号基于 FreqAI 的动态预测
- 使用多目标回归模型预测趋势强度波动率ROI止损和背离评分
- 入场/出场基于连续背离信号
- 不使用 Hyperopt 优化参数
- 不包含任何分类列 market_condition
"""
# 👇 添加在这里
# 👇 币种特定参数(可选)
PAIR_PARAMS = {
"BTC/USDT": {"volatility_factor": 1.0, "min_stop": -0.005},
"TON/USDT": {"volatility_factor": 1.3, "min_stop": -0.0035},
@ -39,10 +42,10 @@ class FreqaiPrimer(IStrategy):
}
use_custom_stoploss = True
trailing_stop = True
trailing_stop_positive = 0.005
trailing_stop_positive_offset = 0.01
trailing_only_offset_is_reached = True
trailing_stop = False # 关闭 trailing_stop避免干扰背离信号
use_dynamic_roi = True
position_adjuster = True
plot_config = {
"main_plot": {},
"subplots": {
@ -51,19 +54,20 @@ class FreqaiPrimer(IStrategy):
"exit_long": {"color": "red"}
},
"FreqAI Predictions": {
"&-buy_signal": {"color": "blue"},
"&-sell_signal": {"color": "orange"},
"&-volatility_forecast": {"color": "purple"}
"&-trend_strength": {"color": "blue"},
"&-volatility_forecast": {"color": "orange"},
"&-divergence_score": {"color": "purple"}
}
}
}
freqai_info = {
"model": "LightGBMClassifier",
"model": "LightGBMMultiTargetRegressor",
"feature_parameters": {
"include_timeframes": ["5m", "15m", "1h"],
"label_period_candles": 24,
"include_shifted_candles": 3,
"principal_component_analysis": True,
},
"data_split_parameters": {
"test_size": 0.2,
@ -76,12 +80,15 @@ class FreqaiPrimer(IStrategy):
"verbose": -1,
},
}
def __init__(self, config: dict, *args, **kwargs):
super().__init__(config, *args, **kwargs)
# 设置日志级别为 DEBUG
logger.setLevel(logging.DEBUG)
logger.debug("✅ 策略已初始化,日志级别设置为 DEBUG")
# 👇 特征工程函数
def feature_engineering_expand_all(self, dataframe: DataFrame, period: int, metadata: dict, **kwargs) -> DataFrame:
# 保留原有指标
dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
@ -93,7 +100,7 @@ class FreqaiPrimer(IStrategy):
dataframe["bb_lowerband-period"] = lowerband
dataframe["bb_upperband-period"] = upperband
dataframe["bb_middleband-period"] = middleband
dataframe["%-bb_width-period"] = (dataframe["bb_upperband-period"] - dataframe["bb_lowerband-period"]) / dataframe["bb_middleband-period"]
dataframe["%-bb_width-period"] = (dataframe["bb_upperband-period"] - dataframe["bb_middleband-period"]) / dataframe["bb_middleband-period"]
dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)
# 添加策略 B 的指标
@ -103,79 +110,53 @@ class FreqaiPrimer(IStrategy):
dataframe["%-relative_volume-period"] = dataframe["volume"] / dataframe["volume"].rolling(period).mean() # 相对成交量
dataframe["%-close-bb_lower-period"] = dataframe["close"] / dataframe["bb_lowerband-period"] # 收盘价/布林带下轨
# 新增:与背离相关的衍生特征
dataframe["%-price_trend_diff-period"] = dataframe["close"] - dataframe["%-ema-period"] # 价格与趋势偏离
dataframe["%-roc_mfi_ratio-period"] = dataframe["%-roc-period"] / (dataframe["%-mfi-period"].replace(0, 1)) # ROC/MFI 比率
# 数据清理
columns_to_clean = [
"%-rsi-period", "%-mfi-period", "%-sma-period", "%-ema-period", "%-adx-period",
"bb_lowerband-period", "bb_middleband-period", "bb_upperband-period",
"%-bb_width-period", "%-roc-period", "%-relative_volume-period", "%-close-bb_lower-period", "%-tema-period"
"%-bb_width-period", "%-roc-period", "%-relative_volume-period", "%-close-bb_lower-period", "%-tema-period",
"%-price_trend_diff-period", "%-roc_mfi_ratio-period"
]
for col in columns_to_clean:
dataframe[col] = dataframe[col].replace([np.inf, -np.inf], 0).ffill().fillna(0)
return dataframe
# 👇 定义目标列(全部为连续值)
def set_freqai_targets(self, dataframe: DataFrame, metadata: dict, **kwargs) -> DataFrame:
"""
使用历史窗口预测未来趋势和波动率作为辅助信号
避免使用任何未来数据 shift(-N)
"""
label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
# 1. 趋势强度:使用过去 N 根 K 线的收益率判断当前趋势
# 1. 趋势强度
dataframe["&-trend_strength"] = dataframe["close"].pct_change(label_period)
# 2. 波动率预测:使用过去 N 根 K 线的价格变动绝对值
# 2. 波动率预测
dataframe["&-volatility_forecast"] = dataframe["close"].pct_change(label_period).abs()
# 3. 动态 ROI 目标:基于趋势强度缩放
# 3. ROI 目标
dataframe["&-roi_target"] = np.where(
dataframe["&-trend_strength"] > 0,
dataframe["&-trend_strength"] * 1.5,
0.01 # 最小 ROI
0.01
)
# 4. 动态止损目标:基于波动率缩放
# 4. 动态止损目标
dataframe["&-stoploss_target"] = -dataframe["&-volatility_forecast"] * 1.2
# 👇 新增z-score 标准化模型输出
if self.freqai and hasattr(self.freqai, "data"):
labels_mean = self.freqai.data.labels_mean
labels_std = self.freqai.data.labels_std
mean_roi = labels_mean.get("&-roi_target", 0.01)
std_roi = labels_std.get("&-roi_target", 0.01)
mean_stop = labels_mean.get("&-stoploss_target", -0.01)
std_stop = labels_std.get("&-stoploss_target", 0.01)
# z-score 标准化
dataframe["&-roi_target_z"] = (dataframe["&-roi_target"] - mean_roi) / std_roi
dataframe["&-stoploss_target_z"] = (dataframe["&-stoploss_target"] - mean_stop) / std_stop
# 市场状态识别:判断当前是震荡、趋势、超买还是超卖
if "bb_upperband-period" in dataframe.columns and "bb_lowerband-period" in dataframe.columns:
dataframe["&-market_condition"] = np.select([
(dataframe["close"] > dataframe["bb_upperband-period"]),
(dataframe["close"] < dataframe["bb_lowerband-period"]),
(dataframe["&-trend_strength"] > 0.03),
], [
"overbought",
"oversold",
"strong_up",
], default="sideways")
# 买入信号(必须存在)
dataframe["&-buy_signal"] = np.where(dataframe["&-trend_strength"] > 0.01, 1, 0)
# 卖出信号(必须存在)
dataframe["&-sell_signal"] = np.where(dataframe["&-trend_strength"] < -0.01, 1, 0)
# 5. 连续背离评分
dataframe["price_change"] = dataframe["close"].pct_change(label_period)
dataframe["trend_change"] = dataframe["&-trend_strength"].pct_change(label_period)
dataframe["&-divergence_score"] = dataframe["price_change"] - dataframe["trend_change"]
return dataframe
# 👇 缓存 mean/std 供后续使用
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe = self.freqai.start(dataframe, metadata, self)
# 缓存 mean/std 供后续使用
if self.freqai and hasattr(self.freqai, "data"):
labels_mean = self.freqai.data.labels_mean
labels_std = self.freqai.data.labels_std
@ -186,120 +167,82 @@ class FreqaiPrimer(IStrategy):
dataframe["mean_volatility"] = labels_mean.get("&-volatility_forecast", 0.0021)
dataframe["std_volatility"] = labels_std.get("&-volatility_forecast", 0.0022)
dataframe["mean_roi"] = labels_mean.get("&-roi_target", 0.0065)
dataframe["std_roi"] = labels_std.get("&-roi_target", 0.0041)
dataframe["mean_stop"] = labels_mean.get("&-stoploss_target", -0.0026)
dataframe["std_stop"] = labels_std.get("&-stoploss_target", 0.0027)
dataframe["mean_divergence"] = labels_mean.get("&-divergence_score", 0.0)
dataframe["std_divergence"] = labels_std.get("&-divergence_score", 1.0)
return dataframe
# 👇 使用背离信号作为入场条件
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
"""
基于 FreqAI 的预测结果生成入场信号
使用滚动分位数 + Z-score + 市场状态过滤提高信号质量
"""
conditions = []
# 确保 &-buy_signal 存在
if "&-buy_signal" in df.columns:
if "&-divergence_score" in df.columns:
# 使用过去 20 根 K 线中 buy_signal 的 80 分位作为动态阈值
df["buy_threshold"] = df["&-buy_signal"].rolling(20).quantile(0.8)
buy_condition = df["&-buy_signal"] >= df["buy_threshold"]
buy_condition = df["&-divergence_score"] > 0.01
# 使用 Z-score 判断趋势显著性(仅保留趋势较强的时间点)
if "mean_trend" in df.columns and "std_trend" in df.columns:
mean_trend = df["mean_trend"].iloc[-1]
std_trend = df["std_trend"].iloc[-1]
if "&-trend_strength" in df.columns:
buy_condition &= df["&-trend_strength"] > 0.005
z_score_trend = (df["&-trend_strength"] - mean_trend) / std_trend
buy_condition &= (z_score_trend > 1) # 只保留趋势显著的信号
# 市场状态过滤:震荡市减少交易频率
if "&-market_condition" in df.columns:
buy_condition &= ~(
(df["&-market_condition"] == "sideways") &
(df["&-buy_signal"] < df["buy_threshold"] * 1.2)
)
# 在超买市场中进一步过滤买入信号
buy_condition &= ~(df["&-market_condition"] == "overbought")
# EMA 趋势过滤:只在价格高于 EMA50 时开仓
df["ema50"] = ta.EMA(df, timeperiod=50)
buy_condition &= (df["close"] > df["ema50"])
# 成交量过滤:成交量需大于 20 日均值的 1 倍
df["vol_mean"] = df["volume"].rolling(20).mean()
buy_condition &= (df["volume"] > df["vol_mean"] * 1)
conditions.append(buy_condition)
else:
self.logger.warning("⚠️ &-buy_signal 列缺失,跳过该条件")
# 如果有多个条件,使用逻辑与合并
if len(conditions):
df.loc[reduce(lambda x, y: x & y, conditions), 'enter_long'] = 1
return df
# 👇 使用背离信号作为出场条件
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
# Compute sell_signal_high outside the conditions list
pair = metadata['pair']
trade = Trade.get_trades([("pair", pair)]).first()
conditions = []
if trade and trade.is_open:
open_candle_index = df.index.get_loc(trade.open_date.replace(tzinfo=None))
current_index = len(df) - 1
holding_period = current_index - open_candle_index
if "&-divergence_score" in df.columns:
if holding_period < 5:
df.loc[df.index[-1], 'exit_long'] = 0
return df
df["sell_signal_high"] = (df["&-sell_signal"] > 0.3).rolling(3).sum() >= 2
sell_condition = df["&-divergence_score"] < -0.01
conditions = [
df["sell_signal_high"] # Append the condition, not an assignment
]
if "&-trend_strength" in df.columns:
sell_condition &= df["&-trend_strength"] < -0.005
if "&-market_condition" in df.columns:
# 在超卖市场中减少卖出信号
conditions.append(df["&-market_condition"] != "oversold")
conditions.append(sell_condition)
# 在超买市场中增强卖出信号
conditions.append(~((df["&-market_condition"] == "overbought") & (df["&-sell_signal"] < 0.7)))
if len(conditions):
df.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
df.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
return df
# 👇 自定义止损(基于波动率缩放)
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1]
volatility = last_candle.get("&-volatility_forecast", 0.0021)
dynamic_stoploss = -volatility * 2 # 设置为波动率的两倍
dynamic_stoploss = max(dynamic_stoploss, -0.01) # 最大不超过 1%
return dynamic_stoploss
# 👇 动态调整持仓止盈
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float,
min_roi: Dict[float, float], max_profit: float) -> Optional[Dict[float, float]]:
"""
动态调整持仓逻辑基于 FreqAI 预测的 ROI 目标
根据 Z-score 判断趋势强度动态设置止盈时间窗口
"""
current_rate: float, current_profit: float,
min_roi: Dict[float, float], max_profit: float) -> Optional[Dict[float, float]]:
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
last_candle = dataframe.iloc[-1]
# 获取预测的 ROI 目标 和 统计信息
roi_target = last_candle.get("&-roi_target", 0.0065)
mean_roi = last_candle.get("mean_roi", 0.0065)
std_roi = last_candle.get("std_roi", 0.0041)
# 计算 Z-score
z_score_roi = (roi_target - mean_roi) / std_roi if std_roi != 0 else 0
# 根据 Z-score 设置不同的 ROI 表
if z_score_roi > 1:
return {
"0": roi_target * 1.2,
"10": roi_target * 0.9,
"30": roi_target * 0.6,
"60": roi_target * 0.3,
"120": 0.01
"30": roi_target * 0.9,
"60": roi_target * 0.6,
"120": roi_target * 0.3,
"180": 0.01
}
elif z_score_roi > 0:
return {
@ -315,43 +258,3 @@ class FreqaiPrimer(IStrategy):
"180": 0.005
}
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""
动态止损回调函数基于 FreqAI 预测的 &-stoploss_target
"""
# 获取当前币种的 dataframe
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1]
# 获取预测的止损目标(使用 z-score 版本)
stoploss_z = last_candle.get("&-stoploss_target_z", -1.0) # 默认值为 -1.0(一个标准差)
# 获取模型统计信息用于自适应判断
mean_stop = -0.01
std_stop = 0.01
if self.freqai and hasattr(self.freqai, "data"):
labels_mean = self.freqai.data.labels_mean
labels_std = self.freqai.data.labels_std
mean_stop = labels_mean.get("&-stoploss_target", mean_stop)
std_stop = labels_std.get("&-stoploss_target", std_stop)
# 获取币种特定参数
params = self.PAIR_PARAMS.get(pair, {"volatility_factor": 1.0, "min_stop": -0.005})
volatility_factor = params["volatility_factor"]
min_stop = params["min_stop"]
# 动态止损下限 = 平均值 - volatility_factor * 标准差
dynamic_min_stop = min(min_stop, mean_stop - volatility_factor * std_stop)
# 如果 z-score < -1则说明当前止损偏移较大适当放宽
if stoploss_z < -1.0:
dynamic_min_stop = min(dynamic_min_stop * 1.2, -0.003)
# 最终止损值 = 模型建议值 和 动态下限中的较小者
dynamic_stoploss = dynamic_min_stop
return dynamic_stoploss