退出条件允许趋势交易

This commit is contained in:
zhangkun9038@dingtalk.com 2025-08-30 13:23:57 +08:00
parent 6aeb28f32b
commit 971fc5bbde

View File

@ -22,9 +22,23 @@ class FreqaiPrimer(IStrategy):
stoploss = -0.01 # 固定止损 -1%
trailing_stop = True
trailing_stop_positive = 0.005 # 价格上涨 0.5% 后开始追踪
trailing_stop_positive_offset = 0.008 # 追踪止损偏移量 0.8%
# 用于跟踪市场状态的数据框缓存
_dataframe_cache = None
@property
def trailing_stop_positive(self):
"""根据市场状态动态调整跟踪止盈参数"""
# 获取当前市场状态
if self._dataframe_cache is not None and len(self._dataframe_cache) > 0:
current_state = self._dataframe_cache['market_state'].iloc[-1]
if current_state == 'strong_bull':
return 0.01 # 强劲牛市中放宽跟踪止盈
elif current_state == 'weak_bull':
return 0.007
return 0.005 # 默认值
timeframe = "3m" # 主时间框架为 3 分钟
can_short = False # 禁用做空
@ -203,14 +217,46 @@ class FreqaiPrimer(IStrategy):
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 做多退出(优化以减少亏损)
dataframe.loc[
(
(dataframe['close'] >= dataframe['bb_upper_3m']) |
(dataframe['rsi_3m'] > self.rsi_overbought) |
(dataframe['close'] > dataframe['open'] + dataframe['atr'] * 2) # 获利2倍ATR
),
'exit_long'] = 1
# 缓存数据框以便在trailing_stop_positive属性中使用
self._dataframe_cache = dataframe
# 基础退出条件
basic_exit = (
(dataframe['close'] >= dataframe['bb_upper_3m']) |
(dataframe['rsi_3m'] > self.rsi_overbought)
)
# 强劲趋势条件1h趋势向上 + 熊牛得分>70
strong_trend = (dataframe['trend_1h_ema'] == 1) & (dataframe['market_score'] > 70)
# 一般趋势条件熊牛得分50-70
normal_trend = (dataframe['market_score'] >= 50) & (dataframe['market_score'] <= 70)
# 获取15m数据进行趋势确认
df_15m = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='15m')
df_15m = df_15m.rename(columns={'date': 'date_15m'})
merged_data = dataframe.merge(df_15m[['date_15m', 'rsi_15m']], how='left', left_on='date', right_on='date_15m')
merged_data = merged_data.fillna(method='ffill')
# 趋势反转信号15m RSI超买
trend_reversal = merged_data['rsi_15m'] > 75
# 动态调整退出条件
# 强劲趋势中只有获利达到3倍ATR才退出或出现明确的趋势反转信号
dataframe.loc[strong_trend & ((dataframe['close'] > dataframe['open'] + dataframe['atr'] * 3) | (basic_exit & trend_reversal)), 'exit_long'] = 1
# 一般趋势中保持原有2倍ATR退出
dataframe.loc[normal_trend & ((dataframe['close'] > dataframe['open'] + dataframe['atr'] * 2) | basic_exit), 'exit_long'] = 1
# 非趋势或弱势:使用基础条件+1.5倍ATR
dataframe.loc[~strong_trend & ~normal_trend & (basic_exit | (dataframe['close'] > dataframe['open'] + dataframe['atr'] * 1.5)), 'exit_long'] = 1
# 记录退出决策日志
if len(dataframe[dataframe['exit_long'] == 1]) > 0:
last_exit = dataframe[dataframe['exit_long'] == 1].iloc[-1]
current_state = dataframe['market_state'].iloc[-1]
logger.info(f"[{metadata['pair']}] 触发退出信号,市场状态: {current_state}, 价格: {last_exit['close']:.2f}")
return dataframe
def detect_h1_rapid_rise(self, pair: str, dataframe: DataFrame, metadata: dict) -> tuple[bool, float]:
@ -278,12 +324,54 @@ class FreqaiPrimer(IStrategy):
logger.error(f"[{pair}] 剧烈拉升检测过程中发生错误: {str(e)}")
return False, 0.0
def custom_stoploss(self, pair: str, trade: 'Trade', current_time, current_rate: float,
def custom_stoploss(self, pair: str, trade: 'Trade', current_time, current_rate: float,
current_profit: float, **kwargs) -> float:
# 动态止损基于ATR
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1]
atr = last_candle['atr']
# 渐进式止损策略
if current_profit > 0.03: # 利润超过3%时
return -1.5 * atr / current_rate # 扩大止损范围,让利润奔跑
elif current_profit > 0.015: # 利润超过1.5%时
return -1.2 * atr / current_rate # 轻微扩大止损范围
if atr > 0:
return -1.0 * atr / current_rate # 收紧到1倍ATR
return -1.0 * atr / current_rate # 基础1倍ATR止损
return self.stoploss
def custom_exit(self, pair: str, trade: 'Trade', current_time, current_rate: float,
current_profit: float, **kwargs) -> float:
"""渐进式止盈逻辑"""
# 获取当前市场状态
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
current_state = dataframe['market_state'].iloc[-1] if 'market_state' in dataframe.columns else 'unknown'
# 定义渐进式止盈水平
profit_levels = {
# 状态: [(止盈触发利润, 止盈比例)]
'strong_bull': [(0.02, 0.3), (0.04, 0.5), (0.06, 0.7), (0.08, 0.9)], # 强劲牛市的渐进止盈
'weak_bull': [(0.015, 0.3), (0.03, 0.5), (0.05, 0.8)], # 弱牛市的渐进止盈
'neutral': [(0.01, 0.4), (0.02, 0.7), (0.03, 0.9)], # 中性市场的渐进止盈
'bear': [(0.008, 0.5), (0.015, 0.8), (0.025, 1.0)] # 熊市的渐进止盈(更保守)
}
# 默认使用中性市场的止盈设置
levels = profit_levels.get(current_state, profit_levels['neutral'])
# 确定当前应该止盈的比例
exit_ratio = 0.0
for profit_target, ratio in levels:
if current_profit >= profit_target:
exit_ratio = ratio
else:
break
# 记录渐进式止盈决策
if exit_ratio > 0:
logger.info(f"[{pair}] 渐进式止盈: 当前利润 {current_profit:.2%}, 市场状态 {current_state}, 止盈比例 {exit_ratio:.0%}")
# 返回应退出的比例0.0表示不退出1.0表示全部退出)
return exit_ratio