log from debug to info

This commit is contained in:
zhangkun9038@dingtalk.com 2025-12-25 20:07:43 +08:00
parent bfd3562436
commit 18126fdd02
4 changed files with 45 additions and 40 deletions

View File

@ -0,0 +1,3 @@
{
"enable_strategy_log": true
}

View File

@ -1,3 +1,3 @@
{
"strategy_log_level": "INFO"
"enable_strategy_log": false
}

View File

@ -35,6 +35,10 @@ class FreqaiPrimer(IStrategy):
def __init__(self, config=None):
"""初始化策略参数调用父类初始化方法并接受config参数"""
super().__init__(config) # 调用父类的初始化方法并传递config
# 读取日志开关配置(默认开启)
self._log_enabled = config.get('enable_strategy_log', True) if config else True
# 存储从配置文件加载的默认值
self._trailing_stop_positive_default = 0.004 # 降低默认值以更容易触发跟踪止盈
@ -117,11 +121,11 @@ class FreqaiPrimer(IStrategy):
# 确保EMA值在合理范围内
final_coef = max(0.1, min(5.0, ema_volatility_coef))
self.log_debug(f"计算波动系数EMA完成 {pair}: 最终系数={final_coef:.4f} (历史数据点数={len(self._volatility_history[pair])})")
self.log_info(f"计算波动系数EMA完成 {pair}: 最终系数={final_coef:.4f} (历史数据点数={len(self._volatility_history[pair])})")
else:
# 如果历史数据不足,返回当前波动系数(或默认值)
final_coef = max(0.1, min(5.0, current_volatility_coef))
self.log_debug(f"计算波动系数EMA完成 {pair}: 最终系数={final_coef:.4f} (历史数据不足,使用当前值)")
self.log_info(f"计算波动系数EMA完成 {pair}: 最终系数={final_coef:.4f} (历史数据不足,使用当前值)")
# 更新缓存和时间戳
self._volatility_cache[pair] = final_coef
@ -301,24 +305,12 @@ class FreqaiPrimer(IStrategy):
def log_info(self, message: str):
"""
条件化的 INFO 日志输出根据 config 中的 strategy_log_level 决定是否输出
条件化的 INFO 日志输出根据 config 中的 enable_strategy_log 决定是否输出
用法self.log_info(f"[{pair}] 一些信息")
"""
# 从 config 中读取日志级别,默认 INFO
log_level = self.config.get('strategy_log_level', 'INFO').upper()
# 只有当级别 <= INFw 时才输出
if log_level in ['DEBUG', 'INFO']:
if self._log_enabled:
logger.info(message)
def log_debug(self, message: str):
"""
条件化的 DEBUG 日志输出
用法self.log_debug(f"[{pair}] 调试信息")
"""
log_level = self.config.get('strategy_log_level', 'INFO').upper()
if log_level == 'DEBUG':
logger.debug(message)
def _validate_dataframe_columns(self, dataframe: DataFrame, required_columns: list, metadata: dict):
"""
验证数据框中是否包含所有需要的列
@ -740,7 +732,7 @@ class FreqaiPrimer(IStrategy):
# 日志记录抄底信号
if dip_buy_condition.sum() > 0:
self.log_debug(
self.log_info(
f"[抄底加速器] [{metadata['pair']}] 检测到 {dip_buy_condition.sum()} 个抄底机会 | "
f"5根K线跌幅: {dataframe.loc[dip_buy_condition, 'price_drop_5'].mean():.2%}"
)
@ -819,7 +811,7 @@ class FreqaiPrimer(IStrategy):
交易买入前的确认函数用于最终决定是否执行交易
此处实现剧烈拉升检查和入场间隔控制逻辑
"""
self.log_debug(f"[{pair}] confirm_trade_entry 被调用 - 价格: {rate:.8f}, 时间: {current_time}")
self.log_info(f"[{pair}] confirm_trade_entry 被调用 - 价格: {rate:.8f}, 时间: {current_time}")
# 默认允许交易
allow_trade = True
@ -830,7 +822,7 @@ class FreqaiPrimer(IStrategy):
last_entry = self._last_entry_time[pair]
time_diff = (current_time - last_entry).total_seconds() * 0.0166666667 # 转换为分钟(使用乘法避免除法)
if time_diff < self.entry_interval_minutes.value:
self.log_debug(f"[{pair}] 入场间隔不足: 距离上次入场 {time_diff:.1f}分钟 < {self.entry_interval_minutes.value}分钟,取消本次入场")
self.log_info(f"[{pair}] 入场间隔不足: 距离上次入场 {time_diff:.1f}分钟 < {self.entry_interval_minutes.value}分钟,取消本次入场")
allow_trade = False
# 检查2检查是否处于剧烈拉升的不稳固区域
@ -869,10 +861,10 @@ class FreqaiPrimer(IStrategy):
entry_prob = max(0.0, min(1.0, entry_prob))
entry_threshold = self.ml_entry_signal_threshold.value
if entry_prob < entry_threshold:
self.log_debug(f"[{pair}] ML 审核官拒绝入场: entry_signal 概率 {entry_prob:.2f} < 阈值 {entry_threshold:.2f}(上涨概率低,不宜入场)")
self.log_info(f"[{pair}] ML 审核官拒绝入场: entry_signal 概率 {entry_prob:.2f} < 阈值 {entry_threshold:.2f}(上涨概率低,不宜入场)")
allow_trade = False
else:
self.log_debug(f"[{pair}] ML 审核官允许入场: entry_signal 概率 {entry_prob:.2f} >= 阈值 {entry_threshold:.2f}")
self.log_info(f"[{pair}] ML 审核官允许入场: entry_signal 概率 {entry_prob:.2f} >= 阈值 {entry_threshold:.2f}")
except Exception as e:
logger.warning(f"[{pair}] ML 审核官检查失败,忽略 ML 过滤: {e}")
@ -905,7 +897,7 @@ class FreqaiPrimer(IStrategy):
)
allow_trade = False
else:
self.log_debug(
self.log_info(
f"[下跌保护] [{pair}] 通过下跌趋势检查 | "
f"连续阴线: {consecutive_red}, 5h跌幅: {price_drop_5h:.2%}, 仍在下跌: {still_falling}"
)
@ -915,11 +907,15 @@ class FreqaiPrimer(IStrategy):
# 如果允许交易,更新最后一次入场时间并输出价格信息
if allow_trade:
self._last_entry_time[pair] = current_time
# 计算实际入场价格下调比例1.67%
# rate 是当前市场价格enter_price = rate * 0.9833
price_discount_percent = 1.67
adjusted_entry_price = rate * 0.9833
self.log_debug(f"[{pair}] 允许入场 - 市场价: {rate:.8f}, 调整后入场价: {adjusted_entry_price:.8f}, 下调: {price_discount_percent}%")
# 计算实际入场价格(使用 hyperopt 参数)
discount_multiplier = 1.0 - self.entry_price_discount.value
adjusted_entry_price = rate * discount_multiplier
self.log_info(
f"[{pair}] ✅ 允许入场 | "
f"原始价格: {rate:.8f} | "
f"下调倍率: {discount_multiplier:.6f} (-{self.entry_price_discount.value:.2%}) | "
f"实际入场价: {adjusted_entry_price:.8f}"
)
# 如果没有阻止因素,允许交易
return allow_trade
@ -940,10 +936,10 @@ class FreqaiPrimer(IStrategy):
交易卖出前的确认函数用于最终决定是否执行出场
此处使用 ML 审核官exit_signal 置信度过滤出场
"""
self.log_debug(f"[{pair}] confirm_trade_exit 被调用 - 价格: {rate:.8f}, 出场原因: {exit_reason}, 时间: {current_time}")
self.log_info(f"[{pair}] confirm_trade_exit 被调用 - 价格: {rate:.8f}, 出场原因: {exit_reason}, 时间: {current_time}")
# 风险控制类退出原因:不经过 ML 审核官,直接允许出场
if exit_reason in ['stop_loss', 'trailing_stop_loss', 'emergency_exit', 'force_exit']:
self.log_debug(f"[{pair}] 风险控制退出,不走 ML 审核官: exit_reason={exit_reason}")
self.log_info(f"[{pair}] 风险控制退出,不走 ML 审核官: exit_reason={exit_reason}")
return True
# 默认允许出场
allow_exit = True
@ -1006,7 +1002,7 @@ class FreqaiPrimer(IStrategy):
if future_vol_signal is not None and exit_reason == 'exit_signal':
# 情况AAI 预测强趋势(高波动),且当前不亏损 → 忽略本次 exit_signal继续持有
if future_vol_signal > 0.65 and current_profit >= 0:
self.log_debug(
self.log_info(
f"[波动率 AI] [{pair}] AI 预测强趋势(高波动 {future_vol_signal:.2f}),忽略本次 exit_signal继续持有 | "
f"持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}"
)
@ -1014,7 +1010,7 @@ class FreqaiPrimer(IStrategy):
return allow_exit
# 情况BAI 预测震荡市(低波动) → 强制接受 exit_signal立即出场
elif future_vol_signal < 0.35:
self.log_debug(
self.log_info(
f"[波动率 AI] [{pair}] AI 预测震荡市(低波动 {future_vol_signal:.2f}),强制接受 exit_signal 出场 | "
f"持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}"
)
@ -1025,17 +1021,23 @@ class FreqaiPrimer(IStrategy):
dynamic_threshold = max(0.05, dynamic_threshold)
if exit_prob < dynamic_threshold:
self.log_debug(
self.log_info(
f"[{pair}] ML 审核官拒绝出场: exit_signal 概率 {exit_prob:.2f} < 动态阈值 {dynamic_threshold:.2f}"
f" | 原应出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}"
f" | 波动率AI: {future_vol_signal if future_vol_signal is not None else 'N/A'}"
)
allow_exit = False
else:
self.log_debug(
f"[{pair}] ML 审核官允许出场: exit_signal 概率 {exit_prob:.2f} >= 动态阈值 {dynamic_threshold:.2f}"
f" | 出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}"
f" | 波动率AI: {future_vol_signal if future_vol_signal is not None else 'N/A'}"
# 计算实际出场价格(使用 hyperopt 参数)
premium_multiplier = 1.0 + self.exit_price_premium.value
adjusted_exit_price = rate * premium_multiplier
self.log_info(
f"[{pair}] ✅ ML 审核官允许出场 | "
f"原始价格: {rate:.8f} | "
f"上调倍率: {premium_multiplier:.6f} (+{self.exit_price_premium.value:.2%}) | "
f"实际出场价: {adjusted_exit_price:.8f} | "
f"出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f} | "
f"波动率AI: {future_vol_signal if future_vol_signal is not None else 'N/A'}"
)
except Exception as e:
logger.warning(f"[{pair}] ML 审核官出场检查失败,允许出场: {e}")
@ -1117,7 +1119,7 @@ class FreqaiPrimer(IStrategy):
# 计算出场价格上浮比例1.25%
price_markup_percent = 1.25
adjusted_exit_price = current_rate * 1.0125
self.log_debug(f"[{pair}] 准备出场 - 市场价: {current_rate:.8f}, 调整后出场价: {adjusted_exit_price:.8f}, 上浮: {price_markup_percent}%, 退出比例: {exit_ratio:.0%}")
self.log_info(f"[{pair}] 准备出场 - 市场价: {current_rate:.8f}, 调整后出场价: {adjusted_exit_price:.8f}, 上浮: {price_markup_percent}%, 退出比例: {exit_ratio:.0%}")
return exit_ratio
@ -1200,7 +1202,6 @@ class FreqaiPrimer(IStrategy):
"""
discount_multiplier = 1.0 - self.entry_price_discount.value
adjusted_price = proposed_rate * discount_multiplier
self.log_debug(f"[实盘入场] [{pair}] 市场价: {proposed_rate:.8f}, 调整后: {adjusted_price:.8f} (-{self.entry_price_discount.value:.2%})")
return adjusted_price
def custom_exit_price(self, pair: str, trade: 'Trade', current_time: datetime,
@ -1211,6 +1212,5 @@ class FreqaiPrimer(IStrategy):
"""
premium_multiplier = 1.0 + self.exit_price_premium.value
adjusted_price = proposed_rate * premium_multiplier
self.log_debug(f"[实盘出场] [{pair}] 市场价: {proposed_rate:.8f}, 调整后: {adjusted_price:.8f} (+{self.exit_price_premium.value:.2%})")
return adjusted_price

View File

@ -190,6 +190,7 @@ echo "docker-compose run --rm freqtrade backtesting $PAIRS_FLAG \
--freqaimodel LightGBMRegressorMultiTarget \
--config /freqtrade/config_examples/$CONFIG_FILE \
--config /freqtrade/templates/freqaiprimer.json \
--config /freqtrade/config_examples/haslog.json \
--strategy-path /freqtrade/templates \
--strategy $STRATEGY_NAME \
--timerange $START_DATE-$END_DATE \
@ -202,6 +203,7 @@ docker-compose run --rm freqtrade backtesting $PAIRS_FLAG \
--freqaimodel LightGBMRegressorMultiTarget \
--config /freqtrade/config_examples/$CONFIG_FILE \
--config /freqtrade/templates/freqaiprimer.json \
--config /freqtrade/config_examples/nolog.json \
--strategy-path /freqtrade/templates \
--enable-protections \
--strategy $STRATEGY_NAME \