hyperopted
This commit is contained in:
parent
ca1b2595a6
commit
3785332155
@ -2,7 +2,7 @@ import warnings
|
||||
warnings.filterwarnings("ignore", category=UserWarning, module="pandas_ta")
|
||||
|
||||
import logging
|
||||
from freqtrade.strategy import IStrategy
|
||||
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
|
||||
from pandas import DataFrame
|
||||
import pandas_ta as ta
|
||||
from freqtrade.persistence import Trade
|
||||
@ -80,17 +80,17 @@ class FreqaiPrimer(IStrategy):
|
||||
timeframe = "3m" # 主时间框架为 3 分钟
|
||||
can_short = False # 禁用做空
|
||||
|
||||
# 自定义指标参数
|
||||
bb_length = 20
|
||||
bb_std = 2.0
|
||||
rsi_length = 14
|
||||
rsi_overbought = 58 # 超买阈值
|
||||
rsi_oversold = 42 # 放宽超卖阈值,增加入场信号
|
||||
# 自定义指标参数 - 使用Hyperopt可优化参数
|
||||
bb_length = IntParameter(10, 30, default=20, optimize=True, load=True, name='bb_length', space='buy')
|
||||
bb_std = DecimalParameter(1.5, 3.0, decimals=1, default=2.0, optimize=True, load=True, name='bb_std', space='buy')
|
||||
rsi_length = IntParameter(7, 21, default=14, optimize=True, load=True, name='rsi_length', space='buy')
|
||||
rsi_overbought = IntParameter(50, 70, default=58, optimize=True, load=True, name='rsi_overbought', space='buy')
|
||||
rsi_oversold = IntParameter(30, 50, default=42, optimize=True, load=True, name='rsi_oversold', space='buy')
|
||||
|
||||
# 剧烈拉升检测参数
|
||||
H1_MAX_CANDLES = 200 # 检查最近200根1h K线
|
||||
H1_RAPID_RISE_THRESHOLD = 0.11 # 5%的抬升阈值
|
||||
H1_MAX_CONSECUTIVE_CANDLES = 2 # 最多连续3根K线内检查
|
||||
# 剧烈拉升检测参数 - 使用Hyperopt可优化参数
|
||||
h1_max_candles = IntParameter(100, 300, default=200, optimize=True, load=True, name='h1_max_candles', space='buy')
|
||||
h1_rapid_rise_threshold = DecimalParameter(0.05, 0.15, decimals=3, default=0.11, optimize=True, load=True, name='h1_rapid_rise_threshold', space='buy')
|
||||
h1_max_consecutive_candles = IntParameter(1, 4, default=2, optimize=True, load=True, name='h1_max_consecutive_candles', space='buy')
|
||||
|
||||
def informative_pairs(self):
|
||||
pairs = self.dp.current_whitelist()
|
||||
@ -107,10 +107,14 @@ class FreqaiPrimer(IStrategy):
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
# 计算 3m 周期的指标
|
||||
bb_3m = ta.bbands(dataframe['close'], length=self.bb_length, std=self.bb_std)
|
||||
dataframe['bb_lower_3m'] = bb_3m[f'BBL_{self.bb_length}_{self.bb_std}']
|
||||
dataframe['bb_upper_3m'] = bb_3m[f'BBU_{self.bb_length}_{self.bb_std}']
|
||||
dataframe['rsi_3m'] = ta.rsi(dataframe['close'], length=self.rsi_length)
|
||||
bb_length_value = self.bb_length.value
|
||||
bb_std_value = self.bb_std.value
|
||||
rsi_length_value = self.rsi_length.value
|
||||
|
||||
bb_3m = ta.bbands(dataframe['close'], length=bb_length_value, std=bb_std_value)
|
||||
dataframe['bb_lower_3m'] = bb_3m[f'BBL_{bb_length_value}_{bb_std_value}']
|
||||
dataframe['bb_upper_3m'] = bb_3m[f'BBU_{bb_length_value}_{bb_std_value}']
|
||||
dataframe['rsi_3m'] = ta.rsi(dataframe['close'], length=rsi_length_value)
|
||||
|
||||
# 新增 StochRSI 指标
|
||||
stochrsi_3m = ta.stochrsi(dataframe['close'], length=14, rsi_length=14)
|
||||
@ -141,9 +145,9 @@ class FreqaiPrimer(IStrategy):
|
||||
df_15m['ema_200_15m'] = ta.ema(df_15m['close'], length=200)
|
||||
|
||||
# 新增 StochRSI 指标
|
||||
stochrsi_15m = ta.stochrsi(df_15m['close'], length=14, rsi_length=14)
|
||||
df_15m['stochrsi_k_15m'] = stochrsi_15m['STOCHRSIk_14_14_3_3']
|
||||
df_15m['stochrsi_d_15m'] = stochrsi_15m['STOCHRSId_14_14_3_3']
|
||||
stochrsi_15m = ta.stochrsi(df_15m['close'], length=rsi_length_value, rsi_length=rsi_length_value)
|
||||
df_15m['stochrsi_k_15m'] = stochrsi_15m[f'STOCHRSIk_{rsi_length_value}_{rsi_length_value}_3_3']
|
||||
df_15m['stochrsi_d_15m'] = stochrsi_15m[f'STOCHRSId_{rsi_length_value}_{rsi_length_value}_3_3']
|
||||
|
||||
# 新增 MACD 指标
|
||||
macd_15m = ta.macd(df_15m['close'], fast=12, slow=26, signal=9)
|
||||
@ -163,20 +167,20 @@ class FreqaiPrimer(IStrategy):
|
||||
df_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1h')
|
||||
|
||||
# 计算 1h 布林带
|
||||
bb_1h = ta.bbands(df_1h['close'], length=self.bb_length, std=self.bb_std)
|
||||
df_1h['bb_lower_1h'] = bb_1h[f'BBL_{self.bb_length}_{self.bb_std}']
|
||||
df_1h['bb_upper_1h'] = bb_1h[f'BBU_{self.bb_length}_{self.bb_std}']
|
||||
bb_1h = ta.bbands(df_1h['close'], length=bb_length_value, std=bb_std_value)
|
||||
df_1h['bb_lower_1h'] = bb_1h[f'BBL_{bb_length_value}_{bb_std_value}']
|
||||
df_1h['bb_upper_1h'] = bb_1h[f'BBU_{bb_length_value}_{bb_std_value}']
|
||||
|
||||
# 计算 1h RSI 和 EMA
|
||||
df_1h['rsi_1h'] = ta.rsi(df_1h['close'], length=self.rsi_length)
|
||||
df_1h['rsi_1h'] = ta.rsi(df_1h['close'], length=rsi_length_value)
|
||||
df_1h['ema_50_1h'] = ta.ema(df_1h['close'], length=50) # 1h 50周期EMA
|
||||
df_1h['ema_200_1h'] = ta.ema(df_1h['close'], length=200) # 1h 200周期EMA
|
||||
df_1h['trend_1h'] = df_1h['close'] > df_1h['ema_50_1h'] # 1h上涨趋势
|
||||
|
||||
# 新增 StochRSI 指标
|
||||
stochrsi_1h = ta.stochrsi(df_1h['close'], length=14, rsi_length=14)
|
||||
df_1h['stochrsi_k_1h'] = stochrsi_1h['STOCHRSIk_14_14_3_3']
|
||||
df_1h['stochrsi_d_1h'] = stochrsi_1h['STOCHRSId_14_14_3_3']
|
||||
stochrsi_1h = ta.stochrsi(df_1h['close'], length=rsi_length_value, rsi_length=rsi_length_value)
|
||||
df_1h['stochrsi_k_1h'] = stochrsi_1h[f'STOCHRSIk_{rsi_length_value}_{rsi_length_value}_3_3']
|
||||
df_1h['stochrsi_d_1h'] = stochrsi_1h[f'STOCHRSId_{rsi_length_value}_{rsi_length_value}_3_3']
|
||||
|
||||
# 新增 MACD 指标
|
||||
macd_1h = ta.macd(df_1h['close'], fast=12, slow=26, signal=9)
|
||||
@ -187,11 +191,7 @@ class FreqaiPrimer(IStrategy):
|
||||
# 验证 MACD 列是否正确生成
|
||||
logger.info(f"[{metadata['pair']}] 1小时 MACD 列: {list(macd_1h.columns)}")
|
||||
|
||||
# 新增 StochRSI 指标
|
||||
stochrsi_1h = ta.stochrsi(df_1h['close'], length=14, rsi_length=14)
|
||||
df_1h['stochrsi_k_1h'] = stochrsi_1h['STOCHRSIk_14_14_3_3']
|
||||
df_1h['stochrsi_d_1h'] = stochrsi_1h['STOCHRSId_14_14_3_3']
|
||||
|
||||
# 确保 StochRSI 指标已正确计算
|
||||
# 将 1h 数据重新索引到主时间框架 (3m),并填充缺失值
|
||||
df_1h = df_1h.set_index('date').reindex(dataframe['date']).ffill().bfill().reset_index()
|
||||
df_1h = df_1h.rename(columns={'index': 'date'})
|
||||
@ -420,20 +420,25 @@ class FreqaiPrimer(IStrategy):
|
||||
# 获取1小时K线数据
|
||||
df_1h = self.dp.get_pair_dataframe(pair=pair, timeframe='1h')
|
||||
|
||||
# 获取当前优化参数值
|
||||
max_candles = self.h1_max_candles.value
|
||||
rapid_rise_threshold = self.h1_rapid_rise_threshold.value
|
||||
max_consecutive_candles = self.h1_max_consecutive_candles.value
|
||||
|
||||
# 确保有足够的K线数据
|
||||
if len(df_1h) < self.H1_MAX_CANDLES:
|
||||
logger.warning(f"[{pair}] 1h K线数据不足 {self.H1_MAX_CANDLES} 根,当前只有 {len(df_1h)} 根,无法完整检测剧烈拉升")
|
||||
if len(df_1h) < max_candles:
|
||||
logger.warning(f"[{pair}] 1h K线数据不足 {max_candles} 根,当前只有 {len(df_1h)} 根,无法完整检测剧烈拉升")
|
||||
return False
|
||||
|
||||
# 获取最近的K线
|
||||
recent_data = df_1h.iloc[-self.H1_MAX_CANDLES:].copy()
|
||||
recent_data = df_1h.iloc[-max_candles:].copy()
|
||||
|
||||
# 检查连续最多3根K线内的最大涨幅
|
||||
# 检查连续最多几根K线内的最大涨幅
|
||||
rapid_rise_detected = False
|
||||
max_rise = 0
|
||||
|
||||
for i in range(len(recent_data) - self.H1_MAX_CONSECUTIVE_CANDLES + 1):
|
||||
window_data = recent_data.iloc[i:i + self.H1_MAX_CONSECUTIVE_CANDLES]
|
||||
for i in range(len(recent_data) - max_consecutive_candles + 1):
|
||||
window_data = recent_data.iloc[i:i + max_consecutive_candles]
|
||||
window_low = window_data['low'].min()
|
||||
window_high = window_data['high'].max()
|
||||
|
||||
@ -444,9 +449,9 @@ class FreqaiPrimer(IStrategy):
|
||||
max_rise = rise_percentage
|
||||
|
||||
# 检查是否超过阈值
|
||||
if rise_percentage >= self.H1_RAPID_RISE_THRESHOLD:
|
||||
if rise_percentage >= rapid_rise_threshold:
|
||||
rapid_rise_detected = True
|
||||
logger.info(f"[{pair}] 检测到剧烈拉升: 从 {window_low:.2f} 到 {window_high:.2f} ({rise_percentage:.2%}) 在 {self.H1_MAX_CONSECUTIVE_CANDLES} 根K线内")
|
||||
logger.info(f"[{pair}] 检测到剧烈拉升: 从 {window_low:.2f} 到 {window_high:.2f} ({rise_percentage:.2%}) 在 {max_consecutive_candles} 根K线内")
|
||||
break
|
||||
|
||||
current_price = recent_data['close'].iloc[-1]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user