diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index b961e557..a454d1a9 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -8,11 +8,24 @@ import pandas as pd import pandas_ta as ta from freqtrade.persistence import Trade import numpy as np -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta import math logger = logging.getLogger(__name__) +# ========== 时区统一管理 ========== +# 全局强制使用 UTC+8 时区(所有虚机统一为 UTC+8) +UTC_PLUS_8 = timezone(timedelta(hours=8)) + +def get_current_time() -> datetime: + """ + 获取当前时间(UTC+8) + + 用途:所有时间获取统一使用此函数 + 返回:datetime 对象(timezone-aware,UTC+8) + """ + return datetime.now(UTC_PLUS_8) + class FreqaiPrimer(IStrategy): # 策略参数 - 使用custom_roi替代minimal_roi字典 loglevel = "warning" @@ -47,7 +60,7 @@ class FreqaiPrimer(IStrategy): self._last_entry_time = {} # 冷启动保护:记录策略启动时间 - self._strategy_start_time = datetime.now(timezone.utc) + self._strategy_start_time = get_current_time() # ========== 数据新鲜度监控统计 ========== # 用于量化和诊断数据延迟问题的严重性 @@ -125,9 +138,7 @@ class FreqaiPrimer(IStrategy): 输出数据新鲜度统计报告 :param force: 强制输出(忽略时间间隔) """ - from datetime import datetime, timezone - - current_time = datetime.now(timezone.utc) + current_time = get_current_time() stats = self._freshness_stats # 检查是否需要报告 @@ -218,8 +229,8 @@ class FreqaiPrimer(IStrategy): return 1.0 try: - # 获取当前时间戳 - current_time = datetime.now().timestamp() + # 获取当前时间戳(UTC+8) + current_time = get_current_time().timestamp() # 检查缓存:如果距离上次计算时间小于更新间隔,则直接返回缓存值 if (pair in self._volatility_cache and @@ -896,16 +907,12 @@ class FreqaiPrimer(IStrategy): # 计算数据延迟(只在 Live/Dryrun 模式下) try: - from datetime import timezone - current_time = datetime.now(timezone.utc) + current_time = get_current_time() - # 处理时区 - if data_timestamp.tzinfo is None and current_time.tzinfo is not None: - import pytz - data_timestamp = pytz.utc.localize(data_timestamp) - elif data_timestamp.tzinfo is not None and current_time.tzinfo is None: - import pytz - current_time = pytz.utc.localize(current_time) + # 强制转换 data_timestamp 为 UTC+8 + if data_timestamp.tzinfo is None: + # 假设 naive datetime 是 UTC+8 + data_timestamp = data_timestamp.replace(tzinfo=UTC_PLUS_8) data_age_minutes = (current_time - data_timestamp).total_seconds() / 60 data_age_str = f"{data_age_minutes:.1f}min" @@ -1145,19 +1152,11 @@ class FreqaiPrimer(IStrategy): # 计算数据延迟(分钟) if isinstance(data_timestamp, datetime): - # 获取当前 UTC 时间 - from datetime import timezone - current_time = datetime.now(timezone.utc) + current_time = get_current_time() - # 处理时区一致性 - if data_timestamp.tzinfo is None and current_time.tzinfo is not None: - # 如果 data_timestamp 没有时区,假设为 UTC - import pytz - data_timestamp = pytz.utc.localize(data_timestamp) - elif data_timestamp.tzinfo is not None and current_time.tzinfo is None: - # 如果 current_time 没有时区,假设为 UTC - import pytz - current_time = pytz.utc.localize(current_time) + # 强制转换 data_timestamp 为 UTC+8 + if data_timestamp.tzinfo is None: + data_timestamp = data_timestamp.replace(tzinfo=UTC_PLUS_8) data_age_minutes = (current_time - data_timestamp).total_seconds() / 60 @@ -1249,17 +1248,11 @@ class FreqaiPrimer(IStrategy): # 计算数据延迟 if isinstance(data_timestamp, datetime): - # 获取当前 UTC 时间 - from datetime import timezone - current_time = datetime.now(timezone.utc) + current_time = get_current_time() - # 处理时区 - if data_timestamp.tzinfo is None and current_time.tzinfo is not None: - import pytz - data_timestamp = pytz.utc.localize(data_timestamp) - elif data_timestamp.tzinfo is not None and current_time.tzinfo is None: - import pytz - current_time = pytz.utc.localize(current_time) + # 强制转换 data_timestamp 为 UTC+8 + if data_timestamp.tzinfo is None: + data_timestamp = data_timestamp.replace(tzinfo=UTC_PLUS_8) data_age_minutes = (current_time - data_timestamp).total_seconds() / 60 data_age_str = f"{data_age_minutes:.1f}min"