mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-10-04 10:21:13 +00:00
Added ISpotOrderManagementSocketClient and IFuturesOrderManagementSocketClient for placing/canceling orders via websocket
This commit is contained in:
@@ -461,11 +461,15 @@ namespace CryptoExchange.Net
|
|||||||
|
|
||||||
if (typeof(ISpotOrderSocketClient).IsAssignableFrom(typeof(T)))
|
if (typeof(ISpotOrderSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
services.AddTransient(x => (ISpotOrderSocketClient)client(x)!);
|
services.AddTransient(x => (ISpotOrderSocketClient)client(x)!);
|
||||||
|
if (typeof(ISpotOrderManagementSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
|
services.AddTransient(x => (ISpotOrderManagementSocketClient)client(x)!);
|
||||||
|
|
||||||
if (typeof(IFuturesOrderSocketClient).IsAssignableFrom(typeof(T)))
|
if (typeof(IFuturesOrderSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
services.AddTransient(x => (IFuturesOrderSocketClient)client(x)!);
|
services.AddTransient(x => (IFuturesOrderSocketClient)client(x)!);
|
||||||
if (typeof(IPositionSocketClient).IsAssignableFrom(typeof(T)))
|
if (typeof(IPositionSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
services.AddTransient(x => (IPositionSocketClient)client(x)!);
|
services.AddTransient(x => (IPositionSocketClient)client(x)!);
|
||||||
|
if (typeof(IFuturesOrderManagementSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
|
services.AddTransient(x => (IFuturesOrderManagementSocketClient)client(x)!);
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
PlaceSpotOrderOptions PlaceSpotOrderOptions { get; }
|
PlaceSpotOrderOptions PlaceSpotOrderOptions { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Place a new spot order, see <see cref="PlaceSpotOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
/// Place a new spot order, see <see cref="PlaceSpotOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
/// The result is paginated, if there are more results to be retrieved, the `NextPageRequest` property of the result will contain the pagination request to be used for the next request to continue pagination.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
|||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for placing and managing futures orders
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesOrderManagementSocketClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How the trading fee is deducted
|
||||||
|
/// </summary>
|
||||||
|
SharedFeeDeductionType FuturesFeeDeductionType { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// How the asset is determined in which the trading fee is paid
|
||||||
|
/// </summary>
|
||||||
|
SharedFeeAssetType FuturesFeeAssetType { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported order types for futures orders
|
||||||
|
/// </summary>
|
||||||
|
SharedOrderType[] FuturesSupportedOrderTypes { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported time in force types for futures orders
|
||||||
|
/// </summary>
|
||||||
|
SharedTimeInForce[] FuturesSupportedTimeInForce { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported quantity types for futures orders
|
||||||
|
/// </summary>
|
||||||
|
SharedQuantitySupport FuturesSupportedOrderQuantity { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a new random client order id
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
string GenerateClientOrderId();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Futures place order request options.<br />
|
||||||
|
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
PlaceFuturesOrderSocketOptions PlaceFuturesOrderOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Place a new futures order, see <see cref="PlaceFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<QueryResult<SharedId>> PlaceFuturesOrderAsync(PlaceFuturesOrderRequest request, CancellationToken ct = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Futures cancel order request options.<br />
|
||||||
|
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
CancelFuturesOrderSocketOptions CancelFuturesOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cancel a futures order, see <see cref="CancelFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<QueryResult<SharedId>> CancelFuturesOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for placing and managing spot orders
|
||||||
|
/// </summary>
|
||||||
|
public interface ISpotOrderManagementSocketClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How the trading fee is deducted
|
||||||
|
/// </summary>
|
||||||
|
SharedFeeDeductionType SpotFeeDeductionType { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// How the asset is determined in which the trading fee is paid
|
||||||
|
/// </summary>
|
||||||
|
SharedFeeAssetType SpotFeeAssetType { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported order types for spot orders
|
||||||
|
/// </summary>
|
||||||
|
SharedOrderType[] SpotSupportedOrderTypes { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported time in force types for placing spot orders
|
||||||
|
/// </summary>
|
||||||
|
SharedTimeInForce[] SpotSupportedTimeInForce { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported quantity types for placing spot orders
|
||||||
|
/// </summary>
|
||||||
|
SharedQuantitySupport SpotSupportedOrderQuantity { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a new random client order id
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
string GenerateClientOrderId();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spot place order request options.<br />
|
||||||
|
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
PlaceSpotOrderSocketOptions PlaceSpotOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Place a new spot order, see <see cref="PlaceSpotOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<QueryResult<SharedId>> PlaceSpotOrderAsync(PlaceSpotOrderRequest request, CancellationToken ct = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spot cancel order request options.<br />
|
||||||
|
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
CancelSpotOrderSocketOptions CancelSpotOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cancel a spot order, see <see cref="CancelSpotOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<QueryResult<SharedId>> CancelSpotOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Options for canceling a futures order
|
||||||
|
/// </summary>
|
||||||
|
public class CancelFuturesOrderSocketOptions : EndpointOptions<CancelOrderRequest, IFuturesOrderManagementSocketClient>
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Description => "Cancel a futures order over a socket connection";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public CancelFuturesOrderSocketOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(IFuturesOrderManagementSocketClient.CancelFuturesOrderAsync))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Options for canceling a spot order
|
||||||
|
/// </summary>
|
||||||
|
public class CancelSpotOrderSocketOptions : EndpointOptions<CancelOrderRequest, ISpotOrderManagementSocketClient>
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Description => "Cancel a spot order over a socket connection";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public CancelSpotOrderSocketOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(ISpotOrderManagementSocketClient.CancelSpotOrderAsync))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Error? ValidateRequest(CancelOrderRequest request, ISpotOrderManagementSocketClient client)
|
||||||
|
{
|
||||||
|
if (request.Symbol!.TradingMode != TradingMode.Spot)
|
||||||
|
return ArgumentError.Invalid("TradingMode", $"TradingMode.{request.Symbol!.TradingMode} is not supported, should be Spot");
|
||||||
|
|
||||||
|
return base.ValidateRequest(request, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Options for placing a new futures order
|
||||||
|
/// </summary>
|
||||||
|
public class PlaceFuturesOrderSocketOptions : EndpointOptions<PlaceFuturesOrderRequest, IFuturesOrderManagementSocketClient>
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Description => "Place a new futures order over a socket connection";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not the API supports setting take profit / stop loss with the order
|
||||||
|
/// </summary>
|
||||||
|
public bool SupportsTpSl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public PlaceFuturesOrderSocketOptions(string exchange, bool supportsTpSl) : base(exchange, true, nameof(IFuturesOrderManagementSocketClient.PlaceFuturesOrderAsync))
|
||||||
|
{
|
||||||
|
SupportsTpSl = supportsTpSl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a request
|
||||||
|
/// </summary>
|
||||||
|
public override Error? ValidateRequest(
|
||||||
|
PlaceFuturesOrderRequest request,
|
||||||
|
IFuturesOrderManagementSocketClient client
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!SupportsTpSl && (request.StopLossPrice != null || request.TakeProfitPrice != null))
|
||||||
|
return ArgumentError.Invalid(nameof(PlaceFuturesOrderRequest.StopLossPrice) + " / " + nameof(PlaceFuturesOrderRequest.TakeProfitPrice), "Tp/Sl parameters not supported");
|
||||||
|
|
||||||
|
if (request.OrderType == SharedOrderType.Other)
|
||||||
|
throw new ArgumentException("OrderType can't be `Other`", nameof(request.OrderType));
|
||||||
|
|
||||||
|
if (!client.FuturesSupportedOrderTypes.Contains(request.OrderType))
|
||||||
|
return ArgumentError.Invalid(nameof(PlaceFuturesOrderRequest.OrderType), "Order type not supported");
|
||||||
|
|
||||||
|
if (request.TimeInForce != null && !client.FuturesSupportedTimeInForce.Contains(request.TimeInForce.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(PlaceFuturesOrderRequest.TimeInForce), "Order time in force not supported");
|
||||||
|
|
||||||
|
var quantityError = client.FuturesSupportedOrderQuantity.Validate(request.Side, request.OrderType, request.Quantity);
|
||||||
|
if (quantityError != null)
|
||||||
|
return quantityError;
|
||||||
|
|
||||||
|
return base.ValidateRequest(request, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Options for placing a new spot order
|
||||||
|
/// </summary>
|
||||||
|
public class PlaceSpotOrderSocketOptions : EndpointOptions<PlaceSpotOrderRequest, ISpotOrderManagementSocketClient>
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Description => "Place a new spot order over a socket connection";
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public PlaceSpotOrderSocketOptions(string exchange) : base(exchange, true, nameof(ISpotOrderManagementSocketClient.PlaceSpotOrderAsync))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a request
|
||||||
|
/// </summary>
|
||||||
|
public override Error? ValidateRequest(
|
||||||
|
PlaceSpotOrderRequest request,
|
||||||
|
ISpotOrderManagementSocketClient client)
|
||||||
|
{
|
||||||
|
if (request.Symbol!.TradingMode != TradingMode.Spot)
|
||||||
|
return ArgumentError.Invalid("TradingMode", $"TradingMode.{request.Symbol!.TradingMode} is not supported, should be Spot");
|
||||||
|
|
||||||
|
if (request.OrderType == SharedOrderType.Other)
|
||||||
|
throw new ArgumentException("OrderType can't be `Other`", nameof(request.OrderType));
|
||||||
|
|
||||||
|
if (!client.SpotSupportedOrderTypes.Contains(request.OrderType))
|
||||||
|
return ArgumentError.Invalid(nameof(PlaceSpotOrderRequest.OrderType), "Order type not supported");
|
||||||
|
|
||||||
|
if (request.TimeInForce != null && !client.SpotSupportedTimeInForce.Contains(request.TimeInForce.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(PlaceSpotOrderRequest.TimeInForce), "Order time in force not supported");
|
||||||
|
|
||||||
|
var quantityError = client.SpotSupportedOrderQuantity.Validate(request.Side, request.OrderType, request.Quantity);
|
||||||
|
if (quantityError != null)
|
||||||
|
return quantityError;
|
||||||
|
|
||||||
|
return base.ValidateRequest(request, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -169,13 +169,23 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
|
|
||||||
if (client is ISpotOrderSocketClient spotOrderSocketClient)
|
if (client is ISpotOrderSocketClient spotOrderSocketClient)
|
||||||
result.Add(spotOrderSocketClient.SubscribeSpotOrderOptions);
|
result.Add(spotOrderSocketClient.SubscribeSpotOrderOptions);
|
||||||
|
if (client is ISpotOrderManagementSocketClient spotOrderManagementSocketClient)
|
||||||
|
{
|
||||||
|
result.Add(spotOrderManagementSocketClient.PlaceSpotOrderOptions);
|
||||||
|
result.Add(spotOrderManagementSocketClient.CancelSpotOrderOptions);
|
||||||
|
}
|
||||||
|
|
||||||
if (client is IFuturesOrderSocketClient futuresOrderSocketClient)
|
if (client is IFuturesOrderSocketClient futuresOrderSocketClient)
|
||||||
result.Add(futuresOrderSocketClient.SubscribeFuturesOrderOptions);
|
result.Add(futuresOrderSocketClient.SubscribeFuturesOrderOptions);
|
||||||
if (client is IPositionSocketClient positionSocketClient)
|
if (client is IPositionSocketClient positionSocketClient)
|
||||||
result.Add(positionSocketClient.SubscribePositionOptions);
|
result.Add(positionSocketClient.SubscribePositionOptions);
|
||||||
|
if (client is IFuturesOrderManagementSocketClient futuresOrderManagementSocketClient)
|
||||||
|
{
|
||||||
|
result.Add(futuresOrderManagementSocketClient.PlaceFuturesOrderOptions);
|
||||||
|
result.Add(futuresOrderManagementSocketClient.CancelFuturesOrderOptions);
|
||||||
|
}
|
||||||
|
|
||||||
return result.ToArray();
|
return result.Where(x => x.Supported).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user