diff --git a/freqtrade/templates/freqaiprimer.py b/freqtrade/templates/freqaiprimer.py index 9a58ba10..0d40868f 100644 --- a/freqtrade/templates/freqaiprimer.py +++ b/freqtrade/templates/freqaiprimer.py @@ -84,6 +84,39 @@ class FreqaiPrimer(IStrategy): else: logger.info(message) + def calculate_data_freshness(self, data_timestamp: datetime, pair: str, dataframe: DataFrame) -> float: + """ + 计算数据新鲜度(与交易所最新数据比较) + :param data_timestamp: 数据时间戳 + :param pair: 交易对 + :param dataframe: 数据框 + :return: 数据延迟时间(分钟) + """ + try: + # 转换为UTC+8时间 + if data_timestamp.tzinfo is None: + data_timestamp = data_timestamp.replace(tzinfo=timezone.utc) + data_timestamp_utc8 = data_timestamp.astimezone(UTC_PLUS_8).replace(tzinfo=None) + + # 获取交易所的最新数据时间 + exchange_latest_candle, exchange_latest_date = self.get_latest_candle(pair, self.timeframe, dataframe) + + if exchange_latest_date: + # 转换为UTC+8时间进行比较 + if exchange_latest_date.tzinfo is None: + exchange_latest_date = exchange_latest_date.replace(tzinfo=timezone.utc) + exchange_latest_utc8 = exchange_latest_date.astimezone(UTC_PLUS_8).replace(tzinfo=None) + freshness_minutes = (exchange_latest_utc8 - data_timestamp_utc8).total_seconds() / 60 + else: + # 如果无法获取交易所最新时间,使用保守估计(3分钟延迟) + freshness_minutes = 3.0 + + return max(0.0, freshness_minutes) # 确保不会返回负数 + + except Exception as e: + self.strategy_log(f"[{pair}] 数据新鲜度计算异常: {e}", "warning") + return 3.0 # 异常时返回保守估计 + def update_freshness_stats(self, pair: str, data_age_minutes: float) -> None: """ 更新数据新鲜度统计 @@ -519,15 +552,9 @@ class FreqaiPrimer(IStrategy): latest_date = latest_date.to_pydatetime() except: pass - # 计算ML数据新鲜度 + # 计算ML数据新鲜度(使用统一函数) if isinstance(latest_date, datetime): - # 转换为UTC+8时间 - if latest_date.tzinfo is None: - latest_date = latest_date.replace(tzinfo=timezone.utc) - latest_date_utc8 = latest_date.astimezone(UTC_PLUS_8).replace(tzinfo=None) - - current_time_utc8 = datetime.now().replace(tzinfo=UTC_PLUS_8).replace(tzinfo=None) - ml_age_minutes = (current_time_utc8 - latest_date_utc8).total_seconds() / 60 + ml_age_minutes = self.calculate_data_freshness(latest_date, metadata['pair'], dataframe) # 检查目标变量的类型和新鲜度 target_vars = [] @@ -977,23 +1004,8 @@ class FreqaiPrimer(IStrategy): display_latest = display_latest.replace(tzinfo=timezone.utc) display_latest = display_latest.astimezone(UTC_PLUS_8) latest_time_str = display_latest.strftime('%H:%M:%S') - # 计算数据新鲜度(与交易所最新数据比较) - latest_naive = display_latest.replace(tzinfo=None) - - # 获取交易所的最新数据时间 - exchange_latest_candle, exchange_latest_date = self.get_latest_candle( - metadata['pair'], self.timeframe, dataframe - ) - - if exchange_latest_date: - # 转换为UTC+8时间进行比较 - if exchange_latest_date.tzinfo is None: - exchange_latest_date = exchange_latest_date.replace(tzinfo=timezone.utc) - exchange_latest_utc8 = exchange_latest_date.astimezone(UTC_PLUS_8).replace(tzinfo=None) - data_freshness = (exchange_latest_utc8 - latest_naive).total_seconds() / 60 - else: - # 如果无法获取交易所最新时间,使用保守估计(3分钟延迟) - data_freshness = 3.0 + # 计算数据新鲜度(使用统一函数) + data_freshness = self.calculate_data_freshness(latest_data_date, metadata['pair'], dataframe) # 数据新鲜度判断 if data_freshness <= 3: # 3分钟内为新鲜数据 @@ -1016,20 +1028,8 @@ class FreqaiPrimer(IStrategy): latest_time_str = display_latest.strftime('%H:%M:%S') latest_naive = display_latest.replace(tzinfo=None) - # 获取交易所的最新数据时间 - exchange_latest_candle, exchange_latest_date = self.get_latest_candle( - metadata['pair'], self.timeframe, dataframe - ) - - if exchange_latest_date: - # 转换为UTC+8时间进行比较 - if exchange_latest_date.tzinfo is None: - exchange_latest_date = exchange_latest_date.replace(tzinfo=timezone.utc) - exchange_latest_utc8 = exchange_latest_date.astimezone(UTC_PLUS_8).replace(tzinfo=None) - data_freshness = (exchange_latest_utc8 - latest_naive).total_seconds() / 60 - else: - # 如果无法获取交易所最新时间,使用保守估计(3分钟延迟) - data_freshness = 3.0 + # 计算数据新鲜度(使用统一函数) + data_freshness = self.calculate_data_freshness(latest_data_date, metadata['pair'], dataframe) # 数据新鲜度判断 if data_freshness <= 3: # 3分钟内为新鲜数据 @@ -1311,17 +1311,11 @@ class FreqaiPrimer(IStrategy): except: pass - # 计算数据延迟(分钟) + # 计算数据延迟(分钟)- 使用统一函数 if isinstance(data_timestamp, datetime): - current_time = datetime.now() - - # FreqAI dataframe 的 date 列是 UTC 时间 - if data_timestamp.tzinfo is None: - data_timestamp = data_timestamp.replace(tzinfo=timezone.utc) - # 转换为 UTC+8 并移除时区信息 - data_timestamp = data_timestamp.astimezone(UTC_PLUS_8).replace(tzinfo=None) - - data_age_minutes = (current_time - data_timestamp).total_seconds() / 60 + # 获取当前数据框用于计算新鲜度 + current_df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) + data_age_minutes = self.calculate_data_freshness(data_timestamp, pair, current_df) # 📊 更新统计数据 self.update_freshness_stats(pair, data_age_minutes)