优化退出条件
This commit is contained in:
parent
04ad9ee171
commit
429f247deb
@ -22,14 +22,8 @@
|
||||
"TRAILING_STOP_DISTANCE": 0.015,
|
||||
"TRAILING_STOP_START": 0.016
|
||||
},
|
||||
"protection": {},
|
||||
"trailing": {
|
||||
"trailing_stop": true,
|
||||
"trailing_stop_positive": 0.106,
|
||||
"trailing_stop_positive_offset": 0.196,
|
||||
"trailing_only_offset_is_reached": false
|
||||
}
|
||||
"protection": {}
|
||||
},
|
||||
"ft_stratparam_v": 1,
|
||||
"export_time": "2025-07-01 14:51:29.420394+00:00"
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,9 +19,6 @@ class FreqaiPrimer(IStrategy):
|
||||
基于 FreqAI 的动态阈值交易策略,集成动态加仓、减仓和自定义 ROI 逻辑,兼容最新 Freqtrade 版本
|
||||
"""
|
||||
|
||||
# --- 🧪 Hyperopt Parameters ---
|
||||
TRAILING_STOP_START = DecimalParameter(0.01, 0.05, default=0.03, space='sell', optimize=True)
|
||||
TRAILING_STOP_DISTANCE = DecimalParameter(0.005, 0.02, default=0.01, space='sell', optimize=True)
|
||||
|
||||
BUY_THRESHOLD_MIN = DecimalParameter(-0.15, -0.03, default=-0.07, space='buy', optimize=True)
|
||||
BUY_THRESHOLD_MAX = DecimalParameter(-0.04, -0.005, default=-0.01, space='buy', optimize=True)
|
||||
@ -190,6 +187,11 @@ class FreqaiPrimer(IStrategy):
|
||||
dataframe["volume_mean_20"] = dataframe["volume"].rolling(20).mean()
|
||||
dataframe["volume_std_20"] = dataframe["volume"].rolling(20).std()
|
||||
dataframe["volume_z_score"] = (dataframe["volume"] - dataframe["volume_mean_20"]) / dataframe["volume_std_20"]
|
||||
dataframe_15m = self.dp.get_pair_dataframe(pair=pair, timeframe="15m")
|
||||
dataframe_15m['atr15m'] = ta.ATR(dataframe_15m, timeperiod=14)
|
||||
dataframe['atr15m'] = dataframe_15m['atr15m'].reindex(dataframe.index, method="ffill")
|
||||
dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
|
||||
dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20)
|
||||
|
||||
# 数据清理
|
||||
for col in ["ema200", "bb_upperband", "bb_middleband", "bb_lowerband", "rsi", "volume_z_score", "&-price_value_divergence", "price_value_divergence"]:
|
||||
@ -349,25 +351,35 @@ class FreqaiPrimer(IStrategy):
|
||||
|
||||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
pair = metadata.get('pair', 'Unknown')
|
||||
conditions = []
|
||||
|
||||
# 初始化所有条件为 False
|
||||
cond1 = cond2 = cond3 = False
|
||||
|
||||
if "&-price_value_divergence" in dataframe.columns:
|
||||
cond1 = (dataframe["&-price_value_divergence"] > self.sell_threshold * 1.025)
|
||||
cond2 = (dataframe["rsi"] > 75)
|
||||
sell_condition = cond1 | cond2
|
||||
conditions.append(sell_condition)
|
||||
cond1 = (dataframe["&-price_value_divergence"] > self.sell_threshold * 1.05)
|
||||
|
||||
logger.debug(f"[{pair}] 卖出条件检查 - "
|
||||
f"&-price_value_divergence > {self.sell_threshold:.6f}: {cond1.iloc[-1]}, "
|
||||
f"rsi > 75: {cond2.iloc[-1]}")
|
||||
else:
|
||||
logger.warning(f"[{pair}] ⚠️ &-price_value_divergence 列缺失,跳过该条件")
|
||||
if "rsi" in dataframe.columns:
|
||||
cond2 = (dataframe["rsi"] > 70)
|
||||
|
||||
if len(conditions) > 0:
|
||||
dataframe.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
|
||||
logger.debug(f"[{pair}] 出场信号触发,条件满足")
|
||||
else:
|
||||
logger.debug(f"[{pair}] 无有效卖出条件")
|
||||
if "ema10" in dataframe.columns and "ema20" in dataframe.columns:
|
||||
cond3 = (dataframe['ema10'] < dataframe['ema20'])
|
||||
|
||||
# 组合卖出信号
|
||||
sell_condition = cond1 | cond2 | cond3
|
||||
if sell_condition.any():
|
||||
dataframe.loc[sell_condition, 'exit_long'] = 1
|
||||
|
||||
# 获取最后一根K线的实际指标值(用于日志)
|
||||
price_divergence = dataframe["&-price_value_divergence"].iloc[-1] if "&-price_value_divergence" in dataframe.columns else np.nan
|
||||
rsi_value = dataframe["rsi"].iloc[-1] if "rsi" in dataframe.columns else np.nan
|
||||
ema10_value = dataframe["ema10"].iloc[-1] if "ema10" in dataframe.columns else np.nan
|
||||
ema20_value = dataframe["ema20"].iloc[-1] if "ema20" in dataframe.columns else np.nan
|
||||
|
||||
# 构建详细日志信息
|
||||
logger.debug(f"[{pair}] 卖出条件检查 - "
|
||||
f"&-price_value_divergence={price_divergence:.6f} > {self.sell_threshold * 1.05:.6f}: {cond1}, "
|
||||
f"rsi={rsi_value:.2f} > 70: {cond2}, "
|
||||
f"ema10={ema10_value:.6f} < ema20={ema20_value:.6f}: {cond3}")
|
||||
|
||||
return dataframe
|
||||
|
||||
@ -463,8 +475,14 @@ class FreqaiPrimer(IStrategy):
|
||||
return (reduce_amount, f"Profit {profit_ratio*100:.2f}%")
|
||||
|
||||
# 追踪止损逻辑
|
||||
trailing_stop_start = self.TRAILING_STOP_START.value
|
||||
trailing_stop_distance = self.TRAILING_STOP_DISTANCE.value
|
||||
|
||||
atr15m = dataframe['atr15m'].iloc[-1]
|
||||
trailing_stop_distance = 2 * atr15m / current_rate # 2倍ATR,转换为比例
|
||||
trailing_stop_price = max_rate * (1 - trailing_stop_distance)
|
||||
if current_rate < trailing_stop_price:
|
||||
logger.info(f"{pair} 价格回落至 {trailing_stop_price:.6f},触发全部卖出")
|
||||
return (-trade.stake_amount, f"ATR trailing stop at {trailing_stop_price:.6f}")
|
||||
|
||||
# 使用 Sigmoid 映射调整追踪止损参数
|
||||
sigmoid = 1 / (1 + np.exp(-0.1 * (trend_score - 50)))
|
||||
trailing_factor = 0.8 + (1.2 - 0.8) * sigmoid # 牛市(100) -> 1.2, 熊市(0) -> 0.8
|
||||
|
||||
@ -65,7 +65,7 @@ echo "docker-compose run --rm freqtrade hyperopt \
|
||||
--timerange ${START_DATE}-${END_DATE} \
|
||||
-e 100 \
|
||||
--hyperopt-loss ShortTradeDurHyperOptLoss \
|
||||
--spaces buy sell trailing \
|
||||
--spaces buy sell \
|
||||
--fee 0.0016"
|
||||
docker-compose run --rm freqtrade hyperopt \
|
||||
--logfile /freqtrade/user_data/logs/freqtrade.log \
|
||||
@ -77,7 +77,7 @@ docker-compose run --rm freqtrade hyperopt \
|
||||
--timerange ${START_DATE}-${END_DATE} \
|
||||
-e 100 \
|
||||
--hyperopt-loss SharpeHyperOptLoss \
|
||||
--spaces buy sell trailing \
|
||||
--spaces buy sell \
|
||||
--fee 0.0016
|
||||
|
||||
#>output.log 2>&1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user