up
This commit is contained in:
parent
7a1993a2e7
commit
c3364852c1
@ -35,7 +35,7 @@
|
|||||||
"timeout": 20000
|
"timeout": 20000
|
||||||
},
|
},
|
||||||
"pair_whitelist": [
|
"pair_whitelist": [
|
||||||
"OKB/USDT",
|
"BTC/USDT",
|
||||||
"SOL/USDT"
|
"SOL/USDT"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -66,7 +66,7 @@
|
|||||||
},
|
},
|
||||||
"freqaimodel": "CatboostClassifier",
|
"freqaimodel": "CatboostClassifier",
|
||||||
"purge_old_models": 2,
|
"purge_old_models": 2,
|
||||||
"identifier": "test176",
|
"identifier": "test178",
|
||||||
"train_period_days": 30,
|
"train_period_days": 30,
|
||||||
"backtest_period_days": 10,
|
"backtest_period_days": 10,
|
||||||
"live_retrain_hours": 0,
|
"live_retrain_hours": 0,
|
||||||
@ -80,7 +80,7 @@
|
|||||||
],
|
],
|
||||||
"include_corr_pairlist": [
|
"include_corr_pairlist": [
|
||||||
"BTC/USDT",
|
"BTC/USDT",
|
||||||
"ETH/USDT"
|
"SOL/USDT"
|
||||||
],
|
],
|
||||||
"label_period_candles": 12,
|
"label_period_candles": 12,
|
||||||
"include_shifted_candles": 3,
|
"include_shifted_candles": 3,
|
||||||
|
|||||||
@ -24,7 +24,7 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
startup_candle_count: int = 40
|
startup_candle_count: int = 40
|
||||||
can_short = False
|
can_short = False
|
||||||
|
|
||||||
buy_rsi = IntParameter(low=10, high=50, default=27, space="buy", optimize=True, load=True)
|
buy_rsi = IntParameter(low=10, high=40, default=20, space="buy", optimize=True, load=True)
|
||||||
sell_rsi = IntParameter(low=50, high=90, default=59, space="sell", optimize=True, load=True)
|
sell_rsi = IntParameter(low=50, high=90, default=59, space="sell", optimize=True, load=True)
|
||||||
roi_0 = DecimalParameter(low=0.01, high=0.2, default=0.038, space="roi", optimize=True, load=True)
|
roi_0 = DecimalParameter(low=0.01, high=0.2, default=0.038, space="roi", optimize=True, load=True)
|
||||||
roi_15 = DecimalParameter(low=0.005, high=0.1, default=0.027, space="roi", optimize=True, load=True)
|
roi_15 = DecimalParameter(low=0.005, high=0.1, default=0.027, space="roi", optimize=True, load=True)
|
||||||
@ -38,11 +38,11 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
"model": "LightGBMRegressor",
|
"model": "LightGBMRegressor",
|
||||||
"feature_parameters": {
|
"feature_parameters": {
|
||||||
"include_timeframes": ["5m"],
|
"include_timeframes": ["5m"],
|
||||||
"include_corr_pairlist": ["SOL/USDT"],
|
"include_corr_pairlist": ["OKB/USDT", "SOL/USDT"], # 与白名单一致
|
||||||
"label_period_candles": 12,
|
"label_period_candles": 12,
|
||||||
"include_shifted_candles": 0,
|
"include_shifted_candles": 0,
|
||||||
"include_periods": [20],
|
"include_periods": [20],
|
||||||
"DI_threshold": 5.0
|
"DI_threshold": 1.5 # 提高以减少丢弃预测
|
||||||
},
|
},
|
||||||
"data_split_parameters": {
|
"data_split_parameters": {
|
||||||
"test_size": 0.2,
|
"test_size": 0.2,
|
||||||
@ -128,9 +128,9 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
return dataframe
|
return dataframe
|
||||||
|
|
||||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
logger.info(f"Processing pair: {metadata['pair']}")
|
logger.info(f"populate_indicators Processing pair: {metadata['pair']}")
|
||||||
logger.info(f"DataFrame rows: {len(dataframe)}")
|
logger.info(f"populate_indicators DataFrame rows: {len(dataframe)}")
|
||||||
logger.info(f"Columns before freqai.start: {list(dataframe.columns)}")
|
logger.info(f"populate_indicators Columns before freqai.start: {list(dataframe.columns)}")
|
||||||
|
|
||||||
if "close" not in dataframe.columns or dataframe["close"].isna().all():
|
if "close" not in dataframe.columns or dataframe["close"].isna().all():
|
||||||
logger.error(f"DataFrame missing 'close' column or all NaN for pair: {metadata['pair']}")
|
logger.error(f"DataFrame missing 'close' column or all NaN for pair: {metadata['pair']}")
|
||||||
@ -173,19 +173,6 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
logger.warning("bb_lowerband contains NaN, filling with close")
|
logger.warning("bb_lowerband contains NaN, filling with close")
|
||||||
dataframe["bb_lowerband"] = dataframe["bb_lowerband"].fillna(dataframe["close"])
|
dataframe["bb_lowerband"] = dataframe["bb_lowerband"].fillna(dataframe["close"])
|
||||||
logger.info(f"bb_lowerband stats: {dataframe['bb_lowerband'].describe().to_string()}")
|
logger.info(f"bb_lowerband stats: {dataframe['bb_lowerband'].describe().to_string()}")
|
||||||
# 生成 up_or_down
|
|
||||||
label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
|
|
||||||
if len(dataframe) < label_period + 1:
|
|
||||||
logger.warning(f"DataFrame too short ({len(dataframe)} rows), cannot compute up_or_down")
|
|
||||||
dataframe["up_or_down"] = 0
|
|
||||||
else:
|
|
||||||
dataframe["up_or_down"] = np.where(
|
|
||||||
dataframe["close"].shift(-label_period) > dataframe["close"], 1, 0
|
|
||||||
)
|
|
||||||
if dataframe["up_or_down"].isna().any():
|
|
||||||
logger.warning("up_or_down contains NaN, filling with 0")
|
|
||||||
dataframe["up_or_down"] = dataframe["up_or_down"].fillna(0)
|
|
||||||
logger.info(f"up_or_down stats: {dataframe['up_or_down'].describe().to_string()}")
|
|
||||||
|
|
||||||
if "date" in dataframe.columns:
|
if "date" in dataframe.columns:
|
||||||
dataframe["%-day_of_week"] = dataframe["date"].dt.dayofweek
|
dataframe["%-day_of_week"] = dataframe["date"].dt.dayofweek
|
||||||
@ -211,17 +198,23 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
logger.info(f"{col} stats: {dataframe[col].describe().to_string()}")
|
logger.info(f"{col} stats: {dataframe[col].describe().to_string()}")
|
||||||
|
|
||||||
# 调试特征分布
|
# 调试特征分布
|
||||||
|
if "%-bb_width-period_10_OKB/USDT_5m" in dataframe.columns:
|
||||||
|
if dataframe["%-bb_width-period_10_OKB/USDT_5m"].std() > 0:
|
||||||
|
dataframe["%-bb_width-period_10_OKB/USDT_5m"] = (
|
||||||
|
dataframe["%-bb_width-period_10_OKB/USDT_5m"] - dataframe["%-bb_width-period_10_OKB/USDT_5m"].mean()
|
||||||
|
) / dataframe["%-bb_width-period_10_OKB/USDT_5m"].std()
|
||||||
|
logger.info(f"%-bb_width-period_10_OKB stats: {dataframe['%-bb_width-period_10_OKB/USDT_5m'].describe().to_string()}")
|
||||||
if "%-bb_width-period_10_SOL/USDT_5m" in dataframe.columns:
|
if "%-bb_width-period_10_SOL/USDT_5m" in dataframe.columns:
|
||||||
if dataframe["%-bb_width-period_10_SOL/USDT_5m"].std() > 0:
|
if dataframe["%-bb_width-period_10_SOL/USDT_5m"].std() > 0:
|
||||||
dataframe["%-bb_width-period_10_SOL/USDT_5m"] = (
|
dataframe["%-bb_width-period_10_SOL/USDT_5m"] = (
|
||||||
dataframe["%-bb_width-period_10_SOL/USDT_5m"] - dataframe["%-bb_width-period_10_SOL/USDT_5m"].mean()
|
dataframe["%-bb_width-period_10_SOL/USDT_5m"] - dataframe["%-bb_width-period_10_SOL/USDT_5m"].mean()
|
||||||
) / dataframe["%-bb_width-period_10_SOL/USDT_5m"].std()
|
) / dataframe["%-bb_width-period_10_SOL/USDT_5m"].std()
|
||||||
logger.info(f"%-bb_width-period_10 stats: {dataframe['%-bb_width-period_10_SOL/USDT_5m'].describe().to_string()}")
|
logger.info(f"%-bb_width-period_10_SOL stats: {dataframe['%-bb_width-period_10_SOL/USDT_5m'].describe().to_string()}")
|
||||||
|
|
||||||
def get_expected_columns(freqai_config: dict) -> list:
|
def get_expected_columns(freqai_config: dict) -> list:
|
||||||
indicators = ["rsi", "bb_width", "pct-change"]
|
indicators = ["rsi", "bb_width", "pct-change"]
|
||||||
periods = freqai_config.get("feature_parameters", {}).get("include_periods", [10, 20])
|
periods = freqai_config.get("feature_parameters", {}).get("include_periods", [10, 20])
|
||||||
pairs = freqai_config.get("include_corr_pairlist", ["SOL/USDT", "BTC/USDT"])
|
pairs = freqai_config.get("include_corr_pairlist", ["OKB/USDT", "SOL/USDT"])
|
||||||
timeframes = freqai_config.get("include_timeframes", ["5m"])
|
timeframes = freqai_config.get("include_timeframes", ["5m"])
|
||||||
shifts = [0]
|
shifts = [0]
|
||||||
expected_columns = ["%-volatility", "%-day_of_week", "%-hour_of_day"]
|
expected_columns = ["%-volatility", "%-day_of_week", "%-hour_of_day"]
|
||||||
@ -256,11 +249,10 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
|
|
||||||
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
||||||
enter_long_conditions = [
|
enter_long_conditions = [
|
||||||
qtpylib.crossed_above(df["rsi"], df["buy_rsi_pred"] + (5 if metadata["pair"] == "BTC/USDT" else 0)),
|
qtpylib.crossed_above(df["rsi"], df["buy_rsi_pred"]),
|
||||||
df["tema"] > df["tema"].shift(1),
|
df["close"] > df["tema"],
|
||||||
df["volume"] > 0,
|
df["volume"] > 0,
|
||||||
df["do_predict"] == 1,
|
df["do_predict"] == 1
|
||||||
df["up_or_down"] == 1
|
|
||||||
]
|
]
|
||||||
if enter_long_conditions:
|
if enter_long_conditions:
|
||||||
df.loc[
|
df.loc[
|
||||||
@ -274,7 +266,9 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
["enter_long", "enter_tag"]
|
["enter_long", "enter_tag"]
|
||||||
] = (1, "long")
|
] = (1, "long")
|
||||||
if df["entry_signal"].iloc[-1]:
|
if df["entry_signal"].iloc[-1]:
|
||||||
logger.info(f"Entry signal triggered for {metadata['pair']}: rsi={df['rsi'].iloc[-1]}, buy_rsi_pred={df['buy_rsi_pred'].iloc[-1]}, do_predict={df['do_predict'].iloc[-1]}")
|
logger.info(f"Entry signal triggered for {metadata['pair']}: rsi={df['rsi'].iloc[-1]}, buy_rsi_pred={df['buy_rsi_pred'].iloc[-1]}, do_predict={df['do_predict'].iloc[-1]}, close={df['close'].iloc[-1]}, tema={df['tema'].iloc[-1]}")
|
||||||
|
logger.info(f"Entry conditions: RSI_cross={qtpylib.crossed_above(df['rsi'], df['buy_rsi_pred']).iloc[-1]}, Close_above_tema={df['close'].iloc[-1] > df['tema'].iloc[-1]}, Volume={df['volume'].iloc[-1] > 0}, Do_predict={df['do_predict'].iloc[-1] == 1}")
|
||||||
|
logger.info(f"Last candle: rsi={df['rsi'].iloc[-1]}, buy_rsi_pred={df['buy_rsi_pred'].iloc[-1]}, close={df['close'].iloc[-1]}, tema={df['tema'].iloc[-1]}, do_predict={df['do_predict'].iloc[-1]}")
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
||||||
@ -283,8 +277,7 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
(df["close"] < df["close"].shift(1) * 0.98) |
|
(df["close"] < df["close"].shift(1) * 0.98) |
|
||||||
(df["close"] < df["bb_lowerband"]),
|
(df["close"] < df["bb_lowerband"]),
|
||||||
df["volume"] > 0,
|
df["volume"] > 0,
|
||||||
df["do_predict"] == 1,
|
df["do_predict"] == 1
|
||||||
df["up_or_down"] == 0
|
|
||||||
]
|
]
|
||||||
time_exit = (df["date"] >= df["date"].shift(1) + pd.Timedelta(days=1))
|
time_exit = (df["date"] >= df["date"].shift(1) + pd.Timedelta(days=1))
|
||||||
df.loc[
|
df.loc[
|
||||||
|
|||||||
104
freqtrade/templates/celuo.diff
Normal file
104
freqtrade/templates/celuo.diff
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
diff --git a/freqtrade/templates/FreqaiExampleStrategy.py b/freqtrade/templates/FreqaiExampleStrategy.py
|
||||||
|
index 1d7ed33..245f771 100644
|
||||||
|
--- a/freqtrade/templates/FreqaiExampleStrategy.py
|
||||||
|
+++ b/freqtrade/templates/FreqaiExampleStrategy.py
|
||||||
|
@@ -128,9 +128,9 @@ class FreqaiExampleStrategy(IStrategy):
|
||||||
|
return dataframe
|
||||||
|
|
||||||
|
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
- logger.info(f"Processing pair: {metadata['pair']}")
|
||||||
|
- logger.info(f"DataFrame rows: {len(dataframe)}")
|
||||||
|
- logger.info(f"Columns before freqai.start: {list(dataframe.columns)}")
|
||||||
|
+ logger.info(f"populate_indicators Processing pair: {metadata['pair']}")
|
||||||
|
+ logger.info(f"populate_indicators DataFrame rows: {len(dataframe)}")
|
||||||
|
+ logger.info(f"populate_indicators Columns before freqai.start: {list(dataframe.columns)}")
|
||||||
|
|
||||||
|
if "close" not in dataframe.columns or dataframe["close"].isna().all():
|
||||||
|
logger.error(f"DataFrame missing 'close' column or all NaN for pair: {metadata['pair']}")
|
||||||
|
@@ -173,6 +173,19 @@ class FreqaiExampleStrategy(IStrategy):
|
||||||
|
logger.warning("bb_lowerband contains NaN, filling with close")
|
||||||
|
dataframe["bb_lowerband"] = dataframe["bb_lowerband"].fillna(dataframe["close"])
|
||||||
|
logger.info(f"bb_lowerband stats: {dataframe['bb_lowerband'].describe().to_string()}")
|
||||||
|
+ # 生成 up_or_down
|
||||||
|
+ label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
|
||||||
|
+ if len(dataframe) < label_period + 1:
|
||||||
|
+ logger.warning(f"DataFrame too short ({len(dataframe)} rows), cannot compute up_or_down")
|
||||||
|
+ dataframe["up_or_down"] = 0
|
||||||
|
+ else:
|
||||||
|
+ dataframe["up_or_down"] = np.where(
|
||||||
|
+ dataframe["close"].shift(-label_period) > dataframe["close"], 1, 0
|
||||||
|
+ )
|
||||||
|
+ if dataframe["up_or_down"].isna().any():
|
||||||
|
+ logger.warning("up_or_down contains NaN, filling with 0")
|
||||||
|
+ dataframe["up_or_down"] = dataframe["up_or_down"].fillna(0)
|
||||||
|
+ logger.info(f"up_or_down stats: {dataframe['up_or_down'].describe().to_string()}")
|
||||||
|
|
||||||
|
if "date" in dataframe.columns:
|
||||||
|
dataframe["%-day_of_week"] = dataframe["date"].dt.dayofweek
|
||||||
|
@@ -197,17 +210,18 @@ class FreqaiExampleStrategy(IStrategy):
|
||||||
|
dataframe[col] = 50 if col == "buy_rsi_pred" else 80
|
||||||
|
logger.info(f"{col} stats: {dataframe[col].describe().to_string()}")
|
||||||
|
|
||||||
|
- if "%-bb_width-period_20_SOL/USDT_5m" in dataframe.columns:
|
||||||
|
- if dataframe["%-bb_width-period_20_SOL/USDT_5m"].std() > 0:
|
||||||
|
- dataframe["%-bb_width-period_20_SOL/USDT_5m"] = (
|
||||||
|
- dataframe["%-bb_width-period_20_SOL/USDT_5m"] - dataframe["%-bb_width-period_20_SOL/USDT_5m"].mean()
|
||||||
|
- ) / dataframe["%-bb_width-period_20_SOL/USDT_5m"].std()
|
||||||
|
- logger.info(f"%-bb_width-period_20 stats: {dataframe['%-bb_width-period_20_SOL/USDT_5m'].describe().to_string()}")
|
||||||
|
+ # 调试特征分布
|
||||||
|
+ if "%-bb_width-period_10_SOL/USDT_5m" in dataframe.columns:
|
||||||
|
+ if dataframe["%-bb_width-period_10_SOL/USDT_5m"].std() > 0:
|
||||||
|
+ dataframe["%-bb_width-period_10_SOL/USDT_5m"] = (
|
||||||
|
+ dataframe["%-bb_width-period_10_SOL/USDT_5m"] - dataframe["%-bb_width-period_10_SOL/USDT_5m"].mean()
|
||||||
|
+ ) / dataframe["%-bb_width-period_10_SOL/USDT_5m"].std()
|
||||||
|
+ logger.info(f"%-bb_width-period_10 stats: {dataframe['%-bb_width-period_10_SOL/USDT_5m'].describe().to_string()}")
|
||||||
|
|
||||||
|
def get_expected_columns(freqai_config: dict) -> list:
|
||||||
|
indicators = ["rsi", "bb_width", "pct-change"]
|
||||||
|
- periods = freqai_config.get("feature_parameters", {}).get("include_periods", [20])
|
||||||
|
- pairs = freqai_config.get("include_corr_pairlist", ["SOL/USDT"])
|
||||||
|
+ periods = freqai_config.get("feature_parameters", {}).get("include_periods", [10, 20])
|
||||||
|
+ pairs = freqai_config.get("include_corr_pairlist", ["SOL/USDT", "BTC/USDT"])
|
||||||
|
timeframes = freqai_config.get("include_timeframes", ["5m"])
|
||||||
|
shifts = [0]
|
||||||
|
expected_columns = ["%-volatility", "%-day_of_week", "%-hour_of_day"]
|
||||||
|
@@ -242,11 +256,17 @@ class FreqaiExampleStrategy(IStrategy):
|
||||||
|
|
||||||
|
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
enter_long_conditions = [
|
||||||
|
- qtpylib.crossed_above(df["rsi"], df["buy_rsi_pred"]),
|
||||||
|
+ qtpylib.crossed_above(df["rsi"], df["buy_rsi_pred"] + (5 if metadata["pair"] == "BTC/USDT" else 0)),
|
||||||
|
df["tema"] > df["tema"].shift(1),
|
||||||
|
df["volume"] > 0,
|
||||||
|
- df["do_predict"] == 1
|
||||||
|
+ df["do_predict"] == 1,
|
||||||
|
+ df["up_or_down"] == 1
|
||||||
|
]
|
||||||
|
+ if enter_long_conditions:
|
||||||
|
+ df.loc[
|
||||||
|
+ reduce(lambda x, y: x & y, enter_long_conditions),
|
||||||
|
+ ["enter_long", "enter_tag"]
|
||||||
|
+ ] = (1, "long")
|
||||||
|
df["entry_signal"] = reduce(lambda x, y: x & y, enter_long_conditions)
|
||||||
|
df["entry_signal"] = df["entry_signal"].rolling(window=2, min_periods=1).max().astype(bool)
|
||||||
|
df.loc[
|
||||||
|
@@ -259,14 +279,16 @@ class FreqaiExampleStrategy(IStrategy):
|
||||||
|
|
||||||
|
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
exit_long_conditions = [
|
||||||
|
- (qtpylib.crossed_above(df["rsi"], df["sell_rsi_pred"] - 5)) |
|
||||||
|
+ (qtpylib.crossed_above(df["rsi"], df["sell_rsi_pred"])) |
|
||||||
|
(df["close"] < df["close"].shift(1) * 0.98) |
|
||||||
|
(df["close"] < df["bb_lowerband"]),
|
||||||
|
df["volume"] > 0,
|
||||||
|
- df["do_predict"] == 1
|
||||||
|
+ df["do_predict"] == 1,
|
||||||
|
+ df["up_or_down"] == 0
|
||||||
|
]
|
||||||
|
+ time_exit = (df["date"] >= df["date"].shift(1) + pd.Timedelta(days=1))
|
||||||
|
df.loc[
|
||||||
|
- reduce(lambda x, y: x & y, exit_long_conditions),
|
||||||
|
+ (reduce(lambda x, y: x & y, exit_long_conditions)) | time_exit,
|
||||||
|
"exit_long"
|
||||||
|
] = 1
|
||||||
|
return df
|
||||||
@ -2,3 +2,4 @@
|
|||||||
实时监控 freqtrade_freqtrade_run_ef258891294d 的日志,过滤 'but got Index'...
|
实时监控 freqtrade_freqtrade_run_ef258891294d 的日志,过滤 'but got Index'...
|
||||||
开始过滤日志,输出到 freqtrade_error_logs.txt ...
|
开始过滤日志,输出到 freqtrade_error_logs.txt ...
|
||||||
实时监控 freqtrade_freqtrade_run_ef258891294d 的日志,过滤 'but got Index'...
|
实时监控 freqtrade_freqtrade_run_ef258891294d 的日志,过滤 'but got Index'...
|
||||||
|
未捕获到包含 'but got Index' 的日志,文件 freqtrade_error_logs.txt 为空
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user