Skip to content

Commit

Permalink
Trackers (#78)
Browse files Browse the repository at this point in the history
Updated examples
Updated CryptoExchange.Net to v8.1.0
Moved FormatSymbol to CoinExExchange class
Added support Side setting on SharedTrade model
Added CoinExTrackerFactory
Added overload to Create method on CoinExOrderBookFactory support SharedSymbol parameter
  • Loading branch information
JKorf authored Oct 28, 2024
1 parent cf9b754 commit 4c6fb2a
Show file tree
Hide file tree
Showing 24 changed files with 444 additions and 21 deletions.
3 changes: 2 additions & 1 deletion CoinEx.Net/Clients/FuturesApi/CoinExRestClientFuturesApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ internal CoinExRestClientFuturesApi(ILogger logger, HttpClient? httpClient, Coin
#endregion

/// <inheritdoc />
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null)
=> CoinExExchange.FormatSymbol(baseAsset, quoteAsset, tradingMode, deliverTime);

/// <inheritdoc />
protected override IStreamMessageAccessor CreateAccessor() => new SystemTextJsonStreamMessageAccessor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,10 @@ async Task<ExchangeWebResult<IEnumerable<SharedTrade>>> IRecentTradeRestClient.G
if (!result)
return result.AsExchangeResult<IEnumerable<SharedTrade>>(Exchange, null, default);

return result.AsExchangeResult<IEnumerable<SharedTrade>>(Exchange, request.Symbol.TradingMode, result.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)).ToArray());
return result.AsExchangeResult<IEnumerable<SharedTrade>>(Exchange, request.Symbol.TradingMode, result.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)
{
Side = x.Side == OrderSide.Buy ? SharedOrderSide.Buy : SharedOrderSide.Sell
}).ToArray());
}

#endregion
Expand Down
5 changes: 3 additions & 2 deletions CoinEx.Net/Clients/FuturesApi/CoinExSocketClientFuturesApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ protected override AuthenticationProvider CreateAuthenticationProvider(ApiCreden
=> new CoinExV2AuthenticationProvider(credentials);

/// <inheritdoc />
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";

public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null)
=> CoinExExchange.FormatSymbol(baseAsset, quoteAsset, tradingMode, deliverTime);

#region methods

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ async Task<ExchangeResult<UpdateSubscription>> ITradeSocketClient.SubscribeToTra
return new ExchangeResult<UpdateSubscription>(Exchange, validationError);

var symbol = request.Symbol.GetSymbol(FormatSymbol);
var result = await SubscribeToTradeUpdatesAsync(symbol, update => handler(update.AsExchangeEvent(Exchange, update.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)))), ct).ConfigureAwait(false);
var result = await SubscribeToTradeUpdatesAsync(symbol, update => handler(update.AsExchangeEvent(Exchange, update.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)
{
Side = x.Side == OrderSide.Buy ? SharedOrderSide.Buy : SharedOrderSide.Sell
}))), ct).ConfigureAwait(false);

return new ExchangeResult<UpdateSubscription>(Exchange, result);
}
Expand Down
3 changes: 2 additions & 1 deletion CoinEx.Net/Clients/SpotApiV2/CoinExRestClientSpotApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ protected override AuthenticationProvider CreateAuthenticationProvider(ApiCreden
=> new CoinExV2AuthenticationProvider(credentials);

/// <inheritdoc />
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null)
=> CoinExExchange.FormatSymbol(baseAsset, quoteAsset, tradingMode, deliverTime);

#region methods
internal async Task<WebCallResult> ExecuteAsync(Uri uri, HttpMethod method, CancellationToken ct, Dictionary<string, object>? parameters = null, bool signed = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ async Task<ExchangeWebResult<IEnumerable<SharedTrade>>> IRecentTradeRestClient.G
if (!result)
return result.AsExchangeResult<IEnumerable<SharedTrade>>(Exchange, null, default);

return result.AsExchangeResult<IEnumerable<SharedTrade>>(Exchange, request.Symbol.TradingMode, result.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)).ToArray());
return result.AsExchangeResult<IEnumerable<SharedTrade>>(Exchange, request.Symbol.TradingMode, result.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)
{
Side = x.Side == OrderSide.Buy ? SharedOrderSide.Buy : SharedOrderSide.Sell
}).ToArray());
}

