集成了 CCI、Williams %R 和布林带宽度三个指标到策略
This commit is contained in:
parent
60490ef078
commit
3141330a1b
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user