集成了 CCI、Williams %R 和布林带宽度三个指标到策略

This commit is contained in:
zhangkun9038@dingtalk.com 2026-01-31 00:25:30 +08:00
parent 60490ef078
commit 3141330a1b

View File

@ -979,6 +979,9 @@ class FreqaiPrimer(IStrategy):
dataframe['bb_lower_3m'] = bb_ma_3m - (bb_std_value * bb_std_3m)
dataframe['bb_upper_3m'] = bb_ma_3m + (bb_std_value * bb_std_3m)
# 计算布林带宽度百分比3m
dataframe['bb_width_3m'] = (dataframe['bb_upper_3m'] - dataframe['bb_lower_3m']) / bb_ma_3m * 100
# 使用 rolling 计算 RSI减少看前偏差
delta_3m = dataframe['close'].diff()
gain_3m = delta_3m.where(delta_3m > 0, 0).rolling(window=rsi_length_value).mean()
@ -997,6 +1000,12 @@ class FreqaiPrimer(IStrategy):
dataframe['kdj_d_3m'] = kdj_3m['STOCHd_9_3_3']
dataframe['kdj_j_3m'] = 3 * dataframe['kdj_k_3m'] - 2 * dataframe['kdj_d_3m']
# 新增 CCI 指标3m
dataframe['cci_3m'] = ta.cci(dataframe['high'], dataframe['low'], dataframe['close'], length=20)
# 新增 Williams %R 指标3m
dataframe['willr_3m'] = ta.willr(dataframe['high'], dataframe['low'], dataframe['close'], length=14)
# 新增 MACD 指标
macd_3m = ta.macd(dataframe['close'], fast=12, slow=26, signal=9)
dataframe['macd_3m'] = macd_3m['MACD_12_26_9']
@ -1060,6 +1069,9 @@ class FreqaiPrimer(IStrategy):
df_1h['bb_lower_1h'] = bb_ma_1h - (bb_std_value * bb_std_1h)
df_1h['bb_upper_1h'] = bb_ma_1h + (bb_std_value * bb_std_1h)
# 计算布林带宽度百分比1h
df_1h['bb_width_1h'] = (df_1h['bb_upper_1h'] - df_1h['bb_lower_1h']) / bb_ma_1h * 100
# 添加 EMA5 和 EMA20 用于趋势过滤方案2宽松条件
df_1h['ema_5_1h'] = df_1h['close'].ewm(span=5, adjust=False).mean()
df_1h['ema_20_1h'] = df_1h['close'].ewm(span=20, adjust=False).mean()
@ -1097,6 +1109,12 @@ class FreqaiPrimer(IStrategy):
df_1h['kdj_d_1h'] = kdj_1h['STOCHd_9_3_3']
df_1h['kdj_j_1h'] = 3 * df_1h['kdj_k_1h'] - 2 * df_1h['kdj_d_1h']
# 新增 CCI 指标1h
df_1h['cci_1h'] = ta.cci(df_1h['high'], df_1h['low'], df_1h['close'], length=20)
# 新增 Williams %R 指标1h
df_1h['willr_1h'] = ta.willr(df_1h['high'], df_1h['low'], df_1h['close'], length=14)
# 新增 MACD 指标
macd_1h = ta.macd(df_1h['close'], fast=12, slow=26, signal=9)
df_1h['macd_1h'] = macd_1h['MACD_12_26_9']
@ -1204,8 +1222,10 @@ class FreqaiPrimer(IStrategy):
# 增加 1h 趋势交易特征列
df_1h = df_1h[[
'date', 'rsi_1h', 'trend_1h', 'ema_50_1h', 'ema_200_1h',
'bb_lower_1h', 'bb_upper_1h', 'stochrsi_k_1h', 'stochrsi_d_1h',
'bb_lower_1h', 'bb_upper_1h', 'bb_width_1h', # 布林带 + 宽度
'stochrsi_k_1h', 'stochrsi_d_1h',
'kdj_k_1h', 'kdj_d_1h', 'kdj_j_1h', # KDJ 指标
'cci_1h', 'willr_1h', # CCI + Williams %R
'macd_1h', 'macd_signal_1h', 'ema_5_1h', 'ema_20_1h', 'ema5_cross_above_ema20',
# === 1h 趋势特征 ===
'adx_1h', 'plus_di_1h', 'minus_di_1h', # ADX 趋势强度
@ -1336,6 +1356,22 @@ class FreqaiPrimer(IStrategy):
kdj_3m_death_cross = (dataframe['kdj_k_3m'] > 80) & (dataframe['kdj_k_3m'] < dataframe['kdj_d_3m']) & (dataframe['kdj_k_3m'].shift(1) >= dataframe['kdj_d_3m'].shift(1))
kdj_3m_exit = kdj_3m_death_cross
# 条件6: CCI 超买出场1h CCI > 100
cci_overbought = pd.Series(False, index=dataframe.index)
if 'cci_1h' in dataframe.columns:
cci_overbought = dataframe['cci_1h'] > 100
# 条件7: Williams %R 超买出场3m %R > -20
willr_overbought = pd.Series(False, index=dataframe.index)
if 'willr_3m' in dataframe.columns:
willr_overbought = dataframe['willr_3m'] > -20
# 条件8: 布林带宽度突然收窄(趋势衰竭)
bb_width_shrink = pd.Series(False, index=dataframe.index)
if 'bb_width_1h' in dataframe.columns:
# 宽度从高位(>6%)快速收窄到低位(<3%
bb_width_shrink = (dataframe['bb_width_1h'] < 3) & (dataframe['bb_width_1h'].shift(5) > 6)
# === 新增1h 趋势反转检测 ===
# 计算趋势反转得分0-100得分越高越可能反转
if 'ema_bear_align_1h' in dataframe.columns and 'adx_1h' in dataframe.columns:
@ -1400,13 +1436,16 @@ class FreqaiPrimer(IStrategy):
self.strategy_log(f"[{metadata['pair']}] 警告:缺少趋势特征,趋势出场禁用")
# === 最终出场条件 ===
# 方案1传统条件 OR 趋势反转 OR KDJ 高位死叉
# 综合多个指标的出场信号
final_condition = (
breakout_condition |
volume_spike |
macd_downward |
rsi_overbought |
kdj_3m_exit |
cci_overbought |
willr_overbought |
bb_width_shrink |
trend_protected_exit
)
@ -1508,6 +1547,41 @@ class FreqaiPrimer(IStrategy):
tech_score += kdj_1h_score
tech_components += 1
# 1.7 CCI 得分1h 级别,避免半山腰抄底)
if 'cci_1h' in dataframe.columns:
# CCI < -100 超卖得满分CCI > 100 超买得 0 分
# 线性映射:-100 -> 100分0 -> 50分100 -> 0分
cci_score = ((100 - dataframe['cci_1h'].clip(-100, 100)) / 2).clip(0, 100)
tech_score += cci_score
tech_components += 1
# 1.8 Williams %R 得分3m 级别,精准抄底)
if 'willr_3m' in dataframe.columns:
# Williams %R 范围 -100 到 0
# %R < -80 深度超卖得满分,%R > -20 超买得 0 分
# 映射:-100 -> 100分-80 -> 100分-50 -> 50分-20 -> 0分0 -> 0分
willr_score = (((-20) - dataframe['willr_3m'].clip(-100, 0)) / 60 * 100).clip(0, 100)
tech_score += willr_score
tech_components += 1
# 1.9 布林带宽度得分(识别波动率变化)
if 'bb_width_1h' in dataframe.columns:
# 宽度过小(<2%)表示震荡末期,即将突破,得高分
# 宽度适中2-5%)正常,中等分
# 宽度过大(>8%)高波动,低分
bb_width_score = pd.Series(50.0, index=dataframe.index) # 默认 50 分
bb_width_score = bb_width_score.where(
dataframe['bb_width_1h'] >= 2,
((2 - dataframe['bb_width_1h'].clip(0, 2)) / 2 * 50 + 50) # <2% 时得 50-100 分
)
bb_width_score = bb_width_score.where(
dataframe['bb_width_1h'] <= 8,
((dataframe['bb_width_1h'].clip(8, 15) - 8) / 7 * -50 + 50) # >8% 时得 0-50 分
)
bb_width_score = bb_width_score.clip(0, 100)
tech_score += bb_width_score
tech_components += 1
# 计算技术指标平均得分
if tech_components > 0:
tech_score = tech_score / tech_components