From b7c9ed2904b735e7b0cb308bb0fb5defe9e86f60 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 11 May 2025 20:09:07 -0700 Subject: [PATCH] Got query to return data. --- ConsoleAppTest/ConsoleAppTest.csproj | 14 ++++ ConsoleAppTest/Program.cs | 12 ++++ Polygon.Client.sln | 6 ++ Polygon.Client/AllTickersRequest.cs | 76 ++++++++++++++++++---- Polygon.Client/AllTickersResponseItem.cs | 16 ++++- Polygon.Client/PolygonClient.AllTickers.cs | 38 +++++++---- Polygon.Client/PolygonClient.cs | 14 ++-- Polygon.Client/RequestQueryBuilder .cs | 48 ++++++++++++++ 8 files changed, 190 insertions(+), 34 deletions(-) create mode 100644 ConsoleAppTest/ConsoleAppTest.csproj create mode 100644 ConsoleAppTest/Program.cs create mode 100644 Polygon.Client/RequestQueryBuilder .cs diff --git a/ConsoleAppTest/ConsoleAppTest.csproj b/ConsoleAppTest/ConsoleAppTest.csproj new file mode 100644 index 0000000..2c9be52 --- /dev/null +++ b/ConsoleAppTest/ConsoleAppTest.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/ConsoleAppTest/Program.cs b/ConsoleAppTest/Program.cs new file mode 100644 index 0000000..957f4c3 --- /dev/null +++ b/ConsoleAppTest/Program.cs @@ -0,0 +1,12 @@ +using Polygon.Client; + +Console.WriteLine("Start"); + +var client = new PolygonClient(""); +var request = new AllTickersRequest(); +var result = await client.GetAllTickersAsync(request); +var a = result.Results.ToList(); + +Console.WriteLine(result.Status); +Console.WriteLine("End"); +Console.ReadKey(); diff --git a/Polygon.Client.sln b/Polygon.Client.sln index 13db0c9..16f74ab 100644 --- a/Polygon.Client.sln +++ b/Polygon.Client.sln @@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polygon.Client", "Polygon.Client\Polygon.Client.csproj", "{B6CA2C9B-AADB-4039-F459-2ED89AFA0461}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppTest", "ConsoleAppTest\ConsoleAppTest.csproj", "{0FD8AE9A-A1E3-4018-B6C1-D987CB1D493B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -23,6 +25,10 @@ Global {B6CA2C9B-AADB-4039-F459-2ED89AFA0461}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6CA2C9B-AADB-4039-F459-2ED89AFA0461}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6CA2C9B-AADB-4039-F459-2ED89AFA0461}.Release|Any CPU.Build.0 = Release|Any CPU + {0FD8AE9A-A1E3-4018-B6C1-D987CB1D493B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FD8AE9A-A1E3-4018-B6C1-D987CB1D493B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FD8AE9A-A1E3-4018-B6C1-D987CB1D493B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FD8AE9A-A1E3-4018-B6C1-D987CB1D493B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Polygon.Client/AllTickersRequest.cs b/Polygon.Client/AllTickersRequest.cs index 47fde89..30115dc 100644 --- a/Polygon.Client/AllTickersRequest.cs +++ b/Polygon.Client/AllTickersRequest.cs @@ -1,16 +1,64 @@ namespace Polygon.Client; -public record AllTickersRequest( - string Ticker, - string Type, - Market Market, - string Exchange, - string Cusip, - string Cik, - DateOnly? Date, - string Search, - bool Active, - Order Order, - int Limit, - Sort Sort -); +public class AllTickersRequest +{ + /// + /// + /// + public string? Ticker { get; set; } + + /// + /// + /// + public string? Type { get; set; } + + /// + /// + /// + public Market Market { get; set; } = Market.Stock; + + /// + /// + /// + public string? Exchange { get; set; } + + /// + /// + /// + public string? Cusip { get; set; } + + /// + /// + /// + public string? Cik { get; set; } + + /// + /// + /// + public DateOnly? Date { get; set; } + + /// + /// + /// + public string? Search { get; set; } + + /// + /// + /// + public bool Active { get; set; } = true; + + /// + /// + /// + public Order Order { get; set; } = Order.Asc; + + /// + /// + /// + public int Limit { get; set; } = 100; + + /// + /// + /// + public Sort Sort { get; set; } = Sort.Ticker; +} diff --git a/Polygon.Client/AllTickersResponseItem.cs b/Polygon.Client/AllTickersResponseItem.cs index 2ff35dd..e62fb67 100644 --- a/Polygon.Client/AllTickersResponseItem.cs +++ b/Polygon.Client/AllTickersResponseItem.cs @@ -1,3 +1,17 @@ namespace Polygon.Client; -public record AllTickersResponseItem(); +public record AllTickersResponseItem( + bool Active, + string Cik, + string Composite_Figi, + string Currency_Name, + string Delisted_Utc, + string Last_Updated_Utc, + string Locale, + string Market, + string Name, + string Primary_Exchange, + string Share_Class_Figi, + string Ticker, + string Type +); diff --git a/Polygon.Client/PolygonClient.AllTickers.cs b/Polygon.Client/PolygonClient.AllTickers.cs index 33671a1..7f140dc 100644 --- a/Polygon.Client/PolygonClient.AllTickers.cs +++ b/Polygon.Client/PolygonClient.AllTickers.cs @@ -20,12 +20,20 @@ public partial class PolygonClient ) { var tickerList = new List(); - var tickerUrl = - $"/v3/reference/tickers" - + $"?ticker={request.Ticker}&type={request.Type}&market={request.Market}" - + $"&exchange={request.Exchange}&cusip={request.Cusip}&cik={request.Cik}" - + $"&date={request.Date}&search={request.Search}&active={request.Active}" - + $"&order={request.Order}&sort={request.Sort}&limit={request.Limit}"; + var tickerUrl = new RequestQueryBuilder("/v3/reference/tickers") + .Add("ticker", request.Ticker) + .Add("type", request.Type) + .Add("market", request.Market) + .Add("exchange", request.Exchange) + .Add("cusip", request.Cusip) + .Add("cik", request.Cik) + .Add("date", request.Date) + .Add("search", request.Search) + .Add("active", request.Active) + .Add("order", request.Order) + .Add("sort", request.Sort) + .Add("limit", request.Limit) + .ToString(); while (tickerUrl != null) { @@ -34,9 +42,7 @@ public partial class PolygonClient if (!response.IsSuccessStatusCode) { if (tickerList.Count != 0) - { break; - } return new AllTickersResponse( Count: 0, @@ -49,12 +55,16 @@ public partial class PolygonClient var content = await response.Content.ReadAsStringAsync(cancellationToken); - var scanResponse = JsonSerializer.Deserialize(content); - if (scanResponse != null) - { - tickerList.AddRange(scanResponse.Results); - tickerUrl = scanResponse.Next_Url; - } + var scanResponse = JsonSerializer.Deserialize( + content, + _jsonOptions + ); + + if (scanResponse == null) + break; + + tickerList.AddRange(scanResponse.Results); + tickerUrl = scanResponse.Next_Url; } return new AllTickersResponse( diff --git a/Polygon.Client/PolygonClient.cs b/Polygon.Client/PolygonClient.cs index 2c2af04..f6be431 100644 --- a/Polygon.Client/PolygonClient.cs +++ b/Polygon.Client/PolygonClient.cs @@ -1,6 +1,7 @@ namespace Polygon.Client; using System.Net.Http; +using System.Text.Json; public partial class PolygonClient { @@ -15,11 +16,14 @@ public partial class PolygonClient /// Polygon API key. public PolygonClient(string apiKey) { - _client = new HttpClient - { - BaseAddress = new Uri("https://api.polygon.io"), - }; + _client = new HttpClient { BaseAddress = new Uri("https://api.polygon.io") }; - _client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey); + _client.DefaultRequestHeaders.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey); } + + private readonly JsonSerializerOptions _jsonOptions = new() + { + PropertyNameCaseInsensitive = true, + }; } diff --git a/Polygon.Client/RequestQueryBuilder .cs b/Polygon.Client/RequestQueryBuilder .cs new file mode 100644 index 0000000..c179603 --- /dev/null +++ b/Polygon.Client/RequestQueryBuilder .cs @@ -0,0 +1,48 @@ +namespace Polygon.Client; + +using System.Text; +using System.Web; + +/// +/// +/// +/// Base URL. Default is empty string. +internal class RequestQueryBuilder(string? baseUrl = null) +{ + private readonly StringBuilder _builder = new(); + + public override string ToString() + { + return (baseUrl ?? string.Empty) + _builder.ToString(); + } + + /// + /// Add a string parameter to the query string. + /// + /// Name of parameter. + /// Value of parameter. + /// RequestQueryBuilder. + public RequestQueryBuilder Add(string name, string? value) + { + if (value != null) + { + _builder.Append(_builder.Length == 0 ? '?' : '&'); + _builder.Append(name); + _builder.Append(':'); + _builder.Append(HttpUtility.UrlEncode(value)); + } + + return this; + } + + public RequestQueryBuilder Add(string name, DateOnly? value) + { + //// TODO: Convert date correctly. + return this.Add(name, value?.ToString()); + } + + public RequestQueryBuilder Add(string name, object? value) + { + return this.Add(name, value?.ToString()); + } +}