LightGBMRegressor
This commit is contained in:
parent
ef4a828678
commit
677914e3ca
@ -69,17 +69,19 @@ class FreqaiPrimer(IStrategy):
|
||||
"verbose": -1,
|
||||
},
|
||||
"fit_live_predictions_candles": 100,
|
||||
"live_retrain_candles": 100,
|
||||
}
|
||||
|
||||
def __init__(self, config: dict, *args, **kwargs):
|
||||
super().__init__(config, *args, **kwargs)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.setLevel(logging.DEBUG) # 保持 DEBUG 级别以查看更多日志
|
||||
logger.debug("✅ 策略已初始化,日志级别设置为 DEBUG")
|
||||
self.trailing_stop_enabled = False
|
||||
self.trailing_stop_start = 0.03
|
||||
self.trailing_stop_distance = 0.01
|
||||
self.pair_stats = {}
|
||||
self.stats_logged = False
|
||||
self.fit_live_predictions_candles = self.freqai_info.get("fit_live_predictions_candles", 100)
|
||||
|
||||
def feature_engineering_expand_all(self, dataframe: DataFrame, period: int, metadata: dict, **kwargs) -> DataFrame:
|
||||
dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
|
||||
@ -165,27 +167,31 @@ class FreqaiPrimer(IStrategy):
|
||||
for col in ["ema200", "bb_upperband", "bb_middleband", "bb_lowerband", "rsi", "volume_z_score", "&-price_value_divergence", "price_value_divergence"]:
|
||||
dataframe[col] = dataframe[col].replace([np.inf, -np.inf], 0).ffill().fillna(0)
|
||||
|
||||
# 添加调试日志:打印关键指标
|
||||
logger.debug(f"[{pair}] 最新数据 - close:{dataframe['close'].iloc[-1]:.6f}, "
|
||||
f"rsi:{dataframe['rsi'].iloc[-1]:.2f}, "
|
||||
f"&-price_value_divergence:{dataframe['&-price_value_divergence'].iloc[-1]:.6f}, "
|
||||
f"volume_z_score:{dataframe['volume_z_score'].iloc[-1]:.2f}, "
|
||||
f"bb_lowerband:{dataframe['bb_lowerband'].iloc[-1]:.6f}")
|
||||
|
||||
# 获取 labels_mean 和 labels_std
|
||||
labels_mean = None
|
||||
labels_std = None
|
||||
|
||||
# 调试:打印 freqai_info 和 user_data_dir
|
||||
logger.debug(f"freqai_info identifier:{self.freqai_info['identifier']}")
|
||||
logger.debug(f"user_data_dir:{self.config['user_data_dir']}")
|
||||
|
||||
# 从最新的子目录读取 metadata.json
|
||||
try:
|
||||
model_base_dir = os.path.join(self.config["user_data_dir"], "models", self.freqai_info["identifier"])
|
||||
pair_base = pair.split('/')[0] if '/' in pair else pair # 取币对基础部分,例如 "TRUMP/USDT" -> "TRUMP"
|
||||
pair_base = pair.split('/')[0] if '/' in pair else pair
|
||||
sub_dirs = glob.glob(os.path.join(model_base_dir, f"sub-train-{pair_base}_*"))
|
||||
|
||||
if not sub_dirs:
|
||||
logger.warning(f"[{pair}] 未找到任何子目录:{model_base_dir}/sub-train-{pair_base}_*")
|
||||
else:
|
||||
# 按时间戳排序,获取最新的子目录
|
||||
latest_sub_dir = max(sub_dirs, key=lambda x: int(x.split('_')[-1]))
|
||||
pair_base_lower = pair_base.lower() # 用于 metadata.json 文件名,例如 "TRUMP" -> "trump"
|
||||
timestamp = latest_sub_dir.split('_')[-1] # 提取时间戳,例如 "1748743825"
|
||||
pair_base_lower = pair_base.lower()
|
||||
timestamp = latest_sub_dir.split('_')[-1]
|
||||
metadata_file = os.path.join(latest_sub_dir, f"cb_{pair_base_lower}_{timestamp}_metadata.json")
|
||||
|
||||
if os.path.exists(metadata_file):
|
||||
@ -199,22 +205,19 @@ class FreqaiPrimer(IStrategy):
|
||||
except Exception as e:
|
||||
logger.warning(f"[{pair}] 无法从子目录读取 labels_mean 和 labels_std:{e},重新计算")
|
||||
|
||||
# 回退:如果无法从文件读取,则重新计算
|
||||
if labels_mean is None or labels_std is None:
|
||||
logger.warning(f"[{pair}] 无法获取 labels_mean 和 labels_std,重新计算")
|
||||
dataframe["&-price_value_divergence_actual"] = (dataframe["close"] - dataframe["ema200"]) / dataframe["ema200"]
|
||||
dataframe["&-price_value_divergence_actual"] = dataframe["&-price_value_divergence_actual"].replace([np.inf, -np.inf], 0).ffill().fillna(0)
|
||||
recent_data = dataframe["&-price_value_divergence_actual"].tail(self.freqai_info["fit_live_predictions_candles"])
|
||||
recent_data = dataframe["&-price_value_divergence_actual"].tail(self.fit_live_predictions_candles)
|
||||
labels_mean = recent_data.mean()
|
||||
labels_std = recent_data.std()
|
||||
if np.isnan(labels_std) or labels_std == 0:
|
||||
labels_std = 0.01
|
||||
logger.warning(f"[{pair}] labels_std 计算异常,使用默认值 0.01")
|
||||
|
||||
# 存储统计信息
|
||||
self.pair_stats[pair] = {"labels_mean": labels_mean, "labels_std": labels_std}
|
||||
|
||||
# 计算动态阈值
|
||||
if labels_std > 0.015:
|
||||
k_buy = 1.2
|
||||
k_sell = 1.5
|
||||
@ -249,8 +252,6 @@ class FreqaiPrimer(IStrategy):
|
||||
logger.info("==============================================")
|
||||
self.stats_logged = True
|
||||
|
||||
# 移除问题日志行,避免 KeyError
|
||||
# logger.info(f"[{metadata['pair']}] 指标计算完成,列:{list(dataframe.columns)}")
|
||||
return dataframe
|
||||
|
||||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
@ -258,17 +259,31 @@ class FreqaiPrimer(IStrategy):
|
||||
conditions = []
|
||||
|
||||
if "&-price_value_divergence" in dataframe.columns:
|
||||
buy_condition = (dataframe["&-price_value_divergence"] < self.buy_threshold)
|
||||
buy_condition &= (dataframe["volume_z_score"] > 1.5)
|
||||
buy_condition &= (dataframe["rsi"] < 40)
|
||||
buy_condition &= (dataframe["close"] <= dataframe["bb_lowerband"])
|
||||
# 逐个检查买入条件
|
||||
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold)
|
||||
cond2 = (dataframe["volume_z_score"] > 1.5)
|
||||
cond3 = (dataframe["rsi"] < 40)
|
||||
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"])
|
||||
buy_condition = cond1 & cond2 & cond3 & cond4
|
||||
conditions.append(buy_condition)
|
||||
|
||||
# 添加调试日志:打印条件是否满足
|
||||
logger.debug(f"[{pair}] 买入条件检查 - "
|
||||
f"&-price_value_divergence < {self.buy_threshold:.6f}: {cond1.iloc[-1]}, "
|
||||
f"volume_z_score > 1.5: {cond2.iloc[-1]}, "
|
||||
f"rsi < 40: {cond3.iloc[-1]}, "
|
||||
f"close <= bb_lowerband: {cond4.iloc[-1]}")
|
||||
else:
|
||||
logger.warning(f"[{pair}] ⚠️ &-price_value_divergence 列缺失,跳过该条件")
|
||||
|
||||
if len(conditions) > 0:
|
||||
dataframe.loc[reduce(lambda x, y: x & y, conditions), 'enter_long'] = 1
|
||||
logger.info(f"[{pair}] 入场信号触发,条件满足")
|
||||
# 检查是否同时有卖出信号
|
||||
if 'exit_long' in dataframe.columns and (dataframe["exit_long"] == 1).any():
|
||||
logger.warning(f"[{pair}] 同时检测到买入和卖出信号,忽略买入信号")
|
||||
dataframe['enter_long'] = 0
|
||||
else:
|
||||
logger.debug(f"[{pair}] 入场信号触发,条件满足") # 改为 DEBUG 级别
|
||||
|
||||
return dataframe
|
||||
|
||||
@ -277,15 +292,22 @@ class FreqaiPrimer(IStrategy):
|
||||
conditions = []
|
||||
|
||||
if "&-price_value_divergence" in dataframe.columns:
|
||||
sell_condition = (dataframe["&-price_value_divergence"] > self.sell_threshold)
|
||||
sell_condition |= (dataframe["rsi"] > 75)
|
||||
# 逐个检查卖出条件
|
||||
cond1 = (dataframe["&-price_value_divergence"] > self.sell_threshold)
|
||||
cond2 = (dataframe["rsi"] > 75)
|
||||
sell_condition = cond1 | cond2
|
||||
conditions.append(sell_condition)
|
||||
|
||||
# 添加调试日志:打印条件是否满足
|
||||
logger.debug(f"[{pair}] 卖出条件检查 - "
|
||||
f"&-price_value_divergence > {self.sell_threshold:.6f}: {cond1.iloc[-1]}, "
|
||||
f"rsi > 75: {cond2.iloc[-1]}")
|
||||
else:
|
||||
logger.warning(f"[{pair}] ⚠️ &-price_value_divergence 列缺失,跳过该条件")
|
||||
|
||||
if len(conditions) > 0:
|
||||
dataframe.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
|
||||
logger.info(f"[{pair}] 出场信号触发,条件满足")
|
||||
logger.debug(f"[{pair}] 出场信号触发,条件满足") # 改为 DEBUG 级别
|
||||
|
||||
return dataframe
|
||||
|
||||
@ -319,14 +341,18 @@ class FreqaiPrimer(IStrategy):
|
||||
|
||||
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
|
||||
time_in_force: str, current_time: datetime, **kwargs) -> bool:
|
||||
# 添加调试日志:检查是否允许买入
|
||||
recent_trades = Trade.get_trades(
|
||||
pair=pair,
|
||||
is_open=False,
|
||||
close_date=current_time - datetime.timedelta(minutes=5)
|
||||
).all()
|
||||
if len(recent_trades) > 0:
|
||||
logger.info(f"[{pair}] 5分钟内有近期交易,跳过本次入场")
|
||||
logger.info(f"[{pair}] 5分钟内有近期交易({len(recent_trades)} 笔),跳过本次入场")
|
||||
return False
|
||||
|
||||
# 检查其他限制(例如资金、仓位等)
|
||||
logger.debug(f"[{pair}] 允许买入 - 订单类型:{order_type}, 数量:{amount:.2f}, 价格:{rate:.6f}, 时间:{current_time}")
|
||||
self.trailing_stop_enabled = False
|
||||
return True
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user