perf: 优化历史价格获取,优先从缓存表查询

1. 先从 market_kline_cache 缓存表查特定日期价格
2. 缓存命中直接返回,减少 API 调用
3. 缓存未命中才调用 GetHistoricalDataAsync
4. 获取历史数据从 365 天减少到 30 天
5. 大幅减少 Tiingo API 消耗
This commit is contained in:
OpenClaw Agent 2026-03-15 10:12:20 +00:00
parent 267b0bd6ba
commit 34f06ce941

View File

@ -469,22 +469,37 @@ public class PortfolioNavService : IPortfolioNavService
} }
/// <summary> /// <summary>
/// 获取历史价格 /// 获取历史价格(优先从缓存读取)
/// </summary> /// </summary>
private async Task<decimal?> GetHistoricalPriceAsync(string symbol, string assetType, DateTime date) private async Task<decimal?> GetHistoricalPriceAsync(string symbol, string assetType, DateTime date)
{ {
try try
{ {
// 先尝试获取历史数据 // 1. 先从缓存表查特定日期的价格
var historicalData = await _marketDataService.GetHistoricalDataAsync(symbol, assetType, "1d", 365); var cachedPrice = await _db.Queryable<MarketKlineCache>()
.Where(k => k.Symbol == symbol.ToUpper()
&& k.AssetType == assetType.ToUpper()
&& k.Timeframe == "1D"
&& k.Timestamp.Date == date.Date)
.FirstAsync();
if (cachedPrice != null && cachedPrice.Close > 0)
{
_logger.LogDebug("缓存命中: {Symbol} {Date}, 价格: {Price}", symbol, date.ToString("yyyy-MM-dd"), cachedPrice.Close);
return cachedPrice.Close;
}
// 2. 缓存未命中,尝试获取该日期附近的历史数据
var historicalData = await _marketDataService.GetHistoricalDataAsync(symbol, assetType, "1d", 30);
// 精确匹配日期
var priceOnDate = historicalData.FirstOrDefault(d => d.Timestamp.Date == date.Date); var priceOnDate = historicalData.FirstOrDefault(d => d.Timestamp.Date == date.Date);
if (priceOnDate != null && priceOnDate.Close > 0) if (priceOnDate != null && priceOnDate.Close > 0)
{ {
return priceOnDate.Close; return priceOnDate.Close;
} }
// 如果找不到当天数据,找最近的 // 找最近的交易日价格
var nearestPrice = historicalData var nearestPrice = historicalData
.Where(d => d.Timestamp.Date <= date.Date) .Where(d => d.Timestamp.Date <= date.Date)
.OrderByDescending(d => d.Timestamp) .OrderByDescending(d => d.Timestamp)
@ -492,17 +507,18 @@ public class PortfolioNavService : IPortfolioNavService
if (nearestPrice != null && nearestPrice.Close > 0) if (nearestPrice != null && nearestPrice.Close > 0)
{ {
_logger.LogDebug("使用最近交易日价格: {Symbol} {Date} → {ActualDate}",
symbol, date.ToString("yyyy-MM-dd"), nearestPrice.Timestamp.ToString("yyyy-MM-dd"));
return nearestPrice.Close; return nearestPrice.Close;
} }
// 最后尝试获取实时价格 // 3. 最后尝试获取实时价格
var currentPrice = await _marketDataService.GetPriceAsync(symbol, assetType); var currentPrice = await _marketDataService.GetPriceAsync(symbol, assetType);
if (currentPrice != null && currentPrice.Price > 0) if (currentPrice != null && currentPrice.Price > 0)
{ {
return currentPrice.Price; return currentPrice.Price;
} }
// 无法获取有效价格
_logger.LogWarning("无法获取有效价格: {Symbol}, {Date}", symbol, date); _logger.LogWarning("无法获取有效价格: {Symbol}, {Date}", symbol, date);
return null; return null;
} }