Skip to content

Commit 1cfebf0

Browse files
authored
Merge pull request #6 from codez0mb1e/develop
Migrate to Binance.Net nuget-package
2 parents 35b92ba + 35b4c0d commit 1cfebf0

64 files changed

Lines changed: 179 additions & 2038 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/BinanceBot.Market/BaseMarketBot.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Threading.Tasks;
4-
using BinanceExchange.API.Models.Request;
5-
using BinanceExchange.API.Models.Response;
4+
using Binance.Net.Objects.Spot.SpotData;
65
using NLog;
76

87
namespace BinanceBot.Market
@@ -17,6 +16,8 @@ public abstract class BaseMarketBot<TStrategy> :
1716
{
1817
protected readonly Logger Logger;
1918

19+
protected readonly TStrategy MarketStrategy;
20+
2021

2122
protected BaseMarketBot(string symbol, TStrategy marketStrategy, Logger logger)
2223
{
@@ -28,20 +29,18 @@ protected BaseMarketBot(string symbol, TStrategy marketStrategy, Logger logger)
2829

2930
public string Symbol { get; }
3031

31-
public TStrategy MarketStrategy { get; }
32-
3332

3433
public abstract Task RunAsync();
3534

3635
public abstract void Stop();
3736

3837
public abstract Task ValidateConnectionAsync();
3938

40-
public abstract Task<IEnumerable<OrderResponse>> GetOpenedOrdersAsync(string symbol);
39+
public abstract Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol);
4140

42-
public abstract Task CancelOrdersAsync(IEnumerable<OrderResponse> orders);
41+
public abstract Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders);
4342

44-
public abstract Task<BaseCreateOrderResponse> CreateOrderAsync(CreateOrderRequest order);
43+
public abstract Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order);
4544

4645

4746
public abstract void Dispose();

src/BinanceBot.Market/BinanceBot.Market.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.1</TargetFramework>
5-
<LangVersion>8.0</LangVersion>
5+
<LangVersion>9.0</LangVersion>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<ProjectReference Include="..\BinanceDotNet.BinanceExchange.API\BinanceDotNet.BinanceExchange.API.csproj" />
9+
<PackageReference Include="Binance.Net" Version="7.2.1" />
10+
<PackageReference Include="NLog" Version="4.7.11" />
1011
</ItemGroup>
1112

1213
</Project>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Binance.Net.Enums;
2+
3+
namespace BinanceBot.Market
4+
{
5+
/// <summary>
6+
/// Request object used to create a new Binance order
7+
/// </summary>
8+
public class CreateOrderRequest
9+
{
10+
public string Symbol { get; set; }
11+
12+
public OrderSide Side { get; set; }
13+
14+
public OrderType Type { get; set; }
15+
16+
public TimeInForce? TimeInForce { get; set; }
17+
18+
public decimal Quantity { get; set; }
19+
20+
public decimal? Price { get; set; }
21+
22+
public string NewClientOrderId { get; set; }
23+
24+
public decimal? StopPrice { get; set; }
25+
26+
public decimal? IcebergQuantity { get; set; }
27+
public int? RecvWindow { get; set; }
28+
}
29+
}

src/BinanceBot.Market/IMarketBot.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System.Collections.Generic;
22
using System.Threading.Tasks;
3-
4-
using BinanceExchange.API.Models.Request;
5-
using BinanceExchange.API.Models.Response;
3+
using Binance.Net.Objects.Spot.SpotData;
64

75

86
namespace BinanceBot.Market
@@ -38,18 +36,18 @@ public interface IMarketBot
3836
/// Get currently opened orders
3937
/// </summary>
4038
/// <param name="symbol"></param>
41-
Task<IEnumerable<OrderResponse>> GetOpenedOrdersAsync(string symbol);
39+
Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol);
4240

4341
/// <summary>
4442
/// Create new order
4543
/// </summary>
4644
/// <param name="order"></param>
47-
Task<BaseCreateOrderResponse> CreateOrderAsync(CreateOrderRequest order);
45+
Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order);
4846

4947
/// <summary>
5048
/// Cancel orders
5149
/// </summary>
5250
/// <param name="orders"></param>
53-
Task CancelOrdersAsync(IEnumerable<OrderResponse> orders);
51+
Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders);
5452
}
5553
}

src/BinanceBot.Market/MarketDepth.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using Binance.Net.Enums;
5+
using Binance.Net.Objects;
46
using BinanceBot.Market.Utility;
5-
using BinanceExchange.API.Enums;
6-
using BinanceExchange.API.Models.Response;
7+
78

