From e5d6cbebda5143b7f12996de2f2f4ec3bcd258c0 Mon Sep 17 00:00:00 2001 From: "zhangkun9038@dingtalk.com" Date: Fri, 6 Feb 2026 23:05:05 +0800 Subject: [PATCH] =?UTF-8?q?log=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- freqtrade/templates/freqaiprimer.py | 96 ++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index c1ea5779..deec5dd5 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -998,9 +998,40 @@ class FreqaiPrimer(IStrategy): ml_prob_str = f"{entry_prob:.2f}" else: ml_prob_str = "N/A" + + # 格式化数字,限制有效位数不超过5位 + def format_number(value, max_digits=5): + """格式化数字,限制有效位数""" + if value == 0: + return "0" + # 转换为字符串并去掉末尾的0 + s = f"{value:.10f}".rstrip('0').rstrip('.') + # 如果小数点前的数字超过max_digits,使用科学计数法 + if len(s.split('.')[0]) > max_digits: + return f"{value:.2e}" + # 如果总长度超过max_digits,截断 + if len(s) > max_digits: + # 保留小数点前的数字 + if '.' in s: + integer_part, decimal_part = s.split('.') + if len(integer_part) > max_digits: + return f"{value:.2e}" + else: + # 截断小数部分 + max_decimal = max_digits - len(integer_part) - 1 + if max_decimal > 0: + s = integer_part + '.' + decimal_part[:max_decimal] + else: + s = integer_part + else: + # 整数部分超过限制 + if len(s) > max_digits: + return f"{value:.2e}" + return s + self.strategy_log( f"[入场诊断] {pair} | " - f"价格: {current_close:.6f} | " + f"价格: {format_number(current_close)} | " f"vs 5K高点: {price_vs_recent_high:+.2%} | " f"vs EMA5: {price_vs_ema5:+.2%} | " f"布林位置: {bb_position:.2f} | " @@ -1152,9 +1183,70 @@ class FreqaiPrimer(IStrategy): future_vol_str = f"{future_vol_signal:.2f}" else: future_vol_str = "N/A" + + # 格式化数字,限制有效位数不超过5位 + def format_number(value, max_digits=5): + """格式化数字,限制有效位数""" + if value == 0: + return "0" + # 转换为字符串并去掉末尾的0 + s = f"{value:.10f}".rstrip('0').rstrip('.') + # 如果小数点前的数字超过max_digits,使用科学计数法 + if len(s.split('.')[0]) > max_digits: + return f"{value:.2e}" + # 如果总长度超过max_digits,截断 + if len(s) > max_digits: + # 保留小数点前的数字 + if '.' in s: + integer_part, decimal_part = s.split('.') + if len(integer_part) > max_digits: + return f"{value:.2e}" + else: + # 截断小数部分 + max_decimal = max_digits - len(integer_part) - 1 + if max_decimal > 0: + s = integer_part + '.' + decimal_part[:max_decimal] + else: + s = integer_part + else: + # 整数部分超过限制 + if len(s) > max_digits: + return f"{value:.2e}" + return s + + # 格式化价格,限制有效位数不超过5位 + def format_number(value, max_digits=5): + """格式化数字,限制有效位数""" + if value == 0: + return "0" + # 转换为字符串并去掉末尾的0 + s = f"{value:.10f}".rstrip('0').rstrip('.') + # 如果小数点前的数字超过max_digits,使用科学计数法 + if len(s.split('.')[0]) > max_digits: + return f"{value:.2e}" + # 如果总长度超过max_digits,截断 + if len(s) > max_digits: + # 保留小数点前的数字 + if '.' in s: + integer_part, decimal_part = s.split('.') + if len(integer_part) > max_digits: + return f"{value:.2e}" + else: + # 截断小数部分 + max_decimal = max_digits - len(integer_part) - 1 + if max_decimal > 0: + s = integer_part + '.' + decimal_part[:max_decimal] + else: + s = integer_part + else: + # 整数部分超过限制 + if len(s) > max_digits: + return f"{value:.2e}" + return s + self.strategy_log( f"[{pair}] ML 审核官允许出场: exit_signal 概率 {exit_prob:.2f} >= 动态阈值 {dynamic_threshold:.2f}" - f" | 出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}" + f" | 出场原因: {exit_reason} | 持仓: {format_number(trade_age_minutes)}min, 利润: {format_number(current_profit)}" f" | 波动率AI: {future_vol_str}" ) except Exception as e: