1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-07-23 09:55:48 +00:00

Added name to clients, added common interfaces

This commit is contained in:
Jkorf 2020-12-10 14:05:34 +01:00
parent 3b6463015a
commit df9d09630a
21 changed files with 679 additions and 18 deletions

View File

@ -9,11 +9,11 @@ namespace CryptoExchange.Net.UnitTests
{
public class TestBaseClient: BaseClient
{
public TestBaseClient(): base(new RestClientOptions("http://testurl.url"), null)
public TestBaseClient(): base("Test", new RestClientOptions("http://testurl.url"), null)
{
}
public TestBaseClient(RestClientOptions exchangeOptions) : base(exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
public TestBaseClient(RestClientOptions exchangeOptions) : base("Test", exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
{
}

View File

@ -16,12 +16,12 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
{
public class TestRestClient: RestClient
{
public TestRestClient() : base(new RestClientOptions("http://testurl.url"), null)
public TestRestClient() : base("Test", new RestClientOptions("http://testurl.url"), null)
{
RequestFactory = new Mock<IRequestFactory>().Object;
}
public TestRestClient(RestClientOptions exchangeOptions) : base(exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
public TestRestClient(RestClientOptions exchangeOptions) : base("Test", exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
{
RequestFactory = new Mock<IRequestFactory>().Object;
}

View File

@ -15,7 +15,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
{
}
public TestSocketClient(SocketClientOptions exchangeOptions) : base(exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
public TestSocketClient(SocketClientOptions exchangeOptions) : base("test", exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
{
SocketFactory = new Mock<IWebsocketFactory>().Object;
Mock.Get(SocketFactory).Setup(f => f.CreateWebsocket(It.IsAny<Log>(), It.IsAny<string>())).Returns(new TestSocket());

View File

@ -25,6 +25,10 @@ namespace CryptoExchange.Net
/// </summary>
public string BaseAddress { get; }
/// <summary>
/// The name of the client
/// </summary>
public string ClientName { get; }
/// <summary>
/// The log object
/// </summary>
protected internal Log log;
@ -64,15 +68,17 @@ namespace CryptoExchange.Net
/// <summary>
/// ctor
/// </summary>
/// <param name="clientName"></param>
/// <param name="options"></param>
/// <param name="authenticationProvider"></param>
protected BaseClient(ClientOptions options, AuthenticationProvider? authenticationProvider)
protected BaseClient(string clientName, ClientOptions options, AuthenticationProvider? authenticationProvider)
{
log = new Log();
log = new Log(clientName);
authProvider = authenticationProvider;
log.UpdateWriters(options.LogWriters);
log.Level = options.LogVerbosity;
ClientName = clientName;
BaseAddress = options.BaseAddress;
apiProxy = options.Proxy;

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup>
@ -21,7 +21,7 @@
<DocumentationFile>CryptoExchange.Net.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="WebSocket4Net" Version="0.15.2" />
</ItemGroup>
</Project>

View File

@ -209,6 +209,11 @@
The address of the client
</summary>
</member>
<member name="P:CryptoExchange.Net.BaseClient.ClientName">
<summary>
The name of the client
</summary>
</member>
<member name="F:CryptoExchange.Net.BaseClient.log">
<summary>
The log object
@ -244,10 +249,11 @@
Last is used
</summary>
</member>
<member name="M:CryptoExchange.Net.BaseClient.#ctor(CryptoExchange.Net.Objects.ClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)">
<member name="M:CryptoExchange.Net.BaseClient.#ctor(System.String,CryptoExchange.Net.Objects.ClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)">
<summary>
ctor
</summary>
<param name="clientName"></param>
<param name="options"></param>
<param name="authenticationProvider"></param>
</member>
@ -435,6 +441,105 @@
<member name="M:CryptoExchange.Net.Converters.UTCDateTimeConverter.CanConvert(System.Type)">
<inheritdoc />
</member>
<member name="T:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient">
<summary>
Shared interface for exchange wrappers based on the CryptoExchange.Net package
</summary>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetSymbolName(System.String,System.String)">
<summary>
Get the symbol name basset on a base and quote asset
</summary>
<param name="baseAsset"></param>
<param name="quoteAsset"></param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetSymbolsAsync">
<summary>
Get a list of symbols for the exchange
</summary>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetTickersAsync">
<summary>
Get a list of tickers for the exchange
</summary>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetKlinesAsync(System.String,System.TimeSpan)">
<summary>
Get a list of candles for a given symbol on the exchange
</summary>
<param name="symbol">The symbol to retrieve the candles for</param>
<param name="timespan">The timespan to retrieve the candles for. The supported value are dependent on the exchange</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetOrderBookAsync(System.String)">
<summary>
Get the order book for a symbol
</summary>
<param name="symbol">The symbol to get the book for</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetRecentTradesAsync(System.String)">
<summary>
The recent trades for a symbol
</summary>
<param name="symbol">The symbol to get the trades for</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.PlaceOrderAsync(System.String,CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.OrderSide,CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.OrderType,System.Decimal,System.Nullable{System.Decimal},System.String)">
<summary>
Place an order
</summary>
<param name="symbol">The symbol the order is for</param>
<param name="side">The side of the order</param>
<param name="type">The type of the order</param>
<param name="quantity">The quantity of the order</param>
<param name="price">The price of the order, only for limit orders</param>
<param name="accountId">[Optional] The account id to place the order on, required for some exchanges</param>
<returns>The id of the resulting order</returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetOrderAsync(System.String,System.String)">
<summary>
Get an order by id
</summary>
<param name="orderId">The id</param>
<param name="symbol">[Optional] The symbol the order is on, required for some exchanges</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetTradesAsync(System.String,System.String)">
<summary>
Get trades for an order by id
</summary>
<param name="orderId">The id</param>
<param name="symbol">[Optional] The symbol the order is on, required for some exchanges</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetOpenOrdersAsync(System.String)">
<summary>
Get a list of open orders
</summary>
<param name="symbol">[Optional] The symbol to get open orders for, required for some exchanges. If the symbol is not required for the call,
the result will NOT be filtered by this</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.GetClosedOrdersAsync(System.String)">
<summary>
Get a list of closed orders
</summary>
<param name="symbol">[Optional] The symbol to get closed orders for, required for some exchanges. If the symbol is not required for the call,
the result will NOT be filtered by this</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.ExchangeInterfaces.IExchangeClient.CancelOrderAsync(System.String,System.String)">
<summary>
Cancel an order by id
</summary>
<param name="orderId">The id</param>
<param name="symbol">[Optional] The symbol the order is on, required for some exchanges</param>
<returns></returns>
</member>
<member name="T:CryptoExchange.Net.ExtensionMethods">
<summary>
Helper methods
@ -712,6 +817,11 @@
The base address of the API
</summary>
</member>
<member name="P:CryptoExchange.Net.Interfaces.IRestClient.ClientName">
<summary>
Client name
</summary>
</member>
<member name="M:CryptoExchange.Net.Interfaces.IRestClient.AddRateLimiter(CryptoExchange.Net.Interfaces.IRateLimiter)">
<summary>
Adds a rate limiter to the client. There are 2 choices, the <see cref="T:CryptoExchange.Net.RateLimiter.RateLimiterTotal"/> and the <see cref="T:CryptoExchange.Net.RateLimiter.RateLimiterPerEndpoint"/>.
@ -1065,7 +1175,12 @@
The verbosity of the logging
</summary>
</member>
<member name="M:CryptoExchange.Net.Logging.Log.#ctor">
<member name="P:CryptoExchange.Net.Logging.Log.ClientName">
<summary>
Client name
</summary>
</member>
<member name="M:CryptoExchange.Net.Logging.Log.#ctor(System.String)">
<summary>
ctor
</summary>
@ -1304,6 +1419,15 @@
<param name="error"></param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.Objects.WebCallResult.CreateErrorResult(CryptoExchange.Net.Objects.WebCallResult)">
<summary>
Create an error result
</summary>
<param name="code"></param>
<param name="responseHeaders"></param>
<param name="error"></param>
<returns></returns>
</member>
<member name="T:CryptoExchange.Net.Objects.WebCallResult`1">
<summary>
The result of a request
@ -2259,10 +2383,11 @@
Total requests made
</summary>
</member>
<member name="M:CryptoExchange.Net.RestClient.#ctor(CryptoExchange.Net.Objects.RestClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)">
<member name="M:CryptoExchange.Net.RestClient.#ctor(System.String,CryptoExchange.Net.Objects.RestClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)">
<summary>
ctor
</summary>
<param name="clientName"></param>
<param name="exchangeOptions"></param>
<param name="authenticationProvider"></param>
</member>
@ -2423,10 +2548,11 @@
If false; data which is a response to a query won't get forwarded to subscriptions as well
</summary>
</member>
<member name="M:CryptoExchange.Net.SocketClient.#ctor(CryptoExchange.Net.Objects.SocketClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)">
<member name="M:CryptoExchange.Net.SocketClient.#ctor(System.String,CryptoExchange.Net.Objects.SocketClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)">
<summary>
Create a socket client
</summary>
<param name="clientName">Client name</param>
<param name="exchangeOptions">Client options</param>
<param name="authenticationProvider">Authentication provider</param>
</member>
@ -3061,5 +3187,148 @@
<member name="M:CryptoExchange.Net.Sockets.WebsocketFactory.CreateWebsocket(CryptoExchange.Net.Logging.Log,System.String,System.Collections.Generic.IDictionary{System.String,System.String},System.Collections.Generic.IDictionary{System.String,System.String})">
<inheritdoc />
</member>
<member name="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute">
<summary>
Specifies that <see langword="null"/> is allowed as an input even if the
corresponding type disallows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.AllowNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute">
<summary>
Specifies that <see langword="null"/> is disallowed as an input even if the
corresponding type allows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.DisallowNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute">
<summary>
Specifies that a method that will never return under any circumstance.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute">
<summary>
Specifies that the method will not return if the associated <see cref="T:System.Boolean"/>
parameter is passed the specified value.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.ParameterValue">
<summary>
Gets the condition parameter value.
Code after the method is considered unreachable by diagnostics if the argument
to the associated parameter matches this value.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.#ctor(System.Boolean)">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute"/>
class with the specified parameter value.
</summary>
<param name="parameterValue">
The condition parameter value.
Code after the method is considered unreachable by diagnostics if the argument
to the associated parameter matches this value.
</param>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute">
<summary>
Specifies that an output may be <see langword="null"/> even if the
corresponding type disallows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.MaybeNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute">
<summary>
Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue"/>,
the parameter may be <see langword="null"/> even if the corresponding type disallows it.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue">
<summary>
Gets the return value condition.
If the method returns this value, the associated parameter may be <see langword="null"/>.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.#ctor(System.Boolean)">
<summary>
Initializes the attribute with the specified return value condition.
</summary>
<param name="returnValue">
The return value condition.
If the method returns this value, the associated parameter may be <see langword="null"/>.
</param>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.NotNullAttribute">
<summary>
Specifies that an output is not <see langword="null"/> even if the
corresponding type allows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.NotNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.NotNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute">
<summary>
Specifies that the output will be non-<see langword="null"/> if the
named parameter is non-<see langword="null"/>.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.ParameterName">
<summary>
Gets the associated parameter name.
The output will be non-<see langword="null"/> if the argument to the
parameter specified is non-<see langword="null"/>.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.#ctor(System.String)">
<summary>
Initializes the attribute with the associated parameter name.
</summary>
<param name="parameterName">
The associated parameter name.
The output will be non-<see langword="null"/> if the argument to the
parameter specified is non-<see langword="null"/>.
</param>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute">
<summary>
Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue"/>,
the parameter will not be <see langword="null"/> even if the corresponding type allows it.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue">
<summary>
Gets the return value condition.
If the method returns this value, the associated parameter will not be <see langword="null"/>.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.#ctor(System.Boolean)">
<summary>
Initializes the attribute with the specified return value condition.
</summary>
<param name="returnValue">
The return value condition.
If the method returns this value, the associated parameter will not be <see langword="null"/>.
</param>
</member>
</members>
</doc>

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common trade
/// </summary>
public interface ICommonTrade
{
/// <summary>
/// Id of the trade
/// </summary>
public string CommonId { get; }
/// <summary>
/// Price of the trade
/// </summary>
public decimal CommonPrice { get; }
/// <summary>
/// Quantity of the trade
/// </summary>
public decimal CommonQuantity { get; }
/// <summary>
/// Fee paid for the trade
/// </summary>
public decimal CommonFee { get; }
/// <summary>
/// The asset fee was paid in
/// </summary>
public string? CommonFeeAsset { get; }
}
}

View File

@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Shared interface for exchange wrappers based on the CryptoExchange.Net package
/// </summary>
public interface IExchangeClient
{
/// <summary>
/// Get the symbol name based on a base and quote asset
/// </summary>
/// <param name="baseAsset"></param>
/// <param name="quoteAsset"></param>
/// <returns></returns>
string GetSymbolName(string baseAsset, string quoteAsset);
/// <summary>
/// Get a list of symbols for the exchange
/// </summary>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonSymbol>>> GetSymbolsAsync();
/// <summary>
/// Get a list of tickers for the exchange
/// </summary>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonTicker>>> GetTickersAsync();
/// <summary>
/// Get a list of candles for a given symbol on the exchange
/// </summary>
/// <param name="symbol">The symbol to retrieve the candles for</param>
/// <param name="timespan">The timespan to retrieve the candles for. The supported value are dependent on the exchange</param>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonKline>>> GetKlinesAsync(string symbol, TimeSpan timespan);
/// <summary>
/// Get the order book for a symbol
/// </summary>
/// <param name="symbol">The symbol to get the book for</param>
/// <returns></returns>
Task<WebCallResult<ICommonOrderBook>> GetOrderBookAsync(string symbol);
/// <summary>
/// The recent trades for a symbol
/// </summary>
/// <param name="symbol">The symbol to get the trades for</param>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonRecentTrade>>> GetRecentTradesAsync(string symbol);
/// <summary>
/// Place an order
/// </summary>
/// <param name="symbol">The symbol the order is for</param>
/// <param name="side">The side of the order</param>
/// <param name="type">The type of the order</param>
/// <param name="quantity">The quantity of the order</param>
/// <param name="price">The price of the order, only for limit orders</param>
/// <param name="accountId">[Optional] The account id to place the order on, required for some exchanges, ignored otherwise</param>
/// <returns>The id of the resulting order</returns>
Task<WebCallResult<ICommonOrderId>> PlaceOrderAsync(string symbol, OrderSide side, OrderType type, decimal quantity, decimal? price = null, string? accountId = null);
/// <summary>
/// Get an order by id
/// </summary>
/// <param name="orderId">The id</param>
/// <param name="symbol">[Optional] The symbol the order is on, required for some exchanges, ignored otherwise</param>
/// <returns></returns>
Task<WebCallResult<ICommonOrder>> GetOrderAsync(string orderId, string? symbol = null);
/// <summary>
/// Get trades for an order by id
/// </summary>
/// <param name="orderId">The id</param>
/// <param name="symbol">[Optional] The symbol the order is on, required for some exchanges, ignored otherwise</param>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonTrade>>> GetTradesAsync(string orderId, string? symbol = null);
/// <summary>
/// Get a list of open orders
/// </summary>
/// <param name="symbol">[Optional] The symbol to get open orders for, required for some exchanges, ignored otherwise</param>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonOrder>>> GetOpenOrdersAsync(string? symbol);
/// <summary>
/// Get a list of closed orders
/// </summary>
/// <param name="symbol">[Optional] The symbol to get closed orders for, required for some exchanges, ignored otherwise</param>
/// <returns></returns>
Task<WebCallResult<IEnumerable<ICommonOrder>>> GetClosedOrdersAsync(string? symbol);
/// <summary>
/// Cancel an order by id
/// </summary>
/// <param name="orderId">The id</param>
/// <param name="symbol">[Optional] The symbol the order is on, required for some exchanges, ignored otherwise</param>
/// <returns></returns>
Task<WebCallResult<ICommonOrderId>> CancelOrderAsync(string orderId, string? symbol);
/// <summary>
/// Common order id
/// </summary>
public enum OrderType
{
/// <summary>
/// Limit type
/// </summary>
Limit,
/// <summary>
/// Market type
/// </summary>
Market,
/// <summary>
/// Other order type
/// </summary>
Other
}
/// <summary>
/// Common order side
/// </summary>
public enum OrderSide
{
/// <summary>
/// Buy order
/// </summary>
Buy,
/// <summary>
/// Sell order
/// </summary>
Sell
}
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common kline
/// </summary>
public interface ICommonKline
{
/// <summary>
/// High price for this kline
/// </summary>
decimal CommonHigh { get; }
/// <summary>
/// Low price for this kline
/// </summary>
decimal CommonLow { get; }
/// <summary>
/// Open price for this kline
/// </summary>
decimal CommonOpen { get; }
/// <summary>
/// Close price for this kline
/// </summary>
decimal CommonClose { get; }
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common order
/// </summary>
public interface ICommonOrder: ICommonOrderId
{
/// <summary>
/// Symbol of the order
/// </summary>
public string CommonSymbol { get; }
/// <summary>
/// Price of the order
/// </summary>
public decimal CommonPrice { get; }
/// <summary>
/// Quantity of the order
/// </summary>
public decimal CommonQuantity { get; }
/// <summary>
/// Status of the order
/// </summary>
public string CommonStatus { get; }
/// <summary>
/// Whether the order is active
/// </summary>
public bool IsActive { get; }
/// <summary>
/// Side of the order
/// </summary>
public IExchangeClient.OrderSide CommonSide { get; }
/// <summary>
/// Type of the order
/// </summary>
public IExchangeClient.OrderType CommonType { get; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
using CryptoExchange.Net.Interfaces;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common order book
/// </summary>
public interface ICommonOrderBook
{
/// <summary>
/// Bids
/// </summary>
IEnumerable<ISymbolOrderBookEntry> CommonBids { get; }
/// <summary>
/// Asks
/// </summary>
IEnumerable<ISymbolOrderBookEntry> CommonAsks { get; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common order id
/// </summary>
public interface ICommonOrderId
{
/// <summary>
/// Id of the order
/// </summary>
public string CommonId { get; }
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Recent trade
/// </summary>
public interface ICommonRecentTrade
{
/// <summary>
/// Price of the trade
/// </summary>
decimal CommonPrice { get; }
/// <summary>
/// Quantity of the trade
/// </summary>
decimal CommonQuantity { get; }
/// <summary>
/// Trade time
/// </summary>
DateTime CommonTradeTime { get; }
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common symbol
/// </summary>
public interface ICommonSymbol
{
/// <summary>
/// Symbol name
/// </summary>
public string CommonName { get; }
/// <summary>
/// Minimum trade size
/// </summary>
public decimal CommonMinimumTradeSize { get; }
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.ExchangeInterfaces
{
/// <summary>
/// Common ticker
/// </summary>
public interface ICommonTicker
{
/// <summary>
/// Symbol name
/// </summary>
public string CommonSymbol { get; }
/// <summary>
/// High price
/// </summary>
public decimal CommonHigh { get; }
/// <summary>
/// Low price
/// </summary>
public decimal CommonLow { get; }
/// <summary>
/// Volume
/// </summary>
public decimal CommonVolume { get; }
}
}

View File

@ -37,6 +37,11 @@ namespace CryptoExchange.Net.Interfaces
/// </summary>
string BaseAddress { get; }
/// <summary>
/// Client name
/// </summary>
string ClientName { get; }
/// <summary>
/// Adds a rate limiter to the client. There are 2 choices, the <see cref="RateLimiterTotal"/> and the <see cref="RateLimiterPerEndpoint"/>.
/// </summary>

View File

@ -17,11 +17,17 @@ namespace CryptoExchange.Net.Logging
/// </summary>
public LogVerbosity Level { get; set; } = LogVerbosity.Info;
/// <summary>
/// Client name
/// </summary>
public string ClientName { get; set; }
/// <summary>
/// ctor
/// </summary>
public Log()
public Log(string clientName)
{
ClientName = clientName;
writers = new List<TextWriter>();
}
@ -44,7 +50,7 @@ namespace CryptoExchange.Net.Logging
if ((int)logType < (int)Level)
return;
var logMessage = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | {logType} | {message}";
var logMessage = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | {ClientName.PadRight(10)} | {logType} | {message}";
foreach (var writer in writers.ToList())
{
try

View File

@ -154,6 +154,18 @@ namespace CryptoExchange.Net.Objects
{
return new WebCallResult(code, responseHeaders, error);
}
/// <summary>
/// Create an error result
/// </summary>
/// <param name="code"></param>
/// <param name="responseHeaders"></param>
/// <param name="error"></param>
/// <returns></returns>
public static WebCallResult CreateErrorResult(WebCallResult result)
{
return new WebCallResult(result.ResponseStatusCode, result.ResponseHeaders, result.Error);
}
}
/// <summary>
@ -187,6 +199,17 @@ namespace CryptoExchange.Net.Objects
ResponseHeaders = responseHeaders;
}
public WebCallResult(WebCallResult<T> callResult): base(callResult.Data, callResult.Error)
{
ResponseHeaders = callResult.ResponseHeaders;
ResponseStatusCode = callResult.ResponseStatusCode;
}
public static WebCallResult<T> CreateFrom<Y>(WebCallResult<Y> source) where Y : T
{
return new WebCallResult<T>(source.ResponseStatusCode, source.ResponseHeaders, (T)source.Data, source.Error);
}
/// <summary>
/// Create an error result
/// </summary>

View File

@ -208,7 +208,7 @@ namespace CryptoExchange.Net.OrderBook
asks = new SortedList<decimal, ISymbolOrderBookEntry>();
bids = new SortedList<decimal, ISymbolOrderBookEntry>(new DescComparer<decimal>());
log = new Log { Level = options.LogVerbosity };
log = new Log(options.OrderBookName) { Level = options.LogVerbosity };
var writers = options.LogWriters ?? new List<TextWriter> { new DebugTextWriter() };
log.UpdateWriters(writers.ToList());
}

View File

@ -76,9 +76,10 @@ namespace CryptoExchange.Net
/// <summary>
/// ctor
/// </summary>
/// <param name="clientName"></param>
/// <param name="exchangeOptions"></param>
/// <param name="authenticationProvider"></param>
protected RestClient(RestClientOptions exchangeOptions, AuthenticationProvider? authenticationProvider) : base(exchangeOptions, authenticationProvider)
protected RestClient(string clientName, RestClientOptions exchangeOptions, AuthenticationProvider? authenticationProvider) : base(clientName, exchangeOptions, authenticationProvider)
{
if (exchangeOptions == null)
throw new ArgumentNullException(nameof(exchangeOptions));

View File

@ -83,9 +83,10 @@ namespace CryptoExchange.Net
/// <summary>
/// Create a socket client
/// </summary>
/// <param name="clientName">Client name</param>
/// <param name="exchangeOptions">Client options</param>
/// <param name="authenticationProvider">Authentication provider</param>
protected SocketClient(SocketClientOptions exchangeOptions, AuthenticationProvider? authenticationProvider): base(exchangeOptions, authenticationProvider)
protected SocketClient(string clientName, SocketClientOptions exchangeOptions, AuthenticationProvider? authenticationProvider): base(clientName, exchangeOptions, authenticationProvider)
{
if (exchangeOptions == null)
throw new ArgumentNullException(nameof(exchangeOptions));