Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Margin trading support, #184

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions BinanceExchange.API/Client/BinanceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,61 @@ public async Task<BaseCreateOrderResponse> CreateOrder(CreateOrderRequest reques

}

/// <summary>
/// Creates an Isolated account order based on the provided request
/// </summary>
/// <param name="request">The <see cref="CreateIsolatedOrderRequest"/> that is used to define the order</param>
/// <returns>This method can return <see cref="AcknowledgeCreateOrderResponse"/>, <see cref="FullCreateOrderResponse"/>
/// or <see cref="ResultCreateOrderResponse"/> based on the provided NewOrderResponseType enum in the request.
/// </returns>
public async Task<BaseCreateOrderResponse> CreateIsolatedOrder(CreateIsolatedOrderRequest request)
{
Guard.AgainstNull(request.Symbol);
Guard.AgainstNull(request.Side);
Guard.AgainstNull(request.Type);
Guard.AgainstNull(request.Quantity);

switch (request.NewOrderResponseType)
{
case NewOrderResponseType.Acknowledge:
return await _apiProcessor.ProcessPostRequest<AcknowledgeCreateOrderResponse>(Endpoints.Account.NewOrder(request));
case NewOrderResponseType.Full:
return await _apiProcessor.ProcessPostRequest<FullCreateOrderResponse>(Endpoints.Account.NewOrder(request));
default:
return await _apiProcessor.ProcessPostRequest<ResultCreateOrderResponse>(Endpoints.Account.NewOrder(request));
}

}

/// <summary>
/// Query account max possible borrow (coin symbol specific)
/// </summary>
/// <param name="request">The <see cref="CreateIsolatedOrderRequest"/> that is used to define the order</param>
/// <returns>This method can return <see cref="AcknowledgeCreateOrderResponse"/>, <see cref="FullCreateOrderResponse"/>
/// or <see cref="ResultCreateOrderResponse"/> based on the provided NewOrderResponseType enum in the request.
/// </returns>
public async Task<MaxBorrowResponse> QueryMaxBorrow(MaxBorrowRequest request)
{
Guard.AgainstNull(request.Asset);
Guard.AgainstNull(request.IsolatedSymbol);

return await _apiProcessor.ProcessGetRequest<MaxBorrowResponse>(Endpoints.Account.NewOrder(request));
}

/// <summary>
/// Creates an order based on the provided request
/// </summary>
/// <param name="request">The <see cref="CreateIsolatedOrderRequest"/> that is used to define the order</param>
/// <returns>This method can return <see cref="AcknowledgeCreateOrderResponse"/>, <see cref="FullCreateOrderResponse"/>
/// or <see cref="ResultCreateOrderResponse"/> based on the provided NewOrderResponseType enum in the request.
/// </returns>
public async Task<IsolatedMarginAccountInfoResponse> QueryIsolatedMarginAccountInfo(IsolatedMarginAccountInfoRequest request)
{
Guard.AgainstNull(request.Symbols);

return await _apiProcessor.ProcessGetRequest<IsolatedMarginAccountInfoResponse>(Endpoints.Account.NewOrder(request));
}

/// <summary>
/// Creates a test order based on the provided request
/// </summary>
Expand Down
22 changes: 22 additions & 0 deletions BinanceExchange.API/Endpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ public static class Endpoints
/// Defaults to API binance domain (https)
/// </summary>
internal static string APIBaseUrl = "https://api.binance.com/api";
internal static string BAPIBaseUrl = "https://api.binance.com/bapi";
internal static string SAPIBaseUrl = "https://api.binance.com/sapi";

/// <summary>
/// Defaults to WAPI binance domain (https)
/// </summary>
internal static string WAPIBaseUrl = "https://api.binance.com/wapi";

private static string APIPrefix { get; } = $"{APIBaseUrl}";
private static string BAPIPrefix { get; } = $"{BAPIBaseUrl}";
private static string SAPIPrefix { get; } = $"{SAPIBaseUrl}/v1";
private static string WAPIPrefix { get; } = $"{WAPIBaseUrl}";

