diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index d55352d0..ea2192a1 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -682,32 +682,23 @@ class FreqaiPrimer(IStrategy): # 这样既能捕捉趋势启动,又能在趋势延续时继续入场 # ========== KDJ 过滤逻辑(1h + 3m 组合)========== - # 1h KDJ:大级别底部确认/方向过滤 - kdj_1h_filter = True - if 'kdj_k_1h' in dataframe.columns and 'kdj_j_1h' in dataframe.columns: - # 1h 允许做多条件(宽松版): - # - K < 40 且 J 上拐(J[t] > J[t-1]) - # - 或 K 从 <20 上穿 20(从超卖区抬头) - kdj_1h_low_upturn = (dataframe['kdj_k_1h'] < 40) & (dataframe['kdj_j_1h'] > dataframe['kdj_j_1h'].shift(1)) - kdj_1h_from_oversold = (dataframe['kdj_k_1h'] >= 20) & (dataframe['kdj_k_1h'].shift(1) < 20) - kdj_1h_allow = kdj_1h_low_upturn | kdj_1h_from_oversold - - # 1h 禁止做多条件:K > 80 且 J 下拐 - kdj_1h_block = (dataframe['kdj_k_1h'] > 80) & (dataframe['kdj_j_1h'] < dataframe['kdj_j_1h'].shift(1)) - - # 最终过滤:允许且不被禁止 - kdj_1h_filter = kdj_1h_allow & ~kdj_1h_block + # KDJ 作为辅助信号,不作为强制条件 - # 3m KDJ:具体入场触发 - kdj_3m_trigger = True + # 1h KDJ:大级别底部确认/方向过滤(只禁止极端高位) + kdj_1h_block = False + if 'kdj_k_1h' in dataframe.columns and 'kdj_j_1h' in dataframe.columns: + # 只禁止极端高位:K > 85 且 J 下拐 + kdj_1h_block = (dataframe['kdj_k_1h'] > 85) & (dataframe['kdj_j_1h'] < dataframe['kdj_j_1h'].shift(1)) + + # 3m KDJ:作为额外加分条件(满足则增加信号质量) + kdj_3m_bonus = 0 if 'kdj_k_3m' in dataframe.columns and 'kdj_d_3m' in dataframe.columns: - # 3m 低位金叉:K < 30 且 K 上穿 D - kdj_3m_golden_cross = (dataframe['kdj_k_3m'] < 30) & (dataframe['kdj_k_3m'] > dataframe['kdj_d_3m']) & (dataframe['kdj_k_3m'].shift(1) <= dataframe['kdj_d_3m'].shift(1)) - - # 可选:J 从 <0 回到 0 以上(防抖) + # 3m 低位金叉:K < 40 且 K 上穿 D(放宽到 40) + kdj_3m_golden_cross = (dataframe['kdj_k_3m'] < 40) & (dataframe['kdj_k_3m'] > dataframe['kdj_d_3m']) & (dataframe['kdj_k_3m'].shift(1) <= dataframe['kdj_d_3m'].shift(1)) + # 或 J 从负值区回正 kdj_3m_j_recovery = (dataframe['kdj_j_3m'] > 0) & (dataframe['kdj_j_3m'].shift(1) <= 0) - - kdj_3m_trigger = kdj_3m_golden_cross | kdj_3m_j_recovery + # 作为加分项(+1 分) + kdj_3m_bonus = (kdj_3m_golden_cross | kdj_3m_j_recovery).astype(int) # 合并 KDJ 过滤到最终条件 # ========== 原有 EMA 趋势过滤 ========== @@ -737,11 +728,13 @@ class FreqaiPrimer(IStrategy): stochrsi_condition_1h.astype(int) + macd_condition_1h.astype(int) + (volume_spike | bb_width_condition).astype(int) + # 成交量或布林带宽度满足其一即可 - trend_confirmation.astype(int) + trend_confirmation.astype(int) + + kdj_3m_bonus # KDJ 3m 作为加分项 ) - # 最终条件:基本条件 + EMA趋势过滤(方案2:宽松版)+ KDJ过滤 + # 最终条件:基本条件 + EMA趋势过滤 - KDJ高位禁止 + # KDJ 不再是必需条件,只在极端高位时禁止入场 basic_condition = condition_count >= self.min_condition_count.value - final_condition = basic_condition & ema_trend_filter & kdj_1h_filter & kdj_3m_trigger + final_condition = basic_condition & ema_trend_filter & ~kdj_1h_block # 设置入场信号 dataframe.loc[final_condition, 'enter_long'] = 1