.stock now shows a candlestick chart with a sparkline on top of it. Reorganized stock code slightly

This commit is contained in:
Kwoth
2022-02-07 17:50:25 +01:00
parent 22eabff276
commit 0008eabdd2
21 changed files with 334 additions and 99 deletions

View File

@@ -0,0 +1,90 @@
using System.Text.Json;
using YahooFinanceApi;
namespace NadekoBot.Modules.Searches;
public sealed class DefaultStockDataService : IStockDataService, INService
{
private readonly IHttpClientFactory _httpClientFactory;
public DefaultStockDataService(IHttpClientFactory httpClientFactory)
=> _httpClientFactory = httpClientFactory;
public async Task<StockData?> GetStockDataAsync(string query)
{
try
{
if (!query.IsAlphaNumeric())
return default;
var symbols = await Yahoo.Symbols(query)
.Fields(Field.LongName,
Field.Symbol,
Field.RegularMarketPrice,
Field.RegularMarketPreviousClose,
Field.MarketCap,
Field.FiftyDayAverageChangePercent,
Field.TwoHundredDayAverageChangePercent,
Field.AverageDailyVolume10Day,
Field.FullExchangeName)
.QueryAsync();
var symbol = symbols.Values.FirstOrDefault();
if (symbol is null)
return default;
return new()
{
Name = symbol.LongName,
Symbol = symbol.Symbol,
Price = symbol.RegularMarketPrice,
Close = symbol.RegularMarketPreviousClose,
MarketCap = symbol.MarketCap,
Change50d = symbol.FiftyDayAverageChangePercent,
Change200d = symbol.TwoHundredDayAverageChangePercent,
DailyVolume = symbol.AverageDailyVolume10Day,
Exchange = symbol.FullExchangeName
};
}
catch (Exception ex)
{
// what the hell is this api exception
Log.Warning(ex, "Error getting stock data: {ErrorMessage}", ex.Message);
return default;
}
}
public async Task<IReadOnlyCollection<SymbolData>> SearchSymbolAsync(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
query = Uri.EscapeDataString(query);
using var http = _httpClientFactory.CreateClient();
var res = await http.GetStringAsync(
"https://finance.yahoo.com/_finance_doubledown/api/resource/searchassist"
+ $";searchTerm={query}"
+ "?device=console");
var data = JsonSerializer.Deserialize<YahooFinanceSearchResponse>(res);
if (data is null or { Items: null })
return Array.Empty<SymbolData>();
return data.Items
.Where(x => x.Type == "S")
.Select(x => new SymbolData(x.Symbol, x.Name))
.ToList();
}
public async Task<IReadOnlyCollection<CandleData>> GetCandleDataAsync(string query)
{
var candles = await Yahoo.GetHistoricalAsync(query, DateTime.Now.Subtract(30.Days()));
return candles
.Map(static x => new CandleData(x.Open, x.Close, x.High, x.Low, x.Volume));
}
}