feat: Yahoo历史数据根据timeframe和limit动态计算开始日期

This commit is contained in:
OpenClaw Agent 2026-03-17 06:48:27 +00:00
parent a91041e168
commit 2edac30fd8

View File

@ -29,15 +29,10 @@ public interface IYahooMarketService
public class YahooMarketService : IYahooMarketService public class YahooMarketService : IYahooMarketService
{ {
private readonly ILogger<YahooMarketService> _logger; private readonly ILogger<YahooMarketService> _logger;
private readonly YahooQuotes _yahooQuotes;
public YahooMarketService(ILogger<YahooMarketService> logger) public YahooMarketService(ILogger<YahooMarketService> logger)
{ {
_logger = logger; _logger = logger;
// 默认获取最近60天的历史数据
_yahooQuotes = new YahooQuotesBuilder()
.WithHistoryStartDate(Instant.FromDateTimeUtc(DateTime.UtcNow.AddDays(-60)))
.Build();
} }
/// <summary> /// <summary>
@ -55,12 +50,34 @@ public class YahooMarketService : IYahooMarketService
return symbol.ToUpper().Replace(".", "-"); return symbol.ToUpper().Replace(".", "-");
} }
/// <summary>
/// 根据 timeframe 和 limit 计算需要的开始日期
/// </summary>
private DateTime CalculateStartDate(string timeframe, int limit)
{
var now = DateTime.UtcNow;
// 根据周期类型计算需要的天数,预留缓冲
return timeframe.ToLower() switch
{
"1d" or "daily" or "day" => now.AddDays(-limit * 1.5), // 日线limit * 1.5 天
"1w" or "weekly" or "week" => now.AddDays(-limit * 8), // 周线limit * 8 天
"1m" or "monthly" or "month" => now.AddDays(-limit * 35), // 月线limit * 35 天
_ => now.AddDays(-Math.Max(limit * 2, 365)) // 默认至少365天
};
}
public async Task<MarketPriceResponse> GetStockPriceAsync(string symbol) public async Task<MarketPriceResponse> GetStockPriceAsync(string symbol)
{ {
var yahooSymbol = ConvertToYahooSymbol(symbol); var yahooSymbol = ConvertToYahooSymbol(symbol);
_logger.LogInformation("Yahoo获取股票价格: {Symbol} -> {YahooSymbol}", symbol, yahooSymbol); _logger.LogInformation("Yahoo获取股票价格: {Symbol} -> {YahooSymbol}", symbol, yahooSymbol);
Snapshot? snapshot = await _yahooQuotes.GetSnapshotAsync(yahooSymbol); // 实时价格不需要历史数据,使用最小范围
var yahooQuotes = new YahooQuotesBuilder()
.WithHistoryStartDate(Instant.FromDateTimeUtc(DateTime.UtcNow.AddDays(-7)))
.Build();
Snapshot? snapshot = await yahooQuotes.GetSnapshotAsync(yahooSymbol);
if (snapshot is null) if (snapshot is null)
throw new InvalidOperationException($"Yahoo未知标的: {symbol}"); throw new InvalidOperationException($"Yahoo未知标的: {symbol}");
@ -90,7 +107,15 @@ public class YahooMarketService : IYahooMarketService
var yahooSymbol = ConvertToYahooSymbol(symbol); var yahooSymbol = ConvertToYahooSymbol(symbol);
_logger.LogInformation("Yahoo获取历史数据: {Symbol} -> {YahooSymbol}, {Timeframe}, {Limit}", symbol, yahooSymbol, timeframe, limit); _logger.LogInformation("Yahoo获取历史数据: {Symbol} -> {YahooSymbol}, {Timeframe}, {Limit}", symbol, yahooSymbol, timeframe, limit);
Result<History> result = await _yahooQuotes.GetHistoryAsync(yahooSymbol); // 根据请求参数动态计算开始日期
var startDate = CalculateStartDate(timeframe, limit);
_logger.LogDebug("历史数据开始日期: {StartDate}", startDate.ToString("yyyy-MM-dd"));
var yahooQuotes = new YahooQuotesBuilder()
.WithHistoryStartDate(Instant.FromDateTimeUtc(startDate))
.Build();
Result<History> result = await yahooQuotes.GetHistoryAsync(yahooSymbol);
if (result.Value == null) if (result.Value == null)
throw new InvalidOperationException($"Yahoo获取历史数据失败标的: {symbol}"); throw new InvalidOperationException($"Yahoo获取历史数据失败标的: {symbol}");
@ -120,7 +145,7 @@ public class YahooMarketService : IYahooMarketService
.TakeLast(limit) .TakeLast(limit)
.ToList(); .ToList();
_logger.LogInformation("Yahoo获取 {Symbol} 历史数据 {Count} 条", symbol, sortedData.Count); _logger.LogInformation("Yahoo获取 {Symbol} 历史数据 {Count} 条(请求 {Limit} 条)", symbol, sortedData.Count, limit);
return sortedData; return sortedData;
} }