替换股票行情接口为东方财富:返回实际交易价格,与券商显示一致,无复权偏差

This commit is contained in:
claw_bot 2026-03-12 05:11:50 +00:00
parent 049050d88e
commit 534ba7c343
2 changed files with 53 additions and 29 deletions

View File

@ -16,7 +16,12 @@
"launchUrl": "swagger", "launchUrl": "swagger",
"applicationUrl": "http://localhost:5050", "applicationUrl": "http://localhost:5050",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development",
"ConnectionStrings__Default": "server=localhost;database=assetmanager;user=root;password=你的数据库密码;",
"Jwt__SecretKey": "你的JWT密钥至少16位",
"Jwt__Issuer": "AssetManager",
"Jwt__Audience": "AssetManager",
"Tiingo__ApiKey": "你的TiingoAPI密钥"
} }
}, },
"https": { "https": {
@ -26,7 +31,12 @@
"launchUrl": "swagger", "launchUrl": "swagger",
"applicationUrl": "https://localhost:7040;http://localhost:5050", "applicationUrl": "https://localhost:7040;http://localhost:5050",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development",
"ConnectionStrings__Default": "server=localhost;database=assetmanager;user=root;password=你的数据库密码;",
"Jwt__SecretKey": "你的JWT密钥至少16位",
"Jwt__Issuer": "AssetManager",
"Jwt__Audience": "AssetManager",
"Tiingo__ApiKey": "你的TiingoAPI密钥"
} }
}, },
"IIS Express": { "IIS Express": {
@ -34,7 +44,12 @@
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "swagger", "launchUrl": "swagger",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development",
"ConnectionStrings__Default": "server=localhost;database=assetmanager;user=root;password=你的数据库密码;",
"Jwt__SecretKey": "你的JWT密钥至少16位",
"Jwt__Issuer": "AssetManager",
"Jwt__Audience": "AssetManager",
"Tiingo__ApiKey": "你的TiingoAPI密钥"
} }
} }
} }

View File

@ -39,7 +39,7 @@ public class MarketDataService : IMarketDataService
} }
/// <summary> /// <summary>
/// 获取股票实时价格(使用腾讯财经接口,免费无限制,支持盘前盘后 /// 获取股票实时价格(使用东方财富接口,免费无限制,返回实际交易价格,和券商一致
/// </summary> /// </summary>
/// <param name="symbol">股票代码</param> /// <param name="symbol">股票代码</param>
/// <returns>股票价格信息</returns> /// <returns>股票价格信息</returns>
@ -47,36 +47,22 @@ public class MarketDataService : IMarketDataService
{ {
try try
{ {
_logger.LogInformation($"Requesting stock price for symbol: {symbol} (腾讯财经接口)"); _logger.LogInformation($"Requesting stock price for symbol: {symbol} (东方财富接口)");
// 腾讯财经美股接口前缀us大写代码 // 东方财富美股接口secid=105.代码105代表美股
var url = $"http://qt.gtimg.cn/q=us{symbol.ToUpper()}"; var url = $"https://push2.eastmoney.com/api/qt/stock/get?secid=105.{symbol.ToUpper()}&ut=fa5fd1943c7b386f172d6893dbfba10b&fields=f43,f60&np=1&fltt=2&invt=2";
var response = await _httpClient.GetStringAsync(url); var response = await _httpClient.GetFromJsonAsync<EastMoneyStockResponse>(url);
if (string.IsNullOrEmpty(response) || !response.Contains("~")) if (response?.data == null || response.data.f43 <= 0)
{ {
throw new Exception($"腾讯财经接口返回无效数据,标的: {symbol}"); throw new Exception($"东方财富接口返回无效数据,标的: {symbol}");
} }
// 解析返回数据 // 提取字段f43=最新价 f60=昨收价,单位都是分,转成元
var parts = response.Split('"')[1].Split('~'); var currentPrice = response.data.f43 / 100m;
if (parts.Length < 36) var prevClose = response.data.f60 / 100m;
{
throw new Exception($"腾讯财经返回字段不足,标的: {symbol}");
}
// 提取字段:[3]=最新价 [4]=昨收价 _logger.LogDebug("东方财富接口返回 {Symbol}:最新价 {CurrentPrice},昨收价 {PrevClose},涨跌额 {Change}",
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; // 解析失败用当前价当昨收
}
_logger.LogDebug("腾讯财经接口返回 {Symbol}:最新价 {CurrentPrice},昨收价 {PrevClose},涨跌额 {Change}",
symbol, currentPrice, prevClose, currentPrice - prevClose); symbol, currentPrice, prevClose, currentPrice - prevClose);
return new MarketPriceResponse return new MarketPriceResponse
@ -90,12 +76,35 @@ public class MarketDataService : IMarketDataService
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, $"腾讯财经接口获取价格失败,标的: {symbol}降级使用Tiingo接口"); _logger.LogError(ex, $"东方财富接口获取价格失败,标的: {symbol}降级使用Tiingo接口");
// 降级使用Tiingo接口 // 降级使用Tiingo接口
return await GetStockPriceFromTiingoAsync(symbol); return await GetStockPriceFromTiingoAsync(symbol);
} }
} }
/// <summary>
/// 东方财富美股接口响应模型
/// </summary>
internal class EastMoneyStockResponse
{
public EastMoneyStockData? data { get; set; }
public int rc { get; set; }
public string? msg { get; set; }
}
internal class EastMoneyStockData
{
/// <summary>
/// 最新价(单位:分)
/// </summary>
public decimal f43 { get; set; }
/// <summary>
/// 昨收价(单位:分)
/// </summary>
public decimal f60 { get; set; }
}
/// <summary> /// <summary>
/// 从Tiingo获取股票价格降级用 /// 从Tiingo获取股票价格降级用
/// </summary> /// </summary>