综合3m,15m,1h的各个指标的入场出场

This commit is contained in:
Ubuntu 2025-08-31 19:52:17 +08:00
parent dc5a388731
commit e627cca90f

View File

@ -388,40 +388,40 @@ class FreqaiPrimer(IStrategy):
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 入场信号主要依据1小时周期
# 条件1: 价格接近布林带下轨
close_to_bb_lower_1h = (dataframe['close'] <= dataframe['bb_lower_1h'] * 1.02)
# 获取当前市场状态
current_state = dataframe['market_state'].iloc[-1] if 'market_state' in dataframe.columns else 'neutral'
# 条件2: RSI 不高于阈值(更严格
rsi_condition_1h = dataframe['rsi_1h'] < 40 # 进一步收紧 RSI 阈值
# 条件1: 价格接近布林带下轨(允许一定偏差
close_to_bb_lower_1h = (dataframe['close'] <= dataframe['bb_lower_1h'] * 1.03) # 放宽到3%偏差
# 条件3: StochRSI 处于超卖区域(更严格)
stochrsi_condition_1h = (dataframe['stochrsi_k_1h'] < 20) & (dataframe['stochrsi_d_1h'] < 20) # 进一步收紧 StochRSI 阈值
# 条件2: RSI 不高于阈值(根据市场状态动态调整)
rsi_threshold = 45 if current_state in ['strong_bull', 'weak_bull'] else 40
rsi_condition_1h = dataframe['rsi_1h'] < rsi_threshold
# 条件3: StochRSI 处于超卖区域(根据市场状态动态调整)
stochrsi_threshold = 30 if current_state in ['strong_bull', 'weak_bull'] else 20
stochrsi_condition_1h = (dataframe['stochrsi_k_1h'] < stochrsi_threshold) & (dataframe['stochrsi_d_1h'] < stochrsi_threshold)
# 条件4: MACD 上升趋势
macd_condition_1h = dataframe['macd_1h'] > dataframe['macd_signal_1h']
# 条件5: 成交量显著放大
# 条件5: 成交量显著放大(可选条件)
volume_spike = dataframe['volume'] > dataframe['volume_ma'] * 1.5
# 条件6: 布林带宽度过滤(避免窄幅震荡)
bb_width = (dataframe['bb_upper_1h'] - dataframe['bb_lower_1h']) / dataframe['close']
bb_width_condition = bb_width > 0.02 # 布林带宽度大于2%
# 辅助条件: 3m 和 15m 趋势确认
trend_confirmation = (dataframe['trend_3m'] == 1) & (dataframe['trend_15m'] == 1)
# 辅助条件: 3m 和 15m 趋势确认(允许部分时间框架不一致)
trend_confirmation = (dataframe['trend_3m'] == 1) | (dataframe['trend_15m'] == 1)
# 增加布林带宽度过滤器,避免窄幅震荡市场
bb_width_condition = (dataframe['bb_upper_1h'] - dataframe['bb_lower_1h']) / dataframe['close'] > 0.03 # 布林带宽度大于3%
# 合并所有条件(增加成交量和布林带宽度过滤)
# 合并所有条件(减少强制性条件)
final_condition = (
close_to_bb_lower_1h &
rsi_condition_1h & # 严格要求RSI满足条件
stochrsi_condition_1h & # 严格要求StochRSI满足条件
rsi_condition_1h &
stochrsi_condition_1h &
macd_condition_1h &
volume_spike & # 成交量显著放大
bb_width_condition & # 布林带宽度过滤
(volume_spike | bb_width_condition) & # 成交量或布林带宽度满足其一即可
trend_confirmation
)
@ -434,6 +434,7 @@ class FreqaiPrimer(IStrategy):
logger.info(f" - RSI 超卖: {rsi_condition_1h.sum()}")
logger.info(f" - StochRSI 超卖: {stochrsi_condition_1h.sum()}")
logger.info(f" - MACD 上升趋势: {macd_condition_1h.sum()}")
logger.info(f" - 成交量或布林带宽度: {(volume_spike | bb_width_condition).sum()}")
logger.info(f" - 趋势确认: {trend_confirmation.sum()}")
logger.info(f" - 最终条件: {final_condition.sum()}")
@ -442,84 +443,6 @@ class FreqaiPrimer(IStrategy):
logger.info(f"[{metadata['pair']}] 发现入场信号数量: {dataframe['enter_long'].sum()}")
return dataframe
# 缓存数据框以便在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)
# 极端强劲趋势条件:熊牛得分>95
extreme_strong_trend = (dataframe['market_score'] > 95)
# 获取15m数据进行趋势确认
df_15m = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='15m')
# 确保df_15m中包含rsi_15m列如果没有则计算
try:
import pandas_ta as ta
if 'rsi_15m' not in df_15m.columns:
# 使用pandas_ta计算14期RSI
rsi_series = ta.rsi(df_15m['close'], length=14)
df_15m['rsi_15m'] = rsi_series
except Exception as e:
# 如果计算失败,创建一个默认值列
logger.warning(f"[{metadata['pair']}] 计算15m RSI时出错: {e}")
df_15m['rsi_15m'] = 50 # 设置默认值为中性
# 重命名date列并保留必要的列
df_15m = df_15m[['date', 'rsi_15m']].rename(columns={'date': 'date_15m'})
# 合并数据
merged_data = dataframe.copy()
# 创建合并列
merged_data['rsi_15m'] = 50 # 设置默认值
# 尝试合并数据
try:
# 使用更简单的方式直接将df_15m的rsi_15m列映射到dataframe
# 创建一个日期到rsi的映射字典
date_rsi_map = df_15m.set_index('date_15m')['rsi_15m'].to_dict()
# 使用映射填充rsi_15m列
merged_data['rsi_15m'] = merged_data['date'].map(date_rsi_map).ffill().bfill()
except Exception as e:
logger.warning(f"[{metadata['pair']}] 合并15m数据时出错: {e}")
# 趋势反转信号15m RSI超买
trend_reversal = merged_data['rsi_15m'] > 75
# 动态调整退出条件 - 提高ATR倍数以增加单笔盈利潜力
# 强劲趋势中大幅提高ATR倍数到5.5倍,充分利用趋势利润
# 但在极端强劲趋势(market_score>95)下不给出退出信号
dataframe.loc[strong_trend & ~extreme_strong_trend & ((dataframe['close'] > dataframe['open'] + dataframe['atr'] * 5.5) | (basic_exit & trend_reversal)), 'exit_long'] = 1
# 一般趋势中提高到4倍ATR退出
# 但在极端强劲趋势(market_score>95)下不给出退出信号
dataframe.loc[normal_trend & ~extreme_strong_trend & ((dataframe['close'] > dataframe['open'] + dataframe['atr'] * 4) | basic_exit), 'exit_long'] = 1
# 非趋势或弱势保持2倍ATR退出
# 但在极端强劲趋势(market_score>95)下不给出退出信号
# 记录退出决策日志
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}")
# 记录因极端强劲趋势阻止的退出信号
extreme_strong_prevented = dataframe[extreme_strong_trend & ((strong_trend & ((dataframe['close'] > dataframe['open'] + dataframe['atr'] * 5.5) | (basic_exit & trend_reversal))) | (normal_trend & ((dataframe['close'] > dataframe['open'] + dataframe['atr'] * 4) | basic_exit)))]
if len(extreme_strong_prevented) > 0:
logger.info(f"[{metadata['pair']}] 由于极端强劲趋势(market_score>95),阻止了 {len(extreme_strong_prevented)} 个潜在的退出信号")
return dataframe
def detect_h1_rapid_rise(self, pair: str, dataframe: DataFrame, metadata: dict) -> tuple[bool, float]:
"""