feat(core): add internal crypto isin resolution and subtitle mapping
This commit is contained in:
@@ -45,15 +45,18 @@ public class YahooFinanceScraper : IYahooFinanceScraper
|
||||
{
|
||||
private readonly YahooFinanceClient _yahooApiClient;
|
||||
private readonly IYahooFinanceHtmlClient _htmlScraperClient;
|
||||
private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration;
|
||||
private readonly IFinlyticLogger<YahooFinanceScraper, FundamentalsDbContext> _finlyticLogger;
|
||||
|
||||
public YahooFinanceScraper(
|
||||
YahooFinanceClient yahooApiClient,
|
||||
IYahooFinanceHtmlClient htmlScraperClient,
|
||||
Microsoft.Extensions.Configuration.IConfiguration configuration,
|
||||
IFinlyticLogger<YahooFinanceScraper, FundamentalsDbContext> finlyticLogger)
|
||||
{
|
||||
_yahooApiClient = yahooApiClient;
|
||||
_htmlScraperClient = htmlScraperClient;
|
||||
_configuration = configuration;
|
||||
_finlyticLogger = finlyticLogger;
|
||||
}
|
||||
|
||||
@@ -72,21 +75,72 @@ public class YahooFinanceScraper : IYahooFinanceScraper
|
||||
var cleanIsin = isin.Trim().ToUpperInvariant();
|
||||
var symbols = new List<(string symbol, string exchange, int priority)>();
|
||||
|
||||
// Crypto / Trade Republic interne ISINs (beginnend mit 'X', z. B. XF000BTC0017)
|
||||
if (cleanIsin.StartsWith("X", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var (cryptoSubtitle, cryptoName) = await FinlyticCore.Utils.CryptoSubtitleResolver.ResolveCryptoInfoAsync(
|
||||
cleanIsin, _configuration.GetConnectionString("DefaultConnection"), cancellationToken);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(cryptoSubtitle))
|
||||
{
|
||||
var cryptoEur = $"{cryptoSubtitle}-EUR";
|
||||
var cryptoUsd = $"{cryptoSubtitle}-USD";
|
||||
|
||||
symbols.Add((cryptoEur, "Crypto", 0));
|
||||
symbols.Add((cryptoUsd, "Crypto", 1));
|
||||
|
||||
try
|
||||
{
|
||||
var searchRes = await _yahooApiClient.SearchAsync(cryptoSubtitle, quotesCount: 10, cancellationToken: cancellationToken);
|
||||
if (searchRes?.Quotes != null)
|
||||
{
|
||||
foreach (var q in searchRes.Quotes.Where(q => !string.IsNullOrEmpty(q.Symbol)))
|
||||
{
|
||||
if (!symbols.Any(s => s.symbol.Equals(q.Symbol, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
symbols.Add((q.Symbol, q.Exchange ?? "Crypto", 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
await _finlyticLogger.LogInfoAsync(SettingKeys.FundamentalsChannel,
|
||||
"[YahooFinanceScraper] Resolved Crypto ISIN {Isin} to {Symbol} using Subtitle {Sub}",
|
||||
cleanIsin, cryptoEur, cryptoSubtitle);
|
||||
|
||||
return symbols
|
||||
.OrderBy(s => s.priority)
|
||||
.Select(s => new TickerInfoDto { Ticker = s.symbol, Exchange = s.exchange })
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 1. Suche via ISIN
|
||||
// 1. Suche via ISIN - der allererste Ticker von Yahoo Finance ist der absolute Primary Ticker
|
||||
var primary = await _yahooApiClient.SearchAsync(cleanIsin, quotesCount: 20, cancellationToken: cancellationToken);
|
||||
var quotes = primary?.Quotes ?? new List<YahooSearchQuoteDto>();
|
||||
var validQuotes = quotes.Where(q => !string.IsNullOrEmpty(q.Symbol)).ToList();
|
||||
|
||||
foreach (var q in quotes.Where(q => !string.IsNullOrEmpty(q.Symbol)))
|
||||
if (validQuotes.Count > 0)
|
||||
{
|
||||
symbols.Add((q.Symbol, q.Exchange ?? string.Empty, GetExchangePriority(q.Symbol, cleanIsin)));
|
||||
var first = validQuotes[0];
|
||||
symbols.Add((first.Symbol, first.Exchange ?? string.Empty, 0));
|
||||
|
||||
foreach (var q in validQuotes.Skip(1))
|
||||
{
|
||||
if (!symbols.Any(s => s.symbol.Equals(q.Symbol, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
symbols.Add((q.Symbol, q.Exchange ?? string.Empty, Math.Max(1, GetExchangePriority(q.Symbol, cleanIsin))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Falls Ticker gefunden, aber mit Unternehmensname noch mehr Exchangeticker auffindbar sind
|
||||
if (quotes.Count > 0)
|
||||
if (validQuotes.Count > 0)
|
||||
{
|
||||
var companyName = quotes[0].LongName ?? quotes[0].ShortName;
|
||||
var companyName = validQuotes[0].LongName ?? validQuotes[0].ShortName;
|
||||
if (!string.IsNullOrWhiteSpace(companyName))
|
||||
{
|
||||
var secondary = await _yahooApiClient.SearchAsync(companyName, quotesCount: 20, cancellationToken: cancellationToken);
|
||||
@@ -95,7 +149,7 @@ public class YahooFinanceScraper : IYahooFinanceScraper
|
||||
if (!string.IsNullOrEmpty(q.Symbol) &&
|
||||
!symbols.Any(s => s.symbol.Equals(q.Symbol, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
symbols.Add((q.Symbol, q.Exchange ?? string.Empty, GetExchangePriority(q.Symbol, cleanIsin)));
|
||||
symbols.Add((q.Symbol, q.Exchange ?? string.Empty, Math.Max(1, GetExchangePriority(q.Symbol, cleanIsin))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user