替换股票行情接口为腾讯财经:免费无限制,支持盘前盘后实时价格,自动降级Tiingo
This commit is contained in:
parent
7685782bb4
commit
ece055fc10
@ -39,7 +39,7 @@ public class MarketDataService : IMarketDataService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取股票实时价格
|
||||
/// 获取股票实时价格(使用腾讯财经接口,免费无限制,支持盘前盘后)
|
||||
/// </summary>
|
||||
/// <param name="symbol">股票代码</param>
|
||||
/// <returns>股票价格信息</returns>
|
||||
@ -47,36 +47,81 @@ public class MarketDataService : IMarketDataService
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation($"Requesting stock price for symbol: {symbol}");
|
||||
_logger.LogInformation($"Requesting stock price for symbol: {symbol} (腾讯财经接口)");
|
||||
|
||||
// Tiingo 日线最新价格端点(取最近1条)
|
||||
var url = $"https://api.tiingo.com/tiingo/daily/{symbol}/prices?token={_tiingoApiKey}";
|
||||
var response = await _httpClient.GetFromJsonAsync<List<TiingoDailyResponse>>(url);
|
||||
// 腾讯财经美股接口:前缀us,小写代码
|
||||
var url = $"http://qt.gtimg.cn/q=us{symbol.ToLower()}";
|
||||
var response = await _httpClient.GetStringAsync(url);
|
||||
|
||||
if (response == null || response.Count == 0)
|
||||
if (string.IsNullOrEmpty(response) || !response.Contains("~"))
|
||||
{
|
||||
throw new Exception($"No data found for {symbol}");
|
||||
throw new Exception($"腾讯财经接口返回无效数据,标的: {symbol}");
|
||||
}
|
||||
|
||||
var latest = response[^1];
|
||||
decimal? prevClose = response.Count >= 2 ? response[^2].close : null;
|
||||
// 解析返回数据
|
||||
var parts = response.Split('"')[1].Split('~');
|
||||
if (parts.Length < 36)
|
||||
{
|
||||
throw new Exception($"腾讯财经返回字段不足,标的: {symbol}");
|
||||
}
|
||||
|
||||
// 提取字段:[3]=最新价 [4]=昨收价
|
||||
if (!decimal.TryParse(parts[3], out var currentPrice) || currentPrice <= 0)
|
||||
{
|
||||
throw new Exception($"解析最新价失败,标的: {symbol},返回值: {parts[3]}");
|
||||
}
|
||||
|
||||
if (!decimal.TryParse(parts[4], out var prevClose) || prevClose <= 0)
|
||||
{
|
||||
prevClose = currentPrice; // 解析失败用当前价当昨收
|
||||
}
|
||||
|
||||
return new MarketPriceResponse
|
||||
{
|
||||
Symbol = symbol,
|
||||
Price = latest.close ?? 0,
|
||||
PreviousClose = prevClose ?? 0,
|
||||
Timestamp = latest.date ?? DateTime.UtcNow,
|
||||
Price = currentPrice,
|
||||
PreviousClose = prevClose,
|
||||
Timestamp = DateTime.UtcNow,
|
||||
AssetType = "Stock"
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"Error getting stock price for {symbol}");
|
||||
throw;
|
||||
_logger.LogError(ex, $"腾讯财经接口获取价格失败,标的: {symbol},降级使用Tiingo接口");
|
||||
// 降级使用Tiingo接口
|
||||
return await GetStockPriceFromTiingoAsync(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Tiingo获取股票价格(降级用)
|
||||
/// </summary>
|
||||
private async Task<MarketPriceResponse> GetStockPriceFromTiingoAsync(string symbol)
|
||||
{
|
||||
_logger.LogInformation($"Requesting stock price for symbol: {symbol} (Tiingo接口)");
|
||||
|
||||
// Tiingo 日线最新价格端点(取最近1条)
|
||||
var url = $"https://api.tiingo.com/tiingo/daily/{symbol}/prices?token={_tiingoApiKey}";
|
||||
var response = await _httpClient.GetFromJsonAsync<List<TiingoDailyResponse>>(url);
|
||||
|
||||
if (response == null || response.Count == 0)
|
||||
{
|
||||
throw new Exception($"No data found for {symbol}");
|
||||
}
|
||||
|
||||
var latest = response[^1];
|
||||
decimal? prevClose = response.Count >= 2 ? response[^2].close : null;
|
||||
|
||||
return new MarketPriceResponse
|
||||
{
|
||||
Symbol = symbol,
|
||||
Price = latest.close ?? 0,
|
||||
PreviousClose = prevClose ?? 0,
|
||||
Timestamp = latest.date ?? DateTime.UtcNow,
|
||||
AssetType = "Stock"
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取加密货币实时价格
|
||||
/// </summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user