波动率相关特征freqai新回归属性
This commit is contained in:
parent
d83213dcf7
commit
2bbf5209bb
@ -23,6 +23,39 @@
|
||||
"TRAILING_STOP_START": 0.045
|
||||
},
|
||||
"protection": {},
|
||||
"model_training_parameters": {
|
||||
"price_value_divergence": {
|
||||
"model": "LightGBMRegressor",
|
||||
"model_params": {
|
||||
"n_estimators": 200,
|
||||
"learning_rate": 0.05,
|
||||
"num_leaves": 31,
|
||||
"verbose": -1
|
||||
}
|
||||
},
|
||||
"optimal_first_length": {
|
||||
"model": "LightGBMClassifier",
|
||||
"model_params": {
|
||||
"n_estimators": 150,
|
||||
"learning_rate": 0.1,
|
||||
"num_leaves": 15,
|
||||
"max_depth": 8,
|
||||
"min_child_samples": 10,
|
||||
"class_weight": "balanced",
|
||||
"verbose": -1
|
||||
}
|
||||
},
|
||||
"volatility_forecast": {
|
||||
"model": "LightGBMRegressor",
|
||||
"model_params": {
|
||||
"n_estimators": 180,
|
||||
"learning_rate": 0.08,
|
||||
"num_leaves": 25,
|
||||
"max_depth": 6,
|
||||
"verbose": -1
|
||||
}
|
||||
}
|
||||
},
|
||||
"trailing": {
|
||||
"trailing_stop": true,
|
||||
"trailing_stop_positive": 0.0125,
|
||||
|
||||
@ -162,6 +162,16 @@ class FreqaiPrimer(IStrategy):
|
||||
"class_weight": "balanced",
|
||||
"verbose": -1,
|
||||
}
|
||||
},
|
||||
"volatility_forecast": { # 新增:波动率预测模型
|
||||
"model": "LightGBMRegressor",
|
||||
"model_params": {
|
||||
"n_estimators": 180,
|
||||
"learning_rate": 0.08,
|
||||
"num_leaves": 25,
|
||||
"max_depth": 6,
|
||||
"verbose": -1,
|
||||
}
|
||||
}
|
||||
},
|
||||
"fit_live_predictions_candles": 100,
|
||||
@ -225,11 +235,18 @@ class FreqaiPrimer(IStrategy):
|
||||
|
||||
dataframe["ema200"] = ta.EMA(dataframe, timeperiod=200)
|
||||
dataframe["%-price_value_divergence"] = (dataframe["close"] - dataframe["ema200"]) / dataframe["ema200"]
|
||||
|
||||
# 新增:波动率相关特征
|
||||
dataframe["%-atr-period"] = ta.ATR(dataframe, timeperiod=period)
|
||||
dataframe["%-volatility_ratio"] = dataframe["%-atr-period"] / dataframe["close"]
|
||||
dataframe["%-price_range"] = (dataframe["high"] - dataframe["low"]) / dataframe["close"]
|
||||
dataframe["%-volume_volatility"] = dataframe["volume"].pct_change().rolling(period).std()
|
||||
|
||||
columns_to_clean = [
|
||||
"%-rsi-period", "%-mfi-period", "%-sma-period", "%-ema-period", "%-adx-period",
|
||||
"bb_lowerband-period", "bb_middleband-period", "bb_upperband-period",
|
||||
"%-bb_width-period", "%-relative_volume-period", "%-price_value_divergence"
|
||||
"%-bb_width-period", "%-relative_volume-period", "%-price_value_divergence",
|
||||
"%-atr-period", "%-volatility_ratio", "%-price_range", "%-volume_volatility"
|
||||
]
|
||||
for col in columns_to_clean:
|
||||
dataframe[col] = dataframe[col].replace([np.inf, -np.inf], 0).ffill().fillna(0)
|
||||
@ -256,10 +273,21 @@ class FreqaiPrimer(IStrategy):
|
||||
price_divergence = dataframe["&-price_value_divergence"].replace([np.inf, -np.inf], 0).ffill().fillna(0)
|
||||
dataframe["&-price_value_divergence"] = price_divergence.astype(np.float64)
|
||||
|
||||
# 新增:波动率预测目标
|
||||
# 计算未来12根K线的真实波动率
|
||||
future_high = dataframe['high'].shift(-12).rolling(12).max()
|
||||
future_low = dataframe['low'].shift(-12).rolling(12).min()
|
||||
dataframe["&-volatility_forecast"] = ((future_high - future_low) / dataframe['close']).replace([np.inf, -np.inf], 0).ffill().fillna(0)
|
||||
|
||||
# 验证数据类型和范围
|
||||
if not np.isfinite(dataframe["&-price_value_divergence"]).all():
|
||||
logger.warning(f"[{pair}] price_value_divergence包含非有限值,进行清理")
|
||||
dataframe["&-price_value_divergence"] = dataframe["&-price_value_divergence"].replace([np.inf, -np.inf, np.nan], 0.0)
|
||||
|
||||
# 清理波动率预测值
|
||||
if not np.isfinite(dataframe["&-volatility_forecast"]).all():
|
||||
logger.warning(f"[{pair}] volatility_forecast包含非有限值,进行清理")
|
||||
dataframe["&-volatility_forecast"] = dataframe["&-volatility_forecast"].replace([np.inf, -np.inf, np.nan], 0.0)
|
||||
|
||||
# 新增:分类模型优化 first_length
|
||||
# 基于市场状态预测最优的 first_length 分类(2, 4, 6, 8, 10)
|
||||
@ -600,6 +628,22 @@ class FreqaiPrimer(IStrategy):
|
||||
logger.info("==============================================")
|
||||
self.stats_logged = True
|
||||
|
||||
# 新增:使用波动率预测结果进行风险调整
|
||||
if "&-volatility_forecast" in dataframe.columns:
|
||||
# 计算波动率因子,用于仓位调整
|
||||
dataframe["volatility_factor"] = 1 / (1 + dataframe["&-volatility_forecast"] * 10)
|
||||
|
||||
# 计算动态止损
|
||||
dataframe["dynamic_stop_loss"] = self.stoploss * (1 + dataframe["&-volatility_forecast"] * 2)
|
||||
|
||||
# 波动率阈值判断
|
||||
high_volatility = dataframe["&-volatility_forecast"] > 0.05 # 5%以上认为是高波动
|
||||
low_volatility = dataframe["&-volatility_forecast"] < 0.02 # 2%以下认为是低波动
|
||||
|
||||
logger.info(f"[{pair}] 波动率分析 - 当前: {dataframe['&-volatility_forecast'].iloc[-1]:.4f}, "
|
||||
f"因子: {dataframe['volatility_factor'].iloc[-1]:.2f}, "
|
||||
f"动态止损: {dataframe['dynamic_stop_loss'].iloc[-1]:.4f}")
|
||||
|
||||
return dataframe
|
||||
|
||||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
@ -622,6 +666,16 @@ class FreqaiPrimer(IStrategy):
|
||||
stochrsi_min = 25
|
||||
stochrsi_max = 45
|
||||
stochrsi_threshold = self.linear_map(trend_score, 0, 100, stochrsi_max, stochrsi_min)
|
||||
|
||||
# 新增:基于波动率预测的动态调整
|
||||
volatility_factor = 1.0
|
||||
if "volatility_factor" in dataframe.columns:
|
||||
volatility_factor = dataframe["volatility_factor"].iloc[-1] if len(dataframe) > 0 else 1.0
|
||||
|
||||
# 根据波动率调整所有阈值(高波动时更严格)
|
||||
volume_z_score_threshold *= volatility_factor
|
||||
rsi_threshold *= volatility_factor
|
||||
stochrsi_threshold *= volatility_factor
|
||||
|
||||
# 计算熊市信号和 STOCHRSI 超买信号
|
||||
bearish_signal = self.is_bearish_market(dataframe, metadata, timeframe="1h")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user