diff --git a/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs b/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs index 271e83ac..02650c03 100644 --- a/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs +++ b/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs @@ -65,6 +65,9 @@ internal HuobiRestClientSpotApi(ILogger logger, HttpClient? httpClient, HuobiRes } #endregion + /// + public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToLowerInvariant()}{quoteAsset.ToLowerInvariant()}"; + /// protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new HuobiAuthenticationProvider(credentials, ClientOptions.SignPublicRequests); @@ -196,9 +199,12 @@ async Task> IBaseRestClient.GetTickerAsync(string symbol, return tickers.As(null); var ticker = tickers.Data.Ticks.SingleOrDefault(s => s.Symbol == symbol); + if (ticker == null) + return tickers.AsError(new ServerError("Symbol not found")); + return tickers.As(new Ticker { - SourceObject =ticker, + SourceObject = ticker, HighPrice = ticker.HighPrice, Symbol = ticker.Symbol, LastPrice = ticker.ClosePrice, diff --git a/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs b/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs index 61f38ff3..e0053181 100644 --- a/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs +++ b/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs @@ -51,6 +51,9 @@ internal HuobiSocketClientSpotApi(ILogger logger, HuobiSocketOptions options) #endregion + /// + public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToLowerInvariant()}{quoteAsset.ToLowerInvariant()}"; + /// public override string? GetListenerIdentifier(IMessageAccessor message) { @@ -79,10 +82,7 @@ public override ReadOnlyMemory PreprocessStreamMessage(WebSocketMessageTyp if (type != WebSocketMessageType.Binary) return data; - using var decompressedStream = new MemoryStream(); - using var deflateStream = new GZipStream(new MemoryStream(data.ToArray()), CompressionMode.Decompress); - deflateStream.CopyTo(decompressedStream); - return new ReadOnlyMemory(decompressedStream.GetBuffer(), 0, (int)decompressedStream.Length); + return data.DecompressGzip(); } /// diff --git a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs index 62f66623..6fe1d892 100644 --- a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs +++ b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs @@ -62,6 +62,9 @@ internal HuobiClientUsdtMarginSwapApi(ILogger log, HttpClient? httpClient, Huobi } #endregion + /// + public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToUpperInvariant()}-{quoteAsset.ToUpperInvariant()}"; + /// protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new HuobiAuthenticationProvider(credentials, ClientOptions.SignPublicRequests); diff --git a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs index e8139af5..e46d65f4 100644 --- a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs +++ b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs @@ -40,16 +40,16 @@ internal HuobiSocketClientUsdtMarginSwapApi(ILogger logger, HuobiSocketOptions o #endregion + /// + public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToUpperInvariant()}-{quoteAsset.ToUpperInvariant()}"; + /// public override ReadOnlyMemory PreprocessStreamMessage(WebSocketMessageType type, ReadOnlyMemory data) { if (type != WebSocketMessageType.Binary) return data; - using var decompressedStream = new MemoryStream(); - using var deflateStream = new GZipStream(new MemoryStream(data.ToArray()), CompressionMode.Decompress); - deflateStream.CopyTo(decompressedStream); - return new ReadOnlyMemory(decompressedStream.GetBuffer(), 0, (int)decompressedStream.Length); + return data.DecompressGzip(); } /// diff --git a/Huobi.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/Huobi.Net/ExtensionMethods/ServiceCollectionExtensions.cs index b0e3ca06..f00e5e9f 100644 --- a/Huobi.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/Huobi.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -59,7 +59,7 @@ public static IServiceCollection AddHuobi( services.AddTransient(); services.AddTransient(); - services.AddSingleton(); + services.AddTransient(); services.AddTransient(x => x.GetRequiredService().SpotApi.CommonSpotClient); if (socketClientLifeTime == null) services.AddSingleton(); diff --git a/Huobi.Net/Huobi.Net.csproj b/Huobi.Net/Huobi.Net.csproj index edcf7911..779ec0fc 100644 --- a/Huobi.Net/Huobi.Net.csproj +++ b/Huobi.Net/Huobi.Net.csproj @@ -52,6 +52,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file diff --git a/Huobi.Net/Huobi.Net.xml b/Huobi.Net/Huobi.Net.xml index 8aabce46..c291bca3 100644 --- a/Huobi.Net/Huobi.Net.xml +++ b/Huobi.Net/Huobi.Net.xml @@ -101,6 +101,9 @@ + + + @@ -334,6 +337,9 @@ + + + @@ -400,6 +406,9 @@ + + + @@ -470,6 +479,9 @@ + + + @@ -2266,6 +2278,26 @@ + + + Huobi exchange information and configuration + + + + + Exchange name + + + + + Url to the main website + + + + + Urls to the API documentation + + Client for accessing the Huobi API. @@ -4212,6 +4244,11 @@ Huobi order book factory + + + Spot order book factory methods + + Create a SymbolOrderBook for the Spot API @@ -9618,6 +9655,9 @@ + + + ctor diff --git a/Huobi.Net/HuobiExchange.cs b/Huobi.Net/HuobiExchange.cs new file mode 100644 index 00000000..64ee5297 --- /dev/null +++ b/Huobi.Net/HuobiExchange.cs @@ -0,0 +1,25 @@ +namespace Huobi.Net +{ + /// + /// Huobi exchange information and configuration + /// + public static class HuobiExchange + { + /// + /// Exchange name + /// + public static string ExchangeName => "Huobi"; + + /// + /// Url to the main website + /// + public static string Url { get; } = "https://www.huobi.com"; + + /// + /// Urls to the API documentation + /// + public static string[] ApiDocsUrl { get; } = new[] { + "https://huobiapi.github.io/docs/spot/v1/en/#change-log" + }; + } +} diff --git a/Huobi.Net/Interfaces/IHuobiOrderBookFactory.cs b/Huobi.Net/Interfaces/IHuobiOrderBookFactory.cs index fb06f17e..b71e5ca5 100644 --- a/Huobi.Net/Interfaces/IHuobiOrderBookFactory.cs +++ b/Huobi.Net/Interfaces/IHuobiOrderBookFactory.cs @@ -9,6 +9,11 @@ namespace Huobi.Net.Interfaces /// public interface IHuobiOrderBookFactory { + /// + /// Spot order book factory methods + /// + public IOrderBookFactory Spot { get; } + /// /// Create a SymbolOrderBook for the Spot API /// diff --git a/Huobi.Net/SymbolOrderBooks/HuobiOrderBookFactory.cs b/Huobi.Net/SymbolOrderBooks/HuobiOrderBookFactory.cs index 1836ba61..b5390658 100644 --- a/Huobi.Net/SymbolOrderBooks/HuobiOrderBookFactory.cs +++ b/Huobi.Net/SymbolOrderBooks/HuobiOrderBookFactory.cs @@ -1,4 +1,5 @@ using CryptoExchange.Net.Interfaces; +using CryptoExchange.Net.OrderBook; using Huobi.Net.Interfaces; using Huobi.Net.Interfaces.Clients; using Huobi.Net.Objects.Options; @@ -13,6 +14,9 @@ public class HuobiOrderBookFactory : IHuobiOrderBookFactory { private readonly IServiceProvider _serviceProvider; + /// + public IOrderBookFactory Spot { get; } + /// /// ctor /// @@ -20,6 +24,8 @@ public class HuobiOrderBookFactory : IHuobiOrderBookFactory public HuobiOrderBookFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; + + Spot = new OrderBookFactory((symbol, options) => CreateSpot(symbol, options), (baseAsset, quoteAsset, options) => CreateSpot(baseAsset.ToLowerInvariant() + quoteAsset.ToLowerInvariant(), options)); } ///