public static class UserStream
Expand Down Expand Up @@ -241,6 +245,24 @@ public static BinanceEndpointData SystemStatus()
{
return new BinanceEndpointData(new Uri($"{WAPIPrefix}/{ApiVersion}/systemStatus.html"), EndpointSecurityType.None);
}

public static BinanceEndpointData NewOrder(CreateIsolatedOrderRequest request)
{
var queryString = GenerateQueryStringFromData(request);
return new BinanceEndpointData(new Uri($"{SAPIPrefix}/margin/order?{queryString}"), EndpointSecurityType.Signed);
}

public static BinanceEndpointData NewOrder(MaxBorrowRequest request)
{
var queryString = GenerateQueryStringFromData(request);
return new BinanceEndpointData(new Uri($"{SAPIPrefix}/margin/maxBorrowable?{queryString}"), EndpointSecurityType.Signed);
}

public static BinanceEndpointData NewOrder(IsolatedMarginAccountInfoRequest request)
{
var queryString = GenerateQueryStringFromData(request);
return new BinanceEndpointData(new Uri($"{SAPIPrefix}/margin/isolated/account?{queryString}"), EndpointSecurityType.Signed);
}
}

private static string GenerateQueryStringFromData(IRequest request)
Expand Down
14 changes: 14 additions & 0 deletions BinanceExchange.API/Enums/SideEffectType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Runtime.Serialization;

namespace BinanceExchange.API.Enums
{
public enum SideEffectType
{
[EnumMember(Value = "NO_SIDE_EFFECT")]
NoSideEffect,
[EnumMember(Value = "MARGIN_BUY")]
MarginBuy,
[EnumMember(Value = "AUTO_REPAY")]
AutoRepay,
}
}
81 changes: 81 additions & 0 deletions BinanceExchange.API/Models/Request/CreateIsolatedOrderRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using BinanceExchange.API.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;
using BinanceExchange.API.Models.Request.Interfaces;
using BinanceExchange.API.Converter;

namespace BinanceExchange.API.Models.Request
{
/// <summary>
/// Request object used to create a new Binance Isolated account order
/// </summary>
[DataContract]
public class CreateIsolatedOrderRequest : IRequest
{
[DataMember(Order = 1)]
[JsonProperty("symbol")]
public string Symbol { get; set; }

[DataMember(Order = 2)]
[JsonProperty("isIsolated")]
public string IsIsolated { get; set; }

[DataMember(Order = 3)]
[JsonProperty("side")]
[JsonConverter(typeof(StringEnumConverter))]
public OrderSide Side { get; set; }

[DataMember(Order = 4)]
[JsonProperty("type")]
[JsonConverter(typeof(StringEnumConverter))]
public OrderType Type { get; set; }

[DataMember(Order = 5)]
[JsonProperty("quantity")]
[JsonConverter(typeof(StringDecimalConverter))]
public decimal Quantity { get; set; }

[DataMember(Order = 6)]
[JsonProperty("timeInForce")]
[JsonConverter(typeof(StringEnumConverter))]
public TimeInForce? TimeInForce { get; set; }

[DataMember(Order = 7)]
[JsonProperty("price")]
[JsonConverter(typeof(StringDecimalConverter))]
public decimal? Price { get; set; }

[DataMember(Order = 8)]
[JsonProperty("newClientOrderId")]
public string NewClientOrderId { get; set; }

[DataMember(Order = 9)]
[JsonProperty("stopPrice")]
[JsonConverter(typeof(StringDecimalConverter))]
public decimal? StopPrice { get; set; }

[DataMember(Order = 10)]
[JsonProperty("icebergQty")]
[JsonConverter(typeof(StringDecimalConverter))]
public decimal? IcebergQuantity { get; set; }

[DataMember(Order = 11)]
[JsonProperty("newOrderRespType")]
[JsonConverter(typeof(StringEnumConverter))]
public NewOrderResponseType? NewOrderResponseType { get; set; }

[DataMember(Order = 12)]
[JsonProperty("sideEffectType")]
[JsonConverter(typeof(StringEnumConverter))]
public SideEffectType? SideEffectType { get; set; }

[DataMember(Order = 13)]
[JsonProperty("recvWindow")]
public long? RecvWindow { get; set; }

[DataMember(Order = 14)]
[JsonProperty("timeStamp")]
public long TimeStamp { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using BinanceExchange.API.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;
using BinanceExchange.API.Models.Request.Interfaces;
using BinanceExchange.API.Converter;

namespace BinanceExchange.API.Models.Request
{
/// <summary>
/// Request object used to query Binance Isolated account info
/// </summary>
[DataContract]
public class IsolatedMarginAccountInfoRequest : IRequest
{
[DataMember(Order = 1)]
[JsonProperty("symbols")]
public string Symbols { get; set; }

[DataMember(Order = 2)]
[JsonProperty("recvWindow")]
public long? RecvWindow { get; set; }

[DataMember(Order = 3)]
[JsonProperty("timeStamp")]
public long TimeStamp { get; set; }
}
}
32 changes: 32 additions & 0 deletions BinanceExchange.API/Models/Request/MaxBorrowRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using BinanceExchange.API.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;
using BinanceExchange.API.Models.Request.Interfaces;
using BinanceExchange.API.Converter;

namespace BinanceExchange.API.Models.Request
{
/// <summary>
/// Request object used to query the accoun't max borrow
/// </summary>
[DataContract]
public class MaxBorrowRequest : IRequest
{
[DataMember(Order = 1)]
[JsonProperty("asset")]
public string Asset { get; set; }

[DataMember(Order = 2)]
[JsonProperty("isolatedSymbol")]
public string IsolatedSymbol { get; set; }

[DataMember(Order = 3)]
[JsonProperty("recvWindow")]
public long? RecvWindow { get; set; }

[DataMember(Order = 4)]
[JsonProperty("timeStamp")]
public long TimeStamp { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
using BinanceExchange.API.Models.Response.Interfaces;

namespace BinanceExchange.API.Models.Response
{
/// <summary>
/// Balance respomse providing information on assets
/// </summary>
[DataContract]
public class AssetType
{
[DataMember]
public string asset { get; set; }
[DataMember]
public bool borrowEnabled { get; set; }
[DataMember]
public long borrowed { get; set; }
[DataMember]
public decimal free { get; set; }
[DataMember]
public long interest { get; set; }
[DataMember]
public long locked { get; set; }
[DataMember]
public decimal netAsset { get; set; }
[DataMember]
public decimal netAssetOfBtc { get; set; }
[DataMember]
public bool repayEnabled { get; set; }
[DataMember]
public decimal totalAsset { get; set; }
}

[DataContract]
public class AssetResponse
{
[DataMember]
public AssetType baseAsset { get; set; }
[DataMember]
public AssetType quoteAsset { get; set; }
[DataMember]
public string symbol { get; set; }
[DataMember]
public bool isolatedCreated { get; set; }
[DataMember]
public long marginLevel { get; set; }
[DataMember]
public string marginLevelStatus { get; set; }
[DataMember]
public long marginRatio { get; set; }
[DataMember]
public decimal indexPrice { get; set; }
[DataMember]
public decimal liquidatePrice { get; set; }
[DataMember]
public decimal liquidateRate { get; set; }
[DataMember]
public bool tradeEnabled { get; set; }
[DataMember]
public bool enabled { get; set; }
}

/// <summary>
/// Balance respomse providing information on assets
/// </summary>
[DataContract]
public class IsolatedMarginAccountInfoResponse
{
[DataMember(Order = 1)]
public List<AssetResponse> assets { get; set; }
}
}
18 changes: 18 additions & 0 deletions BinanceExchange.API/Models/Response/MaxBorrowResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Runtime.Serialization;
using BinanceExchange.API.Models.Response.Interfaces;

namespace BinanceExchange.API.Models.Response
{
/// <summary>
/// Balance respomse providing information on assets
/// </summary>
[DataContract]
public class MaxBorrowResponse
{
[DataMember(Order = 1)]
public decimal amount { get; set; }

[DataMember(Order = 2)]
public decimal borrowLimit { get; set; }
}
}
Loading