265 lines
12 KiB
Diff
265 lines
12 KiB
Diff
diff --git "a/4. **\346\270\205\347\220\206\347\274\223\345\255\230**\357\274\232" "b/4. **\346\270\205\347\220\206\347\274\223\345\255\230**\357\274\232"
|
||
new file mode 100644
|
||
index 0000000..3bb7671
|
||
--- /dev/null
|
||
+++ "b/4. **\346\270\205\347\220\206\347\274\223\345\255\230**\357\274\232"
|
||
@@ -0,0 +1,5 @@
|
||
+
|
||
+<<<<<<< HEAD
|
||
+=======
|
||
+ rm -rf /freqtrade/user_data/models/test62/
|
||
+>>>>>>> Snippet
|
||
diff --git "a/5. **\351\207\215\346\226\260\350\256\255\347\273\203**\357\274\232" "b/5. **\351\207\215\346\226\260\350\256\255\347\273\203**\357\274\232"
|
||
new file mode 100644
|
||
index 0000000..8a18d3d
|
||
--- /dev/null
|
||
+++ "b/5. **\351\207\215\346\226\260\350\256\255\347\273\203**\357\274\232"
|
||
@@ -0,0 +1,5 @@
|
||
+
|
||
+<<<<<<< HEAD
|
||
+=======
|
||
+ freqtrade trade --config config_examples/config_freqai.okx.json --strategy FreqaiExampleStrategy
|
||
+>>>>>>> Snippet
|
||
diff --git a/config_examples/config_freqai.okx.json b/config_examples/config_freqai.okx.json
|
||
index 1816983..4535010 100644
|
||
--- a/config_examples/config_freqai.okx.json
|
||
+++ b/config_examples/config_freqai.okx.json
|
||
@@ -67,45 +67,31 @@
|
||
"freqaimodel": "CatboostClassifier",
|
||
"purge_old_models": 2,
|
||
"train_period_days": 15,
|
||
- "identifier": "test62",
|
||
- "train_period_days": 30,
|
||
- "backtest_period_days": 10,
|
||
+ "train_period_days": 180,
|
||
+ "backtest_period_days": 60,
|
||
"live_retrain_hours": 0,
|
||
"feature_selection": {
|
||
"method": "recursive_elimination"
|
||
},
|
||
"feature_parameters": {
|
||
- "include_timeframes": [
|
||
- "3m",
|
||
- "15m",
|
||
- "1h"
|
||
- ],
|
||
- "include_corr_pairlist": [
|
||
- "BTC/USDT",
|
||
- "SOL/USDT"
|
||
- ],
|
||
- "label_period_candles": 20,
|
||
- "include_shifted_candles": 2,
|
||
- "DI_threshold": 0.9,
|
||
+ "include_timeframes": ["15m"],
|
||
+ "include_corr_pairlist": ["BTC/USDT"],
|
||
+ "label_period_candles": 10,
|
||
+ "include_shifted_candles": 1,
|
||
+ "DI_threshold": 0.7,
|
||
"weight_factor": 0.9,
|
||
"principal_component_analysis": false,
|
||
"use_SVM_to_remove_outliers": false,
|
||
- "indicator_periods_candles": [
|
||
- 10,
|
||
- 20,
|
||
- 50
|
||
- ],
|
||
- "plot_feature_importances": 0
|
||
+ "indicator_periods_candles": [14],
|
||
},
|
||
"data_split_parameters": {
|
||
"test_size": 0.2
|
||
},
|
||
- "model_training_parameters": {
|
||
- "n_estimators": 100,
|
||
- "learning_rate": 0.05,
|
||
- "max_depth": 5,
|
||
- "num_leaves": 31
|
||
- }
|
||
+ "model_training_parameters": {
|
||
+ "n_estimators": 100,
|
||
+ "learning_rate": 0.05,
|
||
+ "max_depth": 5
|
||
+ }
|
||
},
|
||
"api_server": {
|
||
"enabled": true,
|
||
diff --git a/docker-compose.yml b/docker-compose.yml
|
||
index defe81e..aeb31e6 100644
|
||
--- a/docker-compose.yml
|
||
+++ b/docker-compose.yml
|
||
@@ -64,7 +64,7 @@ services:
|
||
command: >
|
||
backtesting
|
||
--logfile /freqtrade/user_data/logs/freqtrade.log
|
||
- --freqaimodel LightGBMRegressor
|
||
+ --freqaimodel XGBoostRegressor
|
||
--config /freqtrade/config_examples/config_freqai.okx.json
|
||
--config /freqtrade/templates/FreqaiExampleStrategy.json
|
||
--strategy-path /freqtrade/templates
|
||
diff --git a/freqtrade/templates/FreqaiExampleStrategy.py b/freqtrade/templates/FreqaiExampleStrategy.py
|
||
index 688e644..e27e17b 100644
|
||
--- a/freqtrade/templates/FreqaiExampleStrategy.py
|
||
+++ b/freqtrade/templates/FreqaiExampleStrategy.py
|
||
@@ -30,12 +30,12 @@ class FreqaiExampleStrategy(IStrategy):
|
||
|
||
# FreqAI 配置
|
||
freqai_info = {
|
||
- "model": "XGBoostRegressor", # 改用XGBoost
|
||
+ "model": "CatboostClassifier", # 与config保持一致
|
||
"feature_parameters": {
|
||
- "include_timeframes": ["5m", "15m", "1h"],
|
||
- "include_corr_pairlist": [],
|
||
- "label_period_candles": 12,
|
||
- "include_shifted_candles": 3,
|
||
+ "include_timeframes": ["3m", "15m", "1h"], # 与config一致
|
||
+ "include_corr_pairlist": ["BTC/USDT", "SOL/USDT"], # 添加相关交易对
|
||
+ "label_period_candles": 20, # 与config一致
|
||
+ "include_shifted_candles": 2, # 与config一致
|
||
},
|
||
"data_split_parameters": {
|
||
"test_size": 0.2,
|
||
@@ -72,54 +72,26 @@ class FreqaiExampleStrategy(IStrategy):
|
||
}
|
||
|
||
def feature_engineering_expand_all(self, dataframe: DataFrame, period: int, metadata: dict, **kwargs) -> DataFrame:
|
||
- # 添加更多技术指标
|
||
+ # 保留关键的技术指标
|
||
dataframe["%-rsi"] = ta.RSI(dataframe, timeperiod=14)
|
||
- dataframe["%-mfi"] = ta.MFI(dataframe, timeperiod=14)
|
||
- dataframe["%-sma"] = ta.SMA(dataframe, timeperiod=20)
|
||
- dataframe["%-ema"] = ta.EMA(dataframe, timeperiod=20)
|
||
- dataframe["%-adx"] = ta.ADX(dataframe, timeperiod=14)
|
||
- dataframe["%-atr"] = ta.ATR(dataframe, timeperiod=14)
|
||
- dataframe["%-obv"] = ta.OBV(dataframe)
|
||
- dataframe["%-cci"] = ta.CCI(dataframe, timeperiod=20)
|
||
- dataframe["%-stoch"] = ta.STOCH(dataframe)['slowk']
|
||
- dataframe["%-macd"] = ta.MACD(dataframe)['macd']
|
||
- dataframe["%-macdsignal"] = ta.MACD(dataframe)['macdsignal']
|
||
- dataframe["%-macdhist"] = ta.MACD(dataframe)['macdhist']
|
||
- dataframe["%-willr"] = ta.WILLR(dataframe, timeperiod=14)
|
||
- dataframe["%-ultosc"] = ta.ULTOSC(dataframe)
|
||
- dataframe["%-trix"] = ta.TRIX(dataframe, timeperiod=14)
|
||
- dataframe["%-ad"] = ta.ADOSC(dataframe)
|
||
- dataframe["%-mom"] = ta.MOM(dataframe, timeperiod=10)
|
||
- dataframe["%-roc"] = ta.ROC(dataframe, timeperiod=10)
|
||
-
|
||
- # 添加布林带相关特征
|
||
+ macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
|
||
+ dataframe["%-macd"] = macd["macd"]
|
||
+ dataframe["%-macdsignal"] = macd["macdsignal"]
|
||
+
|
||
+ # 保留布林带相关特征
|
||
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
|
||
dataframe["bb_lowerband"] = bollinger["lower"]
|
||
dataframe["bb_middleband"] = bollinger["mid"]
|
||
dataframe["bb_upperband"] = bollinger["upper"]
|
||
dataframe["bb_width"] = (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"]
|
||
dataframe["bb_pct"] = (dataframe["close"] - dataframe["bb_lowerband"]) / (dataframe["bb_upperband"] - dataframe["bb_lowerband"])
|
||
-
|
||
- # 添加成交量相关特征
|
||
+
|
||
+ # 保留成交量相关特征
|
||
dataframe["volume_ma"] = dataframe["volume"].rolling(window=20).mean()
|
||
dataframe["volume_roc"] = dataframe["volume"].pct_change(periods=10)
|
||
- dataframe["volume_obv"] = ta.OBV(dataframe)
|
||
-
|
||
- # 添加价格相关特征
|
||
- dataframe["close_ma"] = dataframe["close"].rolling(window=20).mean()
|
||
+
|
||
+ # 保留价格变化率
|
||
dataframe["close_roc"] = dataframe["close"].pct_change(periods=10)
|
||
- dataframe["close_log_ret"] = np.log(dataframe["close"]).diff()
|
||
- dataframe["close_zscore"] = (dataframe["close"] - dataframe["close"].rolling(window=20).mean()) / dataframe["close"].rolling(window=20).std()
|
||
-
|
||
- # 添加时间相关特征
|
||
- dataframe["hour"] = dataframe["date"].dt.hour
|
||
- dataframe["day_of_week"] = dataframe["date"].dt.dayofweek
|
||
- dataframe["is_weekend"] = dataframe["day_of_week"].isin([5, 6]).astype(int)
|
||
-
|
||
- # 添加波动率相关特征
|
||
- dataframe["volatility"] = dataframe["close"].pct_change().rolling(window=20).std()
|
||
- dataframe["volatility_ma"] = dataframe["volatility"].rolling(window=20).mean()
|
||
- dataframe["volatility_roc"] = dataframe["volatility"].pct_change(periods=10)
|
||
|
||
# 改进数据清理
|
||
for col in dataframe.columns:
|
||
@@ -170,16 +142,23 @@ class FreqaiExampleStrategy(IStrategy):
|
||
|
||
try:
|
||
label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
|
||
+
|
||
+ # 生成更复杂的目标变量 up_or_down
|
||
+ dataframe["up_or_down"] = np.where(
|
||
+ dataframe["close"].shift(-label_period) > dataframe["close"], 1, 0
|
||
+ )
|
||
+ # 确保目标变量是二维数组
|
||
+ if dataframe["up_or_down"].ndim == 1:
|
||
+ dataframe["up_or_down"] = dataframe["up_or_down"].values.reshape(-1, 1)
|
||
+
|
||
# 生成 %-volatility 特征
|
||
dataframe["%-volatility"] = dataframe["close"].pct_change().rolling(20).std()
|
||
|
||
- # 单一回归目标
|
||
- # 移除对未来的数据依赖
|
||
# 确保 &-buy_rsi 列的值计算正确
|
||
dataframe["&-buy_rsi"] = ta.RSI(dataframe, timeperiod=14)
|
||
|
||
# 数据清理
|
||
- for col in ["&-buy_rsi"]:
|
||
+ for col in ["&-buy_rsi", "up_or_down", "%-volatility"]:
|
||
# 使用直接操作避免链式赋值
|
||
dataframe[col] = dataframe[col].replace([np.inf, -np.inf], np.nan)
|
||
dataframe[col] = dataframe[col].ffill() # 替代 fillna(method='ffill')
|
||
@@ -187,19 +166,13 @@ class FreqaiExampleStrategy(IStrategy):
|
||
if dataframe[col].isna().any():
|
||
logger.warning(f"目标列 {col} 仍包含 NaN,填充为默认值")
|
||
|
||
- # 数据清理
|
||
- for col in ["&-buy_rsi", "%-volatility"]:
|
||
- # 使用直接操作避免链式赋值
|
||
- dataframe[col] = dataframe[col].replace([np.inf, -np.inf], 0)
|
||
- dataframe[col] = dataframe[col].ffill() # 替代 fillna(method='ffill')
|
||
- dataframe[col] = dataframe[col].fillna(0)
|
||
- if dataframe[col].isna().any():
|
||
- logger.warning(f"目标列 {col} 仍包含 NaN,检查数据生成逻辑")
|
||
except Exception as e:
|
||
logger.error(f"创建 FreqAI 目标失败:{str(e)}")
|
||
raise
|
||
|
||
- logger.info(f"目标列预览:\n{dataframe[['&-buy_rsi']].head().to_string()}")
|
||
+ # Log the shape of the target variable for debugging
|
||
+ logger.info(f"目标列形状:{dataframe['up_or_down'].shape}")
|
||
+ logger.info(f"目标列预览:\n{dataframe[['up_or_down', '&-buy_rsi']].head().to_string()}")
|
||
return dataframe
|
||
|
||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
@@ -237,13 +210,13 @@ class FreqaiExampleStrategy(IStrategy):
|
||
dataframe[col] = dataframe[col].fillna(-0.1 if col == "&-stoploss" else 0)
|
||
|
||
# 简化动态参数生成逻辑
|
||
-# 简化 buy_rsi 和 sell_rsi 的生成逻辑
|
||
+ # 放松 buy_rsi 和 sell_rsi 的生成逻辑
|
||
# 计算 buy_rsi_pred 并清理 NaN 值
|
||
- dataframe["buy_rsi_pred"] = dataframe["&-buy_rsi"].rolling(window=10).mean().clip(20, 40)
|
||
+ dataframe["buy_rsi_pred"] = dataframe["&-buy_rsi"].rolling(window=10).mean().clip(30, 50)
|
||
dataframe["buy_rsi_pred"] = dataframe["buy_rsi_pred"].fillna(dataframe["buy_rsi_pred"].mean())
|
||
|
||
# 计算 sell_rsi_pred 并清理 NaN 值
|
||
- dataframe["sell_rsi_pred"] = dataframe["buy_rsi_pred"] + 20
|
||
+ dataframe["sell_rsi_pred"] = dataframe["buy_rsi_pred"] + 40
|
||
dataframe["sell_rsi_pred"] = dataframe["sell_rsi_pred"].fillna(dataframe["sell_rsi_pred"].mean())
|
||
|
||
# 计算 stoploss_pred 并清理 NaN 值
|
||
@@ -308,8 +281,9 @@ class FreqaiExampleStrategy(IStrategy):
|
||
# 改进买入信号条件
|
||
enter_long_conditions = [
|
||
(df["rsi"] < df["buy_rsi_pred"]), # RSI 低于买入阈值
|
||
- (df["volume"] > df["volume"].rolling(window=10).mean()), # 成交量高于近期均值
|
||
- (df["close"] > df["bb_middleband"]) # 价格高于布林带中轨
|
||
+ (df["volume"] > df["volume"].rolling(window=10).mean() * 1.2), # 成交量高于近期均值20%
|
||
+ (df["close"] > df["bb_middleband"]), # 价格高于布林带中轨
|
||
+ (df["do_predict"] == 1) # 确保模型预测为买入
|
||
]
|
||
if enter_long_conditions:
|
||
df.loc[
|