#endregion
Expand Down
5 changes: 3 additions & 2 deletions CoinEx.Net/Clients/SpotApiV2/CoinExSocketClientSpotApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ protected override AuthenticationProvider CreateAuthenticationProvider(ApiCreden
public ICoinExSocketClientSpotApiShared SharedClient => this;

/// <inheritdoc />
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";

public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null)
=> CoinExExchange.FormatSymbol(baseAsset, quoteAsset, tradingMode, deliverTime);

#region methods

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ async Task<ExchangeResult<UpdateSubscription>> ITradeSocketClient.SubscribeToTra
if (update.UpdateType == SocketUpdateType.Snapshot)
return;

handler(update.AsExchangeEvent<IEnumerable<SharedTrade>>(Exchange, update.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)).ToArray()));
handler(update.AsExchangeEvent<IEnumerable<SharedTrade>>(Exchange, update.Data.Select(x => new SharedTrade(x.Quantity, x.Price, x.Timestamp)
{
Side = x.Side == OrderSide.Buy ? SharedOrderSide.Buy : SharedOrderSide.Sell
}).ToArray()));
}, ct).ConfigureAwait(false);

return new ExchangeResult<UpdateSubscription>(Exchange, result);
Expand Down
4 changes: 2 additions & 2 deletions CoinEx.Net/CoinEx.Net.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>10.0</LangVersion>
Expand Down Expand Up @@ -48,11 +48,11 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="CryptoExchange.Net" Version="8.1.0" />
<PackageReference Include="Crc32.NET" Version="1.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="CryptoExchange.Net" Version="8.0.3" />
</ItemGroup>
</Project>
52 changes: 52 additions & 0 deletions CoinEx.Net/CoinEx.Net.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion CoinEx.Net/CoinExExchange.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace CoinEx.Net
using CryptoExchange.Net.SharedApis;
using System;

namespace CoinEx.Net
{
/// <summary>
/// CoinEx exchange information and configuration
Expand All @@ -22,5 +25,18 @@ public static class CoinExExchange
"https://viabtc.github.io/coinex_api_en_doc/",
"https://docs.coinex.com/api/v2/"
};

/// <summary>
/// Format a base and quote asset to a CoinEx recognized symbol
/// </summary>
/// <param name="baseAsset">Base asset</param>
/// <param name="quoteAsset">Quote asset</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="deliverTime">Delivery time for delivery futures</param>
/// <returns></returns>
public static string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null)
{
return $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";
}
}
}
63 changes: 63 additions & 0 deletions CoinEx.Net/CoinExTrackerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using CoinEx.Net.Clients;
using CoinEx.Net.Interfaces;
using CoinEx.Net.Interfaces.Clients;
using CryptoExchange.Net.SharedApis;
using CryptoExchange.Net.Trackers.Trades;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;

namespace CoinEx.Net
{
/// <inheritdoc />
public class CoinExTrackerFactory : ICoinExTrackerFactory
{
private readonly IServiceProvider? _serviceProvider;

/// <summary>
/// ctor
/// </summary>
public CoinExTrackerFactory()
{
}

/// <summary>
/// ctor
/// </summary>
/// <param name="serviceProvider">Service provider for resolving logging and clients</param>
public CoinExTrackerFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

/// <inheritdoc />
public ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null, TimeSpan? period = null)
{
var restClient = _serviceProvider?.GetRequiredService<ICoinExRestClient>() ?? new CoinExRestClient();
var socketClient = _serviceProvider?.GetRequiredService<ICoinExSocketClient>() ?? new CoinExSocketClient();

IRecentTradeRestClient sharedRestClient;
ITradeSocketClient sharedSocketClient;
if (symbol.TradingMode == TradingMode.Spot)
{
sharedRestClient = restClient.SpotApiV2.SharedClient;
sharedSocketClient = socketClient.SpotApiV2.SharedClient;
}
else
{
sharedRestClient = restClient.FuturesApi.SharedClient;
sharedSocketClient = socketClient.FuturesApi.SharedClient;
}

return new TradeTracker(
_serviceProvider?.GetRequiredService<ILoggerFactory>().CreateLogger(restClient.Exchange),
sharedRestClient,
null,
sharedSocketClient,
symbol,
limit,
period
);
}
}
}
4 changes: 3 additions & 1 deletion CoinEx.Net/ExtensionMethods/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CoinEx.Net.Clients;
using CoinEx.Net;
using CoinEx.Net.Clients;
using CoinEx.Net.Interfaces;
using CoinEx.Net.Interfaces.Clients;
using CoinEx.Net.Objects.Options;
Expand Down Expand Up @@ -61,6 +62,7 @@ public static IServiceCollection AddCoinEx(
services.AddTransient<ICryptoRestClient, CryptoRestClient>();
services.AddTransient<ICryptoSocketClient, CryptoSocketClient>();
services.AddTransient<ICoinExOrderBookFactory, CoinExOrderBookFactory>();
services.AddTransient<ICoinExTrackerFactory, CoinExTrackerFactory>();
services.AddTransient(x => x.GetRequiredService<ICoinExRestClient>().SpotApiV2.CommonSpotClient);

services.RegisterSharedRestInterfaces(x => x.GetRequiredService<ICoinExRestClient>().SpotApiV2.SharedClient);
Expand Down
9 changes: 9 additions & 0 deletions CoinEx.Net/Interfaces/ICoinExOrderBookFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CoinEx.Net.Objects.Options;
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.SharedApis;
using System;

namespace CoinEx.Net.Interfaces
Expand All @@ -19,6 +20,14 @@ public interface ICoinExOrderBookFactory
/// </summary>
public IOrderBookFactory<CoinExOrderBookOptions> Futures { get; }

/// <summary>
/// Create a SymbolOrderBook for the symbol
/// </summary>
/// <param name="symbol">The symbol</param>
/// <param name="options">Book options</param>
/// <returns></returns>
ISymbolOrderBook Create(SharedSymbol symbol, Action<CoinExOrderBookOptions>? options = null);

/// <summary>
/// Create a SymbolOrderBook for the Spot API
/// </summary>
Expand Down
24 changes: 24 additions & 0 deletions CoinEx.Net/Interfaces/ICoinExTrackerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using CryptoExchange.Net.SharedApis;
using CryptoExchange.Net.Trackers.Klines;
using CryptoExchange.Net.Trackers.Trades;
using System;
using System.Collections.Generic;
using System.Text;

namespace CoinEx.Net.Interfaces
{
/// <summary>
/// Tracker factory
/// </summary>
public interface ICoinExTrackerFactory
{
/// <summary>
/// Create a new trade tracker for a symbol
/// </summary>
/// <param name="symbol">The symbol</param>
/// <param name="limit">The max amount of klines to retain</param>
/// <param name="period">The max period the data should be retained</param>
/// <returns></returns>
ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null, TimeSpan? period = null);
}
}
19 changes: 17 additions & 2 deletions CoinEx.Net/SymbolOrderBooks/CoinExOrderBookFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using CoinEx.Net.Objects.Options;
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.OrderBook;
using CryptoExchange.Net.SharedApis;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
Expand All @@ -28,8 +29,22 @@ public CoinExOrderBookFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;

Spot = new OrderBookFactory<CoinExOrderBookOptions>((symbol, options) => CreateSpot(symbol, options), (baseAsset, quoteAsset, options) => CreateSpot(baseAsset + quoteAsset, options));
Futures = new OrderBookFactory<CoinExOrderBookOptions>((symbol, options) => CreateFutures(symbol, options), (baseAsset, quoteAsset, options) => CreateFutures(baseAsset + quoteAsset, options));
Spot = new OrderBookFactory<CoinExOrderBookOptions>(
CreateSpot,
(sharedSymbol, options) => CreateSpot(CoinExExchange.FormatSymbol(sharedSymbol.BaseAsset, sharedSymbol.QuoteAsset, sharedSymbol.TradingMode, sharedSymbol.DeliverTime), options));
Futures = new OrderBookFactory<CoinExOrderBookOptions>(
CreateFutures,
(sharedSymbol, options) => CreateFutures(CoinExExchange.FormatSymbol(sharedSymbol.BaseAsset, sharedSymbol.QuoteAsset, sharedSymbol.TradingMode, sharedSymbol.DeliverTime), options));
}

/// <inheritdoc />
public ISymbolOrderBook Create(SharedSymbol symbol, Action<CoinExOrderBookOptions>? options = null)
{
var symbolName = CoinExExchange.FormatSymbol(symbol.BaseAsset, symbol.QuoteAsset, symbol.TradingMode, symbol.DeliverTime);
if (symbol.TradingMode == TradingMode.Spot)
return CreateSpot(symbolName, options);

return CreateFutures(symbolName, options);
}

/// <inheritdoc />
Expand Down
Loading

0 comments on commit 4c6fb2a

Please sign in to comment.