89
namespace BinanceBot.Market
910
{
@@ -76,7 +77,7 @@ public MarketDepth(string symbol)
7677
/// <summary>
7778
/// Update market depth
7879
/// </summary>
79-
public void UpdateDepth(IEnumerable<TradeResponse> asks, IEnumerable<TradeResponse> bids, long updateTime)
80+
public void UpdateDepth(IEnumerable<BinanceOrderBookEntry> asks, IEnumerable<BinanceOrderBookEntry> bids, long updateTime)
8081
{
8182
if (updateTime <= 0)
8283
throw new ArgumentOutOfRangeException(nameof(updateTime));
@@ -86,11 +87,11 @@ public void UpdateDepth(IEnumerable<TradeResponse> asks, IEnumerable<TradeRespon
8687
if (asks == null && bids == null) return;
8788

8889

89-
void UpdateOrderBook(IEnumerable<TradeResponse> updates, IDictionary<decimal, decimal> orders)
90+
void UpdateOrderBook(IEnumerable<BinanceOrderBookEntry> updates, IDictionary<decimal, decimal> orders)
9091
{
9192
if (updates != null)
9293
{
93-
foreach (TradeResponse t in updates)
94+
foreach (BinanceOrderBookEntry t in updates)
9495
{
9596
if (t.Quantity != IgnoreVolumeValue)
9697
orders[t.Price] = t.Quantity;

src/BinanceBot.Market/MarketDepthManager.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System;
22
using System.Threading.Tasks;
3-
using BinanceExchange.API.Client;
4-
using BinanceExchange.API.Models.Response;
5-
using BinanceExchange.API.Websockets;
3+
using Binance.Net.Interfaces;
4+
using Binance.Net.Objects.Spot.MarketData;
5+
using CryptoExchange.Net.Objects;
6+
67

78
namespace BinanceBot.Market
89
{
@@ -25,8 +26,8 @@ namespace BinanceBot.Market
2526
/// </remarks>
2627
public class MarketDepthManager
2728
{
28-
private readonly IBinanceRestClient _restClient;
29-
private readonly IBinanceWebSocketClient _webSocketClient;
29+
private readonly IBinanceClient _restClient;
30+
private readonly IBinanceSocketClient _webSocketClient;
3031

3132

3233
/// <summary>
@@ -36,7 +37,7 @@ public class MarketDepthManager
3637
/// <param name="webSocketClient">Binance WebSocket client</param>
3738
/// <exception cref="ArgumentNullException"><paramref name="binanceRestClient"/> cannot be <see langword="null"/></exception>
3839
/// <exception cref="ArgumentNullException"><paramref name="webSocketClient"/> cannot be <see langword="null"/></exception>
39-
public MarketDepthManager(IBinanceRestClient binanceRestClient, IBinanceWebSocketClient webSocketClient)
40+
public MarketDepthManager(IBinanceClient binanceRestClient, IBinanceSocketClient webSocketClient)
4041
{
4142
_restClient = binanceRestClient ?? throw new ArgumentNullException(nameof(binanceRestClient));
4243
_webSocketClient = webSocketClient ?? throw new ArgumentNullException(nameof(webSocketClient));
@@ -55,7 +56,8 @@ public async Task BuildAsync(MarketDepth marketDepth, int limit = 100)
5556
if (limit <= 0)
5657
throw new ArgumentOutOfRangeException(nameof(limit));
5758

58-
OrderBookResponse orderBook = await _restClient.GetOrderBookAsync(marketDepth.Symbol, false, limit);
59+
WebCallResult<BinanceOrderBook> response = await _restClient.Spot.Market.GetOrderBookAsync(marketDepth.Symbol, limit);
60+
BinanceOrderBook orderBook = response.Data;
5961

6062
marketDepth.UpdateDepth(orderBook.Asks, orderBook.Bids, orderBook.LastUpdateId);
6163
}
@@ -70,9 +72,10 @@ public void StreamUpdates(MarketDepth marketDepth)
7072
if (marketDepth == null)
7173
throw new ArgumentNullException(nameof(marketDepth));
7274

73-
_webSocketClient.ConnectToDepthWebSocket(
75+
_webSocketClient.Spot.SubscribeToOrderBookUpdatesAsync(
7476
marketDepth.Symbol,
75-
marketData => marketDepth.UpdateDepth(marketData.AskDepthDeltas, marketData.BidDepthDeltas, marketData.UpdateId));
77+
1000,
78+
marketData => marketDepth.UpdateDepth(marketData.Data.Asks, marketData.Data.Bids, marketData.Data.LastUpdateId));
7679
}
7780
}
7881
}

src/BinanceBot.Market/MarketMakerBot.cs

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
// Create test order flag. See more: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#test-new-order-trade
2-
#define TEST_ORDER_CREATION_MODE
1+
#define TEST_ORDER_CREATION_MODE // Test order flag. See details: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#test-new-order-trade
32

43
using System;
54
using System.Collections.Generic;
65
using System.Threading.Tasks;
7-
8-
using BinanceExchange.API.Client;
9-
using BinanceExchange.API.Enums;
10-
using BinanceExchange.API.Models.Request;
11-
using BinanceExchange.API.Models.Response;
12-
using BinanceExchange.API.Websockets;
13-
6+
using Binance.Net.Enums;
7+
using Binance.Net.Interfaces;
8+
using Binance.Net.Objects.Spot.SpotData;
9+
using CryptoExchange.Net.Objects;
1410
using NLog;
1511

1612

@@ -21,8 +17,8 @@ namespace BinanceBot.Market
2117
/// </summary>
2218
public class MarketMakerBot : BaseMarketBot<NaiveMarketMakerStrategy>
2319
{
24-
private readonly IBinanceRestClient _binanceRestClient;
25-
private readonly IBinanceWebSocketClient _webSocketClient;
20+
private readonly IBinanceClient _binanceRestClient;
21+
private readonly IBinanceSocketClient _webSocketClient;
2622
private readonly MarketDepth _marketDepth;
2723

2824

@@ -38,8 +34,8 @@ public class MarketMakerBot : BaseMarketBot<NaiveMarketMakerStrategy>
3834
public MarketMakerBot(
3935
string symbol,
4036
NaiveMarketMakerStrategy marketStrategy,
41-
IBinanceRestClient binanceRestClient,
42-
IBinanceWebSocketClient webSocketClient,
37+
IBinanceClient binanceRestClient,
38+
IBinanceSocketClient webSocketClient,
4339
Logger logger) :
4440
base(symbol, marketStrategy, logger)
4541
{
@@ -53,43 +49,60 @@ public MarketMakerBot(
5349
public override async Task ValidateConnectionAsync()
5450
{
5551
Logger.Info("Testing connection...");
56-
IResponse testConnectResponse = await _binanceRestClient.TestConnectivityAsync();
57-
if (testConnectResponse != null)
52+
53+
CallResult<long> testConnectResponse = await _binanceRestClient.PingAsync().ConfigureAwait(false);
54+
55+
if (testConnectResponse.Error != null)
56+
Logger.Error(testConnectResponse.Error.Message);
57+
else
5858
{
59-
ServerTimeResponse serverTimeResponse = await _binanceRestClient.GetServerTimeAsync();
60-
Logger.Info($"Connection was established successfully. Approximate ping time: {DateTime.UtcNow.Subtract(serverTimeResponse.ServerTime).TotalMilliseconds:F0} ms");
59+
DateTime serverTimeResponse = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
60+
.AddMilliseconds(testConnectResponse.Data/10.0)
61+
.ToLocalTime();
62+
63+
Logger.Info($"Connection was established successfully. Approximate ping time: {DateTime.UtcNow.Subtract(serverTimeResponse).TotalMilliseconds:F0} ms");
6164
}
6265
}
6366

6467

65-
public override async Task<IEnumerable<OrderResponse>> GetOpenedOrdersAsync(string symbol)
68+
public override async Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol)
6669
{
6770
if (string.IsNullOrEmpty(symbol))
6871
throw new ArgumentException("Invalid symbol value", nameof(symbol));
6972

70-
return await _binanceRestClient.GetCurrentOpenOrdersAsync(new CurrentOpenOrdersRequest { Symbol = symbol });
73+
var response = await _binanceRestClient.Spot.Order.GetOpenOrdersAsync(symbol).ConfigureAwait(false);
74+
return response.Data;
7175
}
7276

7377

74-
public override async Task CancelOrdersAsync(IEnumerable<OrderResponse> orders)
78+
public override async Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders)
7579
{
7680
if (orders == null)
7781
throw new ArgumentNullException(nameof(orders));
7882

79-
foreach (OrderResponse order in orders)
80-
await _binanceRestClient.CancelOrderAsync(new CancelOrderRequest { OrderId = order.OrderId, OriginalClientOrderId = order.ClientOrderId, Symbol = order.Symbol });
83+
foreach (var order in orders)
84+
await _binanceRestClient.Spot.Order.CancelOrderAsync(orderId: order.OrderId, origClientOrderId: order.ClientOrderId, symbol: order.Symbol).ConfigureAwait(false);
8185
}
8286

8387

84-
public override async Task<BaseCreateOrderResponse> CreateOrderAsync(CreateOrderRequest order)
88+
public override async Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order)
8589
{
8690

8791
#if TEST_ORDER_CREATION_MODE
88-
EmptyResponse response = await _binanceRestClient.CreateTestOrderAsync(order);
89-
return response != null ? new AcknowledgeCreateOrderResponse() : null;
92+
WebCallResult<BinancePlacedOrder> response = await _binanceRestClient.Spot.Order.PlaceTestOrderAsync(
93+
order.Symbol, order.Side, order.Type, order.Quantity,
94+
newClientOrderId:order.NewClientOrderId,
95+
receiveWindow:order.RecvWindow)
96+
.ConfigureAwait(false);
9097
#else
91-
return await _binanceRestClient.CreateOrderAsync(order);
98+
WebCallResult<BinancePlacedOrder> response = await _binanceRestClient.Spot.Order.PlaceOrderAsync(
99+
order.Symbol, order.Side, order.Type, order.Quantity,
100+
newClientOrderId: order.NewClientOrderId,
101+
receiveWindow: order.RecvWindow)
102+
.ConfigureAwait(false);
92103
#endif
104+
105+
return response.Data;
93106
}
94107

95108

@@ -122,7 +135,7 @@ private async Task OnMarketBestPairChanged(object sender, MarketBestPairChangedE
122135
var openOrdersResponse = await GetOpenedOrdersAsync(Symbol);
123136

124137
// cancel already opened orders (if necessary)
125-
await CancelOrdersAsync(openOrdersResponse);
138+
if (openOrdersResponse != null) await CancelOrdersAsync(openOrdersResponse);
126139

127140
// find new market position
128141
Quote q = MarketStrategy.Process(e.MarketBestPair);
@@ -136,7 +149,7 @@ private async Task OnMarketBestPairChanged(object sender, MarketBestPairChangedE
136149
Price = q.Price,
137150
Side = q.Direction,
138151
Type = OrderType.Limit,
139-
TimeInForce = TimeInForce.GTC // 'Good Till Cancelled' marketStrategy
152+
TimeInForce = TimeInForce.GoodTillCancel // 'Good Till Cancelled' marketStrategy
140153
};
141154

142155
await CreateOrderAsync(newOrderRequest);

src/BinanceBot.Market/NaiveMarketMakerStrategy.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using BinanceExchange.API.Enums;
2+
using Binance.Net.Enums;
33
using NLog;
44

55

@@ -41,7 +41,7 @@ public Quote Process(MarketDepthPair marketPair)
4141
_logger.Info($"Best ask / bid: {marketPair.Ask.Price} / {marketPair.Bid.Price}. Update Id: {marketPair.UpdateTime}.");
4242

4343
// get price spreads (in percent)
44-
decimal actualSpread = marketPair.PriceSpread.Value / marketPair.MediumPrice.Value * 100; // spread_relative = spread_absolute/price * 100
44+
decimal actualSpread = marketPair.PriceSpread!.Value / marketPair.MediumPrice!.Value * 100; // spread_relative = spread_absolute/price * 100
4545
decimal expectedSpread = _marketStrategyConfig.TradeWhenSpreadGreaterThan;
4646

4747
_logger.Info($"Spread absolute / relative: {marketPair.PriceSpread} / {actualSpread:F3}%. Update Id: {marketPair.UpdateTime}.");
@@ -54,13 +54,10 @@ public Quote Process(MarketDepthPair marketPair)
5454
decimal orderPrice = marketPair.Bid.Price + extra; // new_price = best_bid + extra
5555

5656
// compute order volume
57-
decimal volumeSpread = marketPair.VolumeSpread.Value;
58-
decimal orderVolume = volumeSpread > _marketStrategyConfig.MaxOrderVolume
59-
? _marketStrategyConfig.MaxOrderVolume // set max volume
60-
: (volumeSpread < _marketStrategyConfig.MinOrderVolume
61-
? _marketStrategyConfig.MinOrderVolume // set min volume
62-
: volumeSpread);
63-
57+
decimal volumeSpread = marketPair.VolumeSpread!.Value;
58+
decimal orderVolume = volumeSpread > _marketStrategyConfig.MaxOrderVolume ?
59+
_marketStrategyConfig.MaxOrderVolume : // set max volume
60+
(volumeSpread < _marketStrategyConfig.MinOrderVolume ? _marketStrategyConfig.MinOrderVolume : volumeSpread); // set min volume
6461

6562
// return new price-volume pair
6663
quote = new Quote(orderPrice, orderVolume, OrderSide.Buy);

src/BinanceBot.Market/Quote.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using BinanceExchange.API.Enums;
2+
using Binance.Net.Enums;
33

44
namespace BinanceBot.Market
55
{

src/BinanceBot.Market/Utility/QuoteExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3-
using BinanceExchange.API.Enums;
3+
using Binance.Net.Enums;
44

55
namespace BinanceBot.Market.Utility
66
{

0 commit comments

Comments
 (0)