From f77a7d995fcd969ae144f4d01f00f625bb4b18f7 Mon Sep 17 00:00:00 2001 From: ooples Date: Sat, 21 Jan 2023 01:51:18 -0500 Subject: [PATCH] Added a method to get the spark chart info --- src/Helpers/DateTimeHelper.cs | 12 ++++++++++- src/Helpers/DownloadHelper.cs | 20 +++++++++++++++++ src/Helpers/InsightsHelper.cs | 3 +-- src/Helpers/SparkChartHelper.cs | 17 +++++++++++++++ src/Helpers/UrlHelper.cs | 16 ++++++++++---- src/Models/SparkChartData.cs | 33 +++++++++++++++++++++++++++++ src/YahooClient.cs | 14 ++++++++++++ tests/TestConsoleApp/Program.cs | 1 + tests/UnitTests/YahooClientTests.cs | 26 +++++++++++++++++++++++ 9 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 src/Helpers/SparkChartHelper.cs create mode 100644 src/Models/SparkChartData.cs diff --git a/src/Helpers/DateTimeHelper.cs b/src/Helpers/DateTimeHelper.cs index fda15ff..fd08e9d 100644 --- a/src/Helpers/DateTimeHelper.cs +++ b/src/Helpers/DateTimeHelper.cs @@ -3,7 +3,7 @@ public static class DateTimeHelper { /// - /// Yahoo Finance requires all dates to be in the Unix format which is the amount of seconds since Jan 1, 1970 + /// Converts a date to the Unix format which is the amount of seconds since Jan 1, 1970 /// /// /// @@ -11,4 +11,14 @@ public static long ToUnixTimestamp(this DateTime dateTime) { return new DateTimeOffset(dateTime).ToUnixTimeSeconds(); } + + /// + /// Converts a data from the Unix format which is the amount of seconds since Jan 1, 1970 to a normal date + /// + /// + /// + public static DateTime FromUnixTimeStamp(this long unixTimestamp) + { + return DateTimeOffset.FromUnixTimeSeconds(unixTimestamp).DateTime; + } } diff --git a/src/Helpers/DownloadHelper.cs b/src/Helpers/DownloadHelper.cs index 3cc74d9..ffc4084 100644 --- a/src/Helpers/DownloadHelper.cs +++ b/src/Helpers/DownloadHelper.cs @@ -145,6 +145,26 @@ internal static async Task DownloadChartDataAsync(string symbol, TimeRan } } + /// + /// Downloads the spark chart json data using the chosen symbol + /// + /// + /// + /// + /// + /// + internal static async Task DownloadSparkChartDataAsync(string symbol, TimeRange timeRange, TimeInterval timeInterval) + { + if (string.IsNullOrWhiteSpace(symbol)) + { + throw new ArgumentException("Symbol Parameter Can't Be Empty Or Null"); + } + else + { + return await DownloadRawDataAsync(BuildYahooSparkChartUrl(symbol, timeRange, timeInterval)); + } + } + /// /// Downloads the stats json data using the chosen symbol /// diff --git a/src/Helpers/InsightsHelper.cs b/src/Helpers/InsightsHelper.cs index 94a6201..b19820d 100644 --- a/src/Helpers/InsightsHelper.cs +++ b/src/Helpers/InsightsHelper.cs @@ -8,11 +8,10 @@ internal class InsightsHelper : YahooJsonBase /// /// /// - /// internal override IEnumerable ParseYahooJsonData(string jsonData) { var insights = JsonSerializer.Deserialize(jsonData); - return insights != null ? (IEnumerable)insights.Finance.Result : Enumerable.Empty(); + return insights != null ? Enumerable.Cast(new InsightsResult[] { insights.Finance.Result }) : Enumerable.Empty(); } } diff --git a/src/Helpers/SparkChartHelper.cs b/src/Helpers/SparkChartHelper.cs new file mode 100644 index 0000000..21b036d --- /dev/null +++ b/src/Helpers/SparkChartHelper.cs @@ -0,0 +1,17 @@ +namespace OoplesFinance.YahooFinanceAPI.Helpers; + +internal class SparkChartHelper : YahooJsonBase +{ + /// + /// Parses the raw json data for the Spark Chart data + /// + /// + /// + /// + internal override IEnumerable ParseYahooJsonData(string jsonData) + { + var sparkChartData = JsonSerializer.Deserialize(jsonData); + + return sparkChartData != null ? Enumerable.Cast(new SparkInfo[] { sparkChartData.Result }) : Enumerable.Empty(); + } +} diff --git a/src/Helpers/UrlHelper.cs b/src/Helpers/UrlHelper.cs index 8d3f455..d5f5145 100644 --- a/src/Helpers/UrlHelper.cs +++ b/src/Helpers/UrlHelper.cs @@ -1,7 +1,4 @@ -using OoplesFinance.YahooFinanceAPI.Enums; -using System.Reflection; - -namespace OoplesFinance.YahooFinanceAPI.Helpers; +namespace OoplesFinance.YahooFinanceAPI.Helpers; internal static class UrlHelper { @@ -54,6 +51,17 @@ internal static Uri BuildYahooChartUrl(string symbol, TimeRange timeRange, TimeI new(string.Format(CultureInfo.InvariantCulture, $"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}?" + $"range={GetTimeRangeString(timeRange)}&interval={GetTimeIntervalString(timeInterval)}")); + /// + /// Creates a url that will be used to get spark chart data for a selected symbol + /// + /// + /// + /// + /// + internal static Uri BuildYahooSparkChartUrl(string symbol, TimeRange timeRange, TimeInterval timeInterval) => + new(string.Format(CultureInfo.InvariantCulture, $"https://query2.finance.yahoo.com/v8/finance/spark?interval=" + + $"{GetTimeIntervalString(timeInterval)}&range={GetTimeRangeString(timeRange)}&symbols={symbol}?")); + /// /// Creates a url that will be used to get stats for a selected symbol /// diff --git a/src/Models/SparkChartData.cs b/src/Models/SparkChartData.cs new file mode 100644 index 0000000..bce6346 --- /dev/null +++ b/src/Models/SparkChartData.cs @@ -0,0 +1,33 @@ +namespace OoplesFinance.YahooFinanceAPI.Models; + +public class SparkInfo +{ + [JsonPropertyName("timestamp")] + public List Timestamp { get; set; } = new(); + + [JsonPropertyName("symbol")] + public string Symbol { get; set; } = string.Empty; + + [JsonPropertyName("previousClose")] + public object PreviousClose { get; set; } = new(); + + [JsonPropertyName("chartPreviousClose")] + public double? ChartPreviousClose { get; set; } + + [JsonPropertyName("dataGranularity")] + public int? DataGranularity { get; set; } + + [JsonPropertyName("end")] + public object End { get; set; } = new(); + + [JsonPropertyName("start")] + public object Start { get; set; } = new(); + + [JsonPropertyName("close")] + public List Close { get; set; } = new(); +} + +public class SparkChartData +{ + public SparkInfo Result { get; set; } = new(); +} \ No newline at end of file diff --git a/src/YahooClient.cs b/src/YahooClient.cs index e44d2a1..d5d4a05 100644 --- a/src/YahooClient.cs +++ b/src/YahooClient.cs @@ -532,9 +532,23 @@ public async Task> GetBalanceSheetHistoryQuar /// Gets chart info data for the selected stock symbol /// /// + /// + /// /// public async Task> GetChartInfoAsync(string symbol, TimeRange timeRange, TimeInterval timeInterval) { return new ChartHelper().ParseYahooJsonData(await DownloadChartDataAsync(symbol, timeRange, timeInterval)); } + + /// + /// Gets spark chart info data for the selected stock symbol + /// + /// + /// + /// + /// + public async Task GetSparkChartInfoAsync(string symbol, TimeRange timeRange, TimeInterval timeInterval) + { + return new SparkChartHelper().ParseYahooJsonData(await DownloadSparkChartDataAsync(symbol, timeRange, timeInterval)).First(); + } } \ No newline at end of file diff --git a/tests/TestConsoleApp/Program.cs b/tests/TestConsoleApp/Program.cs index 8ab91a0..8146d23 100644 --- a/tests/TestConsoleApp/Program.cs +++ b/tests/TestConsoleApp/Program.cs @@ -43,5 +43,6 @@ var cashflowStatementHistoryQuarterlyList = await yahooClient.GetCashflowStatementHistoryQuarterlyAsync(symbol); var balanceSheetHistoryQuarterlyList = await yahooClient.GetBalanceSheetHistoryQuarterlyAsync(symbol); var chartInfoList = await yahooClient.GetChartInfoAsync(symbol, TimeRange._1Day, TimeInterval._1Minute); +var sparkChartInfoList = await yahooClient.GetSparkChartInfoAsync(symbol, TimeRange._1Month, TimeInterval._1Day); Console.WriteLine(); \ No newline at end of file diff --git a/tests/UnitTests/YahooClientTests.cs b/tests/UnitTests/YahooClientTests.cs index 3497fb5..6674106 100644 --- a/tests/UnitTests/YahooClientTests.cs +++ b/tests/UnitTests/YahooClientTests.cs @@ -991,4 +991,30 @@ public async Task GetChartInfo_ThrowsException_WhenEmptySymbolIsUsed() // Assert await result.Should().ThrowAsync().WithMessage("Symbol Parameter Can't Be Empty Or Null"); } + + [Fact] + public async Task GetSparkChartInfo_ThrowsException_WhenNoSymbolIsFound() + { + // Arrange + var symbol = "OOPLES"; + + // Act + var result = async () => await _sut.GetSparkChartInfoAsync(symbol, TimeRange._1Day, TimeInterval._1Minute); + + // Assert + await result.Should().ThrowAsync().WithMessage("Requested Information Not Available On Yahoo Finance"); + } + + [Fact] + public async Task GetSparkChartInfo_ThrowsException_WhenEmptySymbolIsUsed() + { + // Arrange + var symbol = ""; + + // Act + var result = async () => await _sut.GetSparkChartInfoAsync(symbol, TimeRange._1Day, TimeInterval._1Minute); + + // Assert + await result.Should().ThrowAsync().WithMessage("Symbol Parameter Can't Be Empty Or Null"); + } } \ No newline at end of file