修复实盘开仓频繁问题:添加入场间隔/冷启动保护/提高入场条件严格度
This commit is contained in:
parent
e903e2c0ab
commit
369a3e7b8a
@ -388,7 +388,7 @@ class FreqaiPrimer(IStrategy):
|
|||||||
stochrsi_neutral_threshold = IntParameter(20, 30, default=25, optimize=True, load=True, space='buy')
|
stochrsi_neutral_threshold = IntParameter(20, 30, default=25, optimize=True, load=True, space='buy')
|
||||||
volume_multiplier = DecimalParameter(1.2, 2.0, decimals=1, default=1.5, optimize=True, load=True, space='buy')
|
volume_multiplier = DecimalParameter(1.2, 2.0, decimals=1, default=1.5, optimize=True, load=True, space='buy')
|
||||||
bb_width_threshold = DecimalParameter(0.01, 0.03, decimals=3, default=0.02, optimize=True, load=True, space='buy')
|
bb_width_threshold = DecimalParameter(0.01, 0.03, decimals=3, default=0.02, optimize=True, load=True, space='buy')
|
||||||
min_condition_count = IntParameter(2, 4, default=3, optimize=True, load=True, space='buy')
|
min_condition_count = IntParameter(3, 5, default=4, optimize=True, load=True, space='buy')
|
||||||
|
|
||||||
# 剧烈拉升检测参数 - 使用Hyperopt可优化参数
|
# 剧烈拉升检测参数 - 使用Hyperopt可优化参数
|
||||||
h1_max_candles = IntParameter(100, 300, default=200, optimize=True, load=True, space='buy')
|
h1_max_candles = IntParameter(100, 300, default=200, optimize=True, load=True, space='buy')
|
||||||
@ -396,7 +396,7 @@ class FreqaiPrimer(IStrategy):
|
|||||||
h1_max_consecutive_candles = IntParameter(1, 4, default=2, optimize=True, load=True, space='buy')
|
h1_max_consecutive_candles = IntParameter(1, 4, default=2, optimize=True, load=True, space='buy')
|
||||||
|
|
||||||
# 入场间隔控制参数(分钟)
|
# 入场间隔控制参数(分钟)
|
||||||
entry_interval_minutes = IntParameter(20, 200, default=42, optimize=True, load=True, space='buy')
|
entry_interval_minutes = IntParameter(60, 240, default=90, optimize=True, load=True, space='buy')
|
||||||
|
|
||||||
# EMA20斜率阈值参数(用于趋势强度过滤)
|
# EMA20斜率阈值参数(用于趋势强度过滤)
|
||||||
ema20_slope_threshold = DecimalParameter(0.0005, 0.005, decimals=4, default=0.001, optimize=True, load=True, space='buy')
|
ema20_slope_threshold = DecimalParameter(0.0005, 0.005, decimals=4, default=0.001, optimize=True, load=True, space='buy')
|
||||||
@ -1342,7 +1342,7 @@ class FreqaiPrimer(IStrategy):
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
交易买入前的确认函数,用于最终决定是否执行交易
|
交易买入前的确认函数,用于最终决定是否执行交易
|
||||||
此处实现从API获取数据、高波动禁止入场、时间戳和RMSE检查逻辑
|
包含入场间隔控制、基础保护机制
|
||||||
"""
|
"""
|
||||||
self.strategy_log(f"[{pair}] confirm_trade_entry 被调用 - 价格: {rate:.8f}, 时间: {current_time}")
|
self.strategy_log(f"[{pair}] confirm_trade_entry 被调用 - 价格: {rate:.8f}, 时间: {current_time}")
|
||||||
|
|
||||||
@ -1351,6 +1351,42 @@ class FreqaiPrimer(IStrategy):
|
|||||||
self.strategy_log(f"[{pair}] 非多头交易,跳过入场检查")
|
self.strategy_log(f"[{pair}] 非多头交易,跳过入场检查")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# ========== 基础保护1:入场间隔控制 ==========
|
||||||
|
if pair in self._last_entry_time:
|
||||||
|
last_entry = self._last_entry_time[pair]
|
||||||
|
time_since_last_entry = (current_time - last_entry).total_seconds() / 60
|
||||||
|
interval_minutes = self.entry_interval_minutes.value
|
||||||
|
|
||||||
|
if time_since_last_entry < interval_minutes:
|
||||||
|
self.strategy_log(
|
||||||
|
f"[{pair}] 入场间隔不足: 距离上次入场 {time_since_last_entry:.1f}分钟, "
|
||||||
|
f"需要 {interval_minutes}分钟, 拒绝入场"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# ========== 基础保护2:冷启动保护 ==========
|
||||||
|
time_since_start = (current_time - self._strategy_start_time).total_seconds()
|
||||||
|
if time_since_start < 300: # 5分钟冷启动保护
|
||||||
|
self.strategy_log(f"[{pair}] 冷启动保护中: 策略启动 {time_since_start:.0f}秒, 拒绝入场")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# ========== 基础保护3:检查当前技术指标 ==========
|
||||||
|
try:
|
||||||
|
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||||
|
if len(dataframe) < 10:
|
||||||
|
self.strategy_log(f"[{pair}] 数据不足,拒绝入场")
|
||||||
|
return False
|
||||||
|
|
||||||
|
last_candle = dataframe.iloc[-1]
|
||||||
|
|
||||||
|
# 检查RSI是否过高(避免追高)
|
||||||
|
if 'rsi' in last_candle and last_candle['rsi'] > 65:
|
||||||
|
self.strategy_log(f"[{pair}] RSI过高({last_candle['rsi']:.1f} > 65),拒绝入场")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.strategy_log(f"[{pair}] 技术指标检查出错: {str(e)}")
|
||||||
|
|
||||||
# 获取虚机名字
|
# 获取虚机名字
|
||||||
import os
|
import os
|
||||||
virtual_host_name = os.environ.get('VIRTUAL_HOST_NAME')
|
virtual_host_name = os.environ.get('VIRTUAL_HOST_NAME')
|
||||||
@ -1434,6 +1470,9 @@ class FreqaiPrimer(IStrategy):
|
|||||||
self.strategy_log(f" - 入场信号: {values.get('&s-entry_signal')}")
|
self.strategy_log(f" - 入场信号: {values.get('&s-entry_signal')}")
|
||||||
self.strategy_log(f" - 出场信号: {values.get('&s-exit_signal')}")
|
self.strategy_log(f" - 出场信号: {values.get('&s-exit_signal')}")
|
||||||
|
|
||||||
|
# 记录入场时间
|
||||||
|
self._last_entry_time[pair] = current_time
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
@ -1443,8 +1482,12 @@ class FreqaiPrimer(IStrategy):
|
|||||||
self.strategy_log(f"[{pair}] 检查过程中发生错误: {str(e)}")
|
self.strategy_log(f"[{pair}] 检查过程中发生错误: {str(e)}")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# 虚机名字不是kiko,跳过外部数据获取和RMSE限制,直接允许入场
|
# 虚机名字不是kiko,只使用基础保护机制
|
||||||
self.strategy_log(f"[{pair}] 虚机名字不是kiko,跳过外部数据获取和RMSE限制,直接允许入场")
|
self.strategy_log(f"[{pair}] 虚机名字不是kiko,使用基础保护机制,允许入场")
|
||||||
|
|
||||||
|
# 记录入场时间
|
||||||
|
self._last_entry_time[pair] = current_time
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user