mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-13 17:33:02 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 613766dbca | |||
| 23b07d709e | |||
| bbbdac2fd3 | |||
| c614b7869c | |||
| 1f31e4a9d7 | |||
| 6cb6cd6b11 | |||
| 17ffec329f | |||
| 7a3927ef49 | |||
| c1b0437c93 |
@@ -11,7 +11,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorClient", "Examples\Bl
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{5734C2A9-F12C-4754-A8B9-640C24DC4E02}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleClient", "Examples\ConsoleClient\ConsoleClient.csproj", "{23480C58-23BF-4EBF-A173-B7F51A043A99}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleClient", "Examples\ConsoleClient\ConsoleClient.csproj", "{23480C58-23BF-4EBF-A173-B7F51A043A99}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedClients", "Examples\SharedClients\SharedClients.csproj", "{988A87EF-EAEA-4313-A6CF-FA869813D5AB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -35,6 +37,10 @@ Global
|
||||
{23480C58-23BF-4EBF-A173-B7F51A043A99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23480C58-23BF-4EBF-A173-B7F51A043A99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23480C58-23BF-4EBF-A173-B7F51A043A99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{988A87EF-EAEA-4313-A6CF-FA869813D5AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{988A87EF-EAEA-4313-A6CF-FA869813D5AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{988A87EF-EAEA-4313-A6CF-FA869813D5AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{988A87EF-EAEA-4313-A6CF-FA869813D5AB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -42,6 +48,7 @@ Global
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{AF4F5C19-162E-48F4-8B0B-BA5A2D7CE06A} = {5734C2A9-F12C-4754-A8B9-640C24DC4E02}
|
||||
{23480C58-23BF-4EBF-A173-B7F51A043A99} = {5734C2A9-F12C-4754-A8B9-640C24DC4E02}
|
||||
{988A87EF-EAEA-4313-A6CF-FA869813D5AB} = {5734C2A9-F12C-4754-A8B9-640C24DC4E02}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0D1B9CE9-E0B7-4B8B-88BF-6EA2CC8CA3D7}
|
||||
|
||||
@@ -11,12 +11,12 @@ namespace CryptoExchange.Net.Authentication
|
||||
public class ApiCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// The api key to authenticate requests
|
||||
/// The api key / label to authenticate requests
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The api secret to authenticate requests
|
||||
/// The api secret or private key to authenticate requests
|
||||
/// </summary>
|
||||
public string Secret { get; }
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// <summary>
|
||||
/// Create Api credentials providing an api key and secret for authentication
|
||||
/// </summary>
|
||||
/// <param name="key">The api key used for identification</param>
|
||||
/// <param name="secret">The api secret used for signing</param>
|
||||
/// <param name="key">The api key / label used for identification</param>
|
||||
/// <param name="secret">The api secret or private key used for signing</param>
|
||||
public ApiCredentials(string key, string secret) : this(key, secret, ApiCredentialsType.Hmac)
|
||||
{
|
||||
}
|
||||
@@ -37,8 +37,8 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// <summary>
|
||||
/// Create Api credentials providing an api key and secret for authentication
|
||||
/// </summary>
|
||||
/// <param name="key">The api key used for identification</param>
|
||||
/// <param name="secret">The api secret used for signing</param>
|
||||
/// <param name="key">The api key / label used for identification</param>
|
||||
/// <param name="secret">The api secret or private key used for signing</param>
|
||||
/// <param name="credentialsType">The type of credentials</param>
|
||||
public ApiCredentials(string key, string secret, ApiCredentialsType credentialsType)
|
||||
{
|
||||
|
||||
@@ -12,6 +12,28 @@ namespace CryptoExchange.Net.Clients
|
||||
/// </summary>
|
||||
public abstract class BaseClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Version of the CryptoExchange.Net base library
|
||||
/// </summary>
|
||||
public Version CryptoExchangeLibVersion { get; } = typeof(BaseClient).Assembly.GetName().Version;
|
||||
|
||||
/// <summary>
|
||||
/// Version of the client implementation
|
||||
/// </summary>
|
||||
public Version ExchangeLibVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
lock(_versionLock)
|
||||
{
|
||||
if (_exchangeVersion == null)
|
||||
_exchangeVersion = GetType().Assembly.GetName().Version;
|
||||
|
||||
return _exchangeVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the API the client is for
|
||||
/// </summary>
|
||||
@@ -27,6 +49,9 @@ namespace CryptoExchange.Net.Clients
|
||||
/// </summary>
|
||||
protected internal ILogger _logger;
|
||||
|
||||
private object _versionLock = new object();
|
||||
private Version _exchangeVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Provided client options
|
||||
/// </summary>
|
||||
@@ -57,7 +82,7 @@ namespace CryptoExchange.Net.Clients
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
|
||||
ClientOptions = options;
|
||||
_logger.Log(LogLevel.Trace, $"Client configuration: {options}, CryptoExchange.Net: v{typeof(BaseClient).Assembly.GetName().Version}, {Exchange}.Net: v{GetType().Assembly.GetName().Version}");
|
||||
_logger.Log(LogLevel.Trace, $"Client configuration: {options}, CryptoExchange.Net: v{CryptoExchangeLibVersion}, {Exchange}.Net: v{ExchangeLibVersion}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
||||
var stringValue = reader.GetString();
|
||||
if (string.IsNullOrWhiteSpace(stringValue)
|
||||
|| stringValue == "-1"
|
||||
|| stringValue == "0001-01-01T00:00:00Z"
|
||||
|| double.TryParse(stringValue, out var doubleVal) && doubleVal == 0)
|
||||
{
|
||||
return default;
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
<PackageId>CryptoExchange.Net</PackageId>
|
||||
<Authors>JKorf</Authors>
|
||||
<Description>CryptoExchange.Net is a base library which is used to implement different cryptocurrency (exchange) API's. It provides a standardized way of implementing different API's, which results in a very similar experience for users of the API implementations.</Description>
|
||||
<PackageVersion>8.0.0</PackageVersion>
|
||||
<AssemblyVersion>8.0.0</AssemblyVersion>
|
||||
<FileVersion>8.0.0</FileVersion>
|
||||
<PackageVersion>8.0.1</PackageVersion>
|
||||
<AssemblyVersion>8.0.1</AssemblyVersion>
|
||||
<FileVersion>8.0.1</FileVersion>
|
||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||
<PackageTags>OKX;OKX.Net;Mexc;Mexc.Net;Kucoin;Kucoin.Net;Kraken;Kraken.Net;Huobi;Huobi.Net;CoinEx;CoinEx.Net;Bybit;Bybit.Net;Bitget;Bitget.Net;Bitfinex;Bitfinex.Net;Binance;Binance.Net;CryptoCurrency;CryptoCurrency Exchange</PackageTags>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
|
||||
@@ -189,6 +189,16 @@ namespace CryptoExchange.Net
|
||||
throw new ArgumentException($"No values provided for parameter {argumentName}", argumentName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format a string to RFC3339/ISO8601 string
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToRfc3339String(this DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format an exception and inner exception to a readable string
|
||||
/// </summary>
|
||||
|
||||
@@ -506,8 +506,11 @@ namespace CryptoExchange.Net.Sockets
|
||||
}
|
||||
|
||||
if (processor is Subscription subscriptionProcessor && !subscriptionProcessor.Confirmed)
|
||||
{
|
||||
// If this message is for this listener then it is automatically confirmed, even if the subscription is not (yet) confirmed
|
||||
subscriptionProcessor.Confirmed = true;
|
||||
// This doesn't trigger a waiting subscribe query, should probably also somehow set the wait event for that
|
||||
}
|
||||
|
||||
// 6. Deserialize the message
|
||||
object? deserialized = null;
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
||||
{
|
||||
if (propertyValue == default && propValue.Type != JTokenType.Null && !string.IsNullOrEmpty(propValue.ToString()))
|
||||
{
|
||||
if (propertyType == typeof(DateTime?) && (propValue.ToString() == "" || propValue.ToString() == "0" || propValue.ToString() == "-1"))
|
||||
if (propertyType == typeof(DateTime?) && (propValue.ToString() == "" || propValue.ToString() == "0" || propValue.ToString() == "-1" || propValue.ToString() == "01/01/0001 00:00:00"))
|
||||
return;
|
||||
|
||||
// Property value not correct
|
||||
|
||||
@@ -5,17 +5,20 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Binance.Net" Version="9.7.1" />
|
||||
<PackageReference Include="Bitfinex.Net" Version="7.2.2" />
|
||||
<PackageReference Include="Bybit.Net" Version="3.7.1" />
|
||||
<PackageReference Include="CoinEx.Net" Version="6.2.1" />
|
||||
<PackageReference Include="Huobi.Net" Version="5.2.1" />
|
||||
<PackageReference Include="JK.BingX.Net" Version="1.0.0" />
|
||||
<PackageReference Include="JK.Bitget.Net" Version="1.3.1" />
|
||||
<PackageReference Include="JK.OKX.Net" Version="1.7.1" />
|
||||
<PackageReference Include="KrakenExchange.Net" Version="4.4.3" />
|
||||
<PackageReference Include="Kucoin.Net" Version="5.3.2" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="6.0.0" />
|
||||
<PackageReference Include="Binance.Net" Version="10.5.0" />
|
||||
<PackageReference Include="Bitfinex.Net" Version="7.8.0" />
|
||||
<PackageReference Include="BitMart.Net" Version="1.2.0" />
|
||||
<PackageReference Include="Bybit.Net" Version="3.14.0" />
|
||||
<PackageReference Include="CoinEx.Net" Version="7.7.0" />
|
||||
<PackageReference Include="GateIo.Net" Version="1.6.0" />
|
||||
<PackageReference Include="JK.BingX.Net" Version="1.11.0" />
|
||||
<PackageReference Include="JK.Bitget.Net" Version="1.10.0" />
|
||||
<PackageReference Include="JK.Mexc.Net" Version="1.8.0" />
|
||||
<PackageReference Include="JK.OKX.Net" Version="2.4.0" />
|
||||
<PackageReference Include="JKorf.HTX.Net" Version="6.1.0" />
|
||||
<PackageReference Include="KrakenExchange.Net" Version="4.12.0" />
|
||||
<PackageReference Include="Kucoin.Net" Version="5.14.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
@inject IBinanceRestClient binanceClient
|
||||
@inject IBingXRestClient bingXClient
|
||||
@inject IBitfinexRestClient bitfinexClient
|
||||
@inject IBitMartRestClient bitmartClient
|
||||
@inject IBitgetRestClient bitgetClient
|
||||
@inject IBybitRestClient bybitClient
|
||||
@inject ICoinExRestClient coinexClient
|
||||
@inject IHuobiRestClient huobiClient
|
||||
@inject IGateIoRestClient gateioClient
|
||||
@inject IHTXRestClient huobiClient
|
||||
@inject IKrakenRestClient krakenClient
|
||||
@inject IKucoinRestClient kucoinClient
|
||||
@inject IMexcRestClient mexcClient
|
||||
@inject IOKXRestClient okxClient
|
||||
|
||||
<h3>BTC-USD prices:</h3>
|
||||
@@ -25,14 +28,17 @@
|
||||
var bingXTask = bingXClient.SpotApi.ExchangeData.GetTickersAsync("BTC-USDT");
|
||||
var bitfinexTask = bitfinexClient.SpotApi.ExchangeData.GetTickerAsync("tBTCUSD");
|
||||
var bitgetTask = bitgetClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT_SPBL");
|
||||
var bitmartTask = bitmartClient.SpotApi.ExchangeData.GetTickerAsync("BTC_USDT");
|
||||
var bybitTask = bybitClient.V5Api.ExchangeData.GetSpotTickersAsync("BTCUSDT");
|
||||
var coinexTask = coinexClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT");
|
||||
var huobiTask = huobiClient.SpotApi.ExchangeData.GetTickerAsync("btcusdt");
|
||||
var gateioTask = gateioClient.SpotApi.ExchangeData.GetTickersAsync("BTC_USDT");
|
||||
var htxTask = huobiClient.SpotApi.ExchangeData.GetTickerAsync("btcusdt");
|
||||
var krakenTask = krakenClient.SpotApi.ExchangeData.GetTickerAsync("XBTUSD");
|
||||
var kucoinTask = kucoinClient.SpotApi.ExchangeData.GetTickerAsync("BTC-USDT");
|
||||
var mexcTask = mexcClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT");
|
||||
var okxTask = okxClient.UnifiedApi.ExchangeData.GetTickerAsync("BTCUSDT");
|
||||
|
||||
await Task.WhenAll(binanceTask, bingXTask, bitfinexTask, bybitTask, coinexTask, huobiTask, krakenTask, kucoinTask);
|
||||
await Task.WhenAll(binanceTask, bingXTask, bitfinexTask, bitgetTask, bitmartTask, bybitTask, coinexTask, gateioTask, htxTask, krakenTask, kucoinTask, mexcTask, okxTask);
|
||||
|
||||
if (binanceTask.Result.Success)
|
||||
_prices.Add("Binance", binanceTask.Result.Data.LastPrice);
|
||||
@@ -46,14 +52,20 @@
|
||||
if (bitgetTask.Result.Success)
|
||||
_prices.Add("Bitget", bitgetTask.Result.Data.ClosePrice);
|
||||
|
||||
if (bitmartTask.Result.Success)
|
||||
_prices.Add("BitMart", bitgetTask.Result.Data.ClosePrice);
|
||||
|
||||
if (bybitTask.Result.Success)
|
||||
_prices.Add("Bybit", bybitTask.Result.Data.List.First().LastPrice);
|
||||
|
||||
if (coinexTask.Result.Success)
|
||||
_prices.Add("CoinEx", coinexTask.Result.Data.Ticker.LastPrice);
|
||||
|
||||
if (huobiTask.Result.Success)
|
||||
_prices.Add("Huobi", huobiTask.Result.Data.ClosePrice ?? 0);
|
||||
if (gateioTask.Result.Success)
|
||||
_prices.Add("GateIo", gateioTask.Result.Data.First().LastPrice);
|
||||
|
||||
if (htxTask.Result.Success)
|
||||
_prices.Add("HTX", htxTask.Result.Data.ClosePrice ?? 0);
|
||||
|
||||
if (krakenTask.Result.Success)
|
||||
_prices.Add("Kraken", krakenTask.Result.Data.First().Value.LastTrade.Price);
|
||||
@@ -61,6 +73,9 @@
|
||||
if (kucoinTask.Result.Success)
|
||||
_prices.Add("Kucoin", kucoinTask.Result.Data.LastPrice ?? 0);
|
||||
|
||||
if (mexcTask.Result.Success)
|
||||
_prices.Add("Mexc", mexcTask.Result.Data.LastPrice);
|
||||
|
||||
if (okxTask.Result.Success)
|
||||
_prices.Add("OKX", okxTask.Result.Data.LastPrice ?? 0);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
@inject IBingXSocketClient bingXSocketClient
|
||||
@inject IBitfinexSocketClient bitfinexSocketClient
|
||||
@inject IBitgetSocketClient bitgetSocketClient
|
||||
@inject IBitMartSocketClient bitmartSocketClient
|
||||
@inject IBybitSocketClient bybitSocketClient
|
||||
@inject ICoinExSocketClient coinExSocketClient
|
||||
@inject IHuobiSocketClient huobiSocketClient
|
||||
@inject IGateIoSocketClient gateioSocketClient
|
||||
@inject IHTXSocketClient htxSocketClient
|
||||
@inject IKrakenSocketClient krakenSocketClient
|
||||
@inject IKucoinSocketClient kucoinSocketClient
|
||||
@inject IMexcSocketClient mexcSocketClient
|
||||
@inject IOKXSocketClient okxSocketClient
|
||||
@using System.Collections.Concurrent
|
||||
@using CryptoExchange.Net.Objects
|
||||
@@ -33,11 +36,14 @@
|
||||
bingXSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETH-BTC", data => UpdateData("BingX", data.Data.LastPrice)),
|
||||
bitfinexSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("tETHBTC", data => UpdateData("Bitfinex", data.Data.LastPrice)),
|
||||
bitgetSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETHBTC", data => UpdateData("Bitget", data.Data.LastPrice)),
|
||||
bitmartSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETH_BTC", data => UpdateData("BitMart", data.Data.LastPrice)),
|
||||
bybitSocketClient.V5SpotApi.SubscribeToTickerUpdatesAsync("ETHBTC", data => UpdateData("Bybit", data.Data.LastPrice)),
|
||||
coinExSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETHBTC", data => UpdateData("CoinEx", data.Data.LastPrice)),
|
||||
huobiSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ethbtc", data => UpdateData("Huobi", data.Data.ClosePrice ?? 0)),
|
||||
gateioSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETH_BTC", data => UpdateData("GateIo", data.Data.LastPrice)),
|
||||
htxSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ethbtc", data => UpdateData("HTX", data.Data.ClosePrice ?? 0)),
|
||||
krakenSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETH/XBT", data => UpdateData("Kraken", data.Data.LastTrade.Price)),
|
||||
kucoinSocketClient.SpotApi.SubscribeToTickerUpdatesAsync("ETH-BTC", data => UpdateData("Kucoin", data.Data.LastPrice ?? 0)),
|
||||
mexcSocketClient.SpotApi.SubscribeToMiniTickerUpdatesAsync("ETHBTC", data => UpdateData("Mexc", data.Data.LastPrice)),
|
||||
okxSocketClient.UnifiedApi.ExchangeData.SubscribeToTickerUpdatesAsync("ETH-BTC", data => UpdateData("OKX", data.Data.LastPrice ?? 0)),
|
||||
};
|
||||
|
||||
|
||||
@@ -5,23 +5,29 @@
|
||||
@using BingX.Net.Interfaces
|
||||
@using Bitfinex.Net.Interfaces
|
||||
@using Bitget.Net.Interfaces;
|
||||
@using BitMart.Net.Interfaces;
|
||||
@using Bybit.Net.Interfaces
|
||||
@using CoinEx.Net.Interfaces
|
||||
@using CryptoExchange.Net.Interfaces
|
||||
@using Huobi.Net.Interfaces
|
||||
@using GateIo.Net.Interfaces
|
||||
@using HTX.Net.Interfaces
|
||||
@using Kraken.Net.Interfaces
|
||||
@using Kucoin.Net.Clients
|
||||
@using Kucoin.Net.Interfaces
|
||||
@using Mexc.Net.Interfaces
|
||||
@using OKX.Net.Interfaces;
|
||||
@inject IBinanceOrderBookFactory binanceFactory
|
||||
@inject IBingXOrderBookFactory bingXFactory
|
||||
@inject IBitfinexOrderBookFactory bitfinexFactory
|
||||
@inject IBitgetOrderBookFactory bitgetFactory
|
||||
@inject IBitMartOrderBookFactory bitmartFactory
|
||||
@inject IBybitOrderBookFactory bybitFactory
|
||||
@inject ICoinExOrderBookFactory coinExFactory
|
||||
@inject IHuobiOrderBookFactory huobiFactory
|
||||
@inject IGateIoOrderBookFactory gateioFactory
|
||||
@inject IHTXOrderBookFactory htxFactory
|
||||
@inject IKrakenOrderBookFactory krakenFactory
|
||||
@inject IKucoinOrderBookFactory kucoinFactory
|
||||
@inject IMexcOrderBookFactory mexcFactory
|
||||
@inject IOKXOrderBookFactory okxFactory
|
||||
@implements IDisposable
|
||||
|
||||
@@ -60,11 +66,14 @@
|
||||
{ "BingX", bingXFactory.CreateSpot("ETH-BTC") },
|
||||
{ "Bitfinex", bitfinexFactory.Create("tETHBTC") },
|
||||
{ "Bitget", bitgetFactory.CreateSpot("ETHBTC") },
|
||||
{ "BitMart", bitmartFactory.CreateSpot("ETH_BTC", null) },
|
||||
{ "Bybit", bybitFactory.Create("ETHBTC", Bybit.Net.Enums.Category.Spot) },
|
||||
{ "CoinEx", coinExFactory.CreateSpot("ETHBTC") },
|
||||
{ "Huobi", huobiFactory.CreateSpot("ethbtc") },
|
||||
{ "GateIo", gateioFactory.CreateSpot("ETH_BTC") },
|
||||
{ "HTX", htxFactory.CreateSpot("ethbtc") },
|
||||
{ "Kraken", krakenFactory.CreateSpot("ETH/XBT") },
|
||||
{ "Kucoin", kucoinFactory.CreateSpot("ETH-BTC") },
|
||||
{ "Mexc", mexcFactory.CreateSpot("ETHBTC") },
|
||||
{ "OKX", okxFactory.Create("ETH-BTC") },
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@page "/SpotClient"
|
||||
@inject ICryptoRestClient restClient
|
||||
@using CryptoExchange.Net.SharedApis
|
||||
@inject IEnumerable<ISpotTickerRestClient> restClients
|
||||
|
||||
<h3>ETH-BTC prices:</h3>
|
||||
@foreach(var price in _prices.OrderBy(p => p.Key))
|
||||
@@ -12,13 +13,13 @@
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var clients = restClient.GetSpotClients();
|
||||
var tasks = clients.Select(c => (c.ExchangeName, c.GetTickerAsync(c.GetSymbolName("ETH", "BTC"))));
|
||||
await Task.WhenAll(tasks.Select(t => t.Item2));
|
||||
foreach(var task in tasks)
|
||||
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "BTC");
|
||||
var tasks = restClients.Select(x => x.GetSpotTickerAsync(new GetTickerRequest(symbol)));
|
||||
await Task.WhenAll(tasks);
|
||||
foreach (var ticker in tasks.Select(x => x.Result))
|
||||
{
|
||||
if(task.Item2.Result.Success)
|
||||
_prices.Add(task.Item1, task.Item2.Result.Data.HighPrice);
|
||||
if (ticker.Success)
|
||||
_prices.Add(ticker.Exchange, ticker.Data.LastPrice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,14 @@ namespace BlazorClient
|
||||
services.AddBingX();
|
||||
services.AddBitfinex();
|
||||
services.AddBitget();
|
||||
services.AddBitMart();
|
||||
services.AddBybit();
|
||||
services.AddCoinEx();
|
||||
services.AddHuobi();
|
||||
services.AddGateIo();
|
||||
services.AddHTX();
|
||||
services.AddKraken();
|
||||
services.AddKucoin();
|
||||
services.AddMexc();
|
||||
services.AddOKX();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,13 @@
|
||||
@using BingX.Net.Interfaces.Clients;
|
||||
@using Bitfinex.Net.Interfaces.Clients;
|
||||
@using Bitget.Net.Interfaces.Clients;
|
||||
@using BitMart.Net.Interfaces.Clients;
|
||||
@using Bybit.Net.Interfaces.Clients;
|
||||
@using CoinEx.Net.Interfaces.Clients;
|
||||
@using Huobi.Net.Interfaces.Clients;
|
||||
@using GateIo.Net.Interfaces.Clients;
|
||||
@using HTX.Net.Interfaces.Clients;
|
||||
@using Kraken.Net.Interfaces.Clients;
|
||||
@using Kucoin.Net.Interfaces.Clients;
|
||||
@using Mexc.Net.Interfaces.Clients;
|
||||
@using OKX.Net.Interfaces.Clients;
|
||||
@using CryptoExchange.Net.Interfaces;
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
@@ -6,16 +6,18 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Binance.Net" Version="9.5.0" />
|
||||
<PackageReference Include="Bitfinex.Net" Version="7.1.0" />
|
||||
<PackageReference Include="Bittrex.Net" Version="8.0.3" />
|
||||
<PackageReference Include="Bybit.Net" Version="3.4.0" />
|
||||
<PackageReference Include="CoinEx.Net" Version="6.1.0" />
|
||||
<PackageReference Include="Huobi.Net" Version="5.1.0" />
|
||||
<PackageReference Include="JK.Bitget.Net" Version="1.1.0" />
|
||||
<PackageReference Include="JK.OKX.Net" Version="1.6.0" />
|
||||
<PackageReference Include="KrakenExchange.Net" Version="4.3.0" />
|
||||
<PackageReference Include="Kucoin.Net" Version="5.2.0" />
|
||||
<PackageReference Include="Binance.Net" Version="10.5.0" />
|
||||
<PackageReference Include="Bitfinex.Net" Version="7.8.0" />
|
||||
<PackageReference Include="BitMart.Net" Version="1.2.0" />
|
||||
<PackageReference Include="Bybit.Net" Version="3.14.0" />
|
||||
<PackageReference Include="CoinEx.Net" Version="7.7.0" />
|
||||
<PackageReference Include="GateIo.Net" Version="1.6.0" />
|
||||
<PackageReference Include="JK.Bitget.Net" Version="1.10.0" />
|
||||
<PackageReference Include="JK.Mexc.Net" Version="1.8.0" />
|
||||
<PackageReference Include="JK.OKX.Net" Version="2.4.0" />
|
||||
<PackageReference Include="JKorf.HTX.Net" Version="6.1.0" />
|
||||
<PackageReference Include="KrakenExchange.Net" Version="4.12.0" />
|
||||
<PackageReference Include="Kucoin.Net" Version="5.14.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -4,12 +4,10 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Binance.Net.Clients;
|
||||
using Binance.Net.Objects;
|
||||
using Bybit.Net.Clients;
|
||||
using ConsoleClient.Exchanges;
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using CryptoExchange.Net.Objects.Sockets;
|
||||
using CryptoExchange.Net.Sockets;
|
||||
|
||||
namespace ConsoleClient
|
||||
{
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using Binance.Net.Clients;
|
||||
using BitMart.Net.Clients;
|
||||
using CryptoExchange.Net.SharedApis;
|
||||
using OKX.Net.Clients;
|
||||
|
||||
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
|
||||
var binanceSpotRestClient = new BinanceRestClient().SpotApi.SharedClient;
|
||||
var okxSpotRestClient = new OKXRestClient().UnifiedApi.SharedClient;
|
||||
var bitmartSpotRestClient = new BitMartRestClient().SpotApi.SharedClient;
|
||||
|
||||
var binanceSpotSocketClient = new BinanceSocketClient().SpotApi.SharedClient;
|
||||
var okxSpotSocketClient = new OKXSocketClient().UnifiedApi.SharedClient;
|
||||
var bitmartSpotSocketClient = new BitMartSocketClient().SpotApi.SharedClient;
|
||||
|
||||
await GetLastTradePriceAsync(binanceSpotRestClient, symbol);
|
||||
await GetLastTradePriceAsync(okxSpotRestClient, symbol);
|
||||
await GetLastTradePriceAsync(bitmartSpotRestClient, symbol);
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Press enter to start websocket");
|
||||
Console.ReadLine();
|
||||
|
||||
await SubscribeTickerUpdatesAsync(binanceSpotSocketClient, symbol);
|
||||
await SubscribeTickerUpdatesAsync(okxSpotSocketClient, symbol);
|
||||
await SubscribeTickerUpdatesAsync(bitmartSpotSocketClient, symbol);
|
||||
|
||||
Console.ReadLine();
|
||||
|
||||
async Task GetLastTradePriceAsync(ISpotTickerRestClient client, SharedSymbol symbol)
|
||||
{
|
||||
var result = await client.GetSpotTickerAsync(new GetTickerRequest(symbol));
|
||||
if (!result.Success)
|
||||
{
|
||||
Console.WriteLine($"Failed to get ticker: {result.Error}");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{client.Exchange} {result.Data.Symbol}: {result.Data.LastPrice}");
|
||||
}
|
||||
|
||||
async Task SubscribeTickerUpdatesAsync(ITickerSocketClient client, SharedSymbol symbol)
|
||||
{
|
||||
var result = await client.SubscribeToTickerUpdatesAsync(new SubscribeTickerRequest(symbol), update =>
|
||||
{
|
||||
Console.WriteLine($"{client.Exchange} {update.Data.Symbol} {update.Data.LastPrice}");
|
||||
});
|
||||
|
||||
if (!result.Success)
|
||||
Console.WriteLine($"Failed to subscribe ticker: {result.Error}");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Binance.Net" Version="10.5.0" />
|
||||
<PackageReference Include="BitMart.Net" Version="1.2.0" />
|
||||
<PackageReference Include="JK.OKX.Net" Version="2.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -47,6 +47,11 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d
|
||||
Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf).
|
||||
|
||||
## Release notes
|
||||
* Version 8.0.1 - 07 Oct 2024
|
||||
* Added cached library version properties on base client
|
||||
* Added support for derserializing 0001-01-01 as datetime null value
|
||||
* Added ToRfc3339String extension method for DateTime type
|
||||
|
||||
* Version 8.0.0 - 27 Sep 2024
|
||||
* Added new cross exchange interfaces implementation
|
||||
* Supports REST, WebSocket, Spot and Futures API's
|
||||
|
||||
@@ -1859,7 +1859,26 @@ while (true)
|
||||
|
||||
<pre><code>await foreach (var pageResult in ExchangeHelpers.ExecutePages(client.GetClosedFuturesOrdersAsync, new GetClosedOrdersRequest(symbol, limit: 2)))
|
||||
Console.WriteLine($"{pageResult.Data.Count()} items");</code></pre>
|
||||
|
||||
<h4 id="shared_parameters">Optional and exchange specific parameters</h4>
|
||||
<p>Not all exchanges require the same parameters. Some parameters are defined on the request model, but only required for specific exchanges. For example a <code>listenKey</code> parameter when subscribing to a user stream. When not provided for an exchange that needs it an <code>ArgumentError</code> will be returned.</p>
|
||||
|
||||
<p>Other parameters are not defined on the request model at all because they're very specific to a single exchange. For example the <code>AccountId</code> parameter for Spot authenticated requests on HTX. To not pollute the request models with every single possible parameter for each single exchange there is an <code>ExchangeParameters</code> structure to provide these values.</p>
|
||||
|
||||
<pre><code>// Set as static parameter, automatically used if not overridden
|
||||
ExchangeParameters.SetStaticParameter("HTX", "AccountId", 123123123);
|
||||
var balances1 = await restClient.HTX.SpotApi.SharedClient.GetBalancesAsync(new GetBalancesRequest());
|
||||
|
||||
// Specify exchange parameters for a request
|
||||
var exchangeParameters = new ExchangeParameters(new ExchangeParameter("HTX", "AccountId", 456456456));
|
||||
var balances = await restClient.HTX.SpotApi.SharedClient.GetBalancesAsync(new GetBalancesRequest(exchangeParameters: exchangeParameters));</code></pre>
|
||||
|
||||
<p>To determine which parameters are required for an exchange request either inspect the ArgmumentError when the call fails, or output the request info:</p>
|
||||
<pre><code>Console.WriteLine(restClient.HTX.SpotApi.SharedClient.GetBalancesOptions.ToString(Exchange.HTX));
|
||||
// Output:
|
||||
// HTX GetBalancesRequest
|
||||
// Needs authentication: True
|
||||
// Required exchange specific parameters: [Int64] AccountId: Account id of the user | example: 123123123</code></pre>
|
||||
<h4 id="shared_interfaces">Available Interfaces</h4>
|
||||
|
||||
<p>Available REST shared interfaces</p>
|
||||
|
||||
Reference in New Issue
Block a user