using Binance.Net.Clients; using Binance.Net.Objects; using Binance.TradeRobot.Model.Base; using CryptoExchange.Net.Authentication; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Threading; namespace SDKAdapter.WebSockets.Order.SpotOrder { public class BinanceSpotOrderWebSocketClient : SpotOrderWebSocketClient { private BinanceSocketClient binanceSocketClient; private BinanceClient binanceClient; private CancellationTokenSource cancellationTokenSource; private string listenKey; private IList unSupportStateList; public BinanceSpotOrderWebSocketClient(Enums.BusinessType businessType, long accountId, string apiKey, string secret, NLog.ILogger logger) : base(businessType, accountId, apiKey, secret, logger) { var spotClientOption = new BinanceApiClientOptions() { BaseAddress = "https://api.binance.com", ApiCredentials = new ApiCredentials(apiKey, secret) }; //var usdFuturesClientOption = new BinanceApiClientOptions() //{ // BaseAddress = "https://fapi.binance.com", // ApiCredentials = new ApiCredentials(apiKey, secret) //}; binanceClient = new BinanceClient(new BinanceClientOptions() { //UsdFuturesApiOptions = usdFuturesClientOption, SpotApiOptions = spotClientOption }); binanceSocketClient = new BinanceSocketClient(); listenKey = string.Empty; unSupportStateList = new List() { Binance.Net.Enums.OrderStatus.PendingCancel, Binance.Net.Enums.OrderStatus.Insurance, Binance.Net.Enums.OrderStatus.Adl }; } public override void Start(string symbol = "") { if (IsConnected) return; IsConnected = true; cancellationTokenSource = new CancellationTokenSource(); var getListenKeyResponse = binanceClient.SpotApi.Account.StartIsolatedMarginUserStreamAsync(symbol).Result; if (!getListenKeyResponse.Success) throw new Exception(getListenKeyResponse.Error?.Message ?? ""); listenKey = getListenKeyResponse.Data; binanceSocketClient.SpotStreams.SubscribeToUserDataUpdatesAsync(listenKey, (e) => { logger.Info(JsonConvert.SerializeObject(e.Data)); if (unSupportStateList.Contains(e.Data.Status)) return; OnOrderUpdated?.Invoke(new Model.SpotOrderTradePublishInfo() { OrderId = e.Data.Id, Symbol = e.Data.Symbol, AccountId = this.AccountId, OrderType = (Enums.OrderType)(int)e.Data.Type, SpotOrderState = (Enums.SpotOrderState)(int)e.Data.Status, TradeDirection = (Enums.TradeDirection)(int)e.Data.Side, ClientOrderId = e.Data.ClientOrderId, CummulativeTradeAmount = e.Data.QuoteQuantityFilled, CummulativeTradeQuantity = e.Data.QuantityFilled, Exchange = Enums.Exchange.Binance, Fee = e.Data.Fee, FeeUnit = e.Data.FeeAsset, LastTradeAmount = e.Data.LastQuoteQuantity, LastTradePrice = e.Data.LastPriceFilled, LastTradeQuantity = e.Data.LastQuantityFilled, LastTradeTime = e.Data.UpdateTime, CreateTime = e.Data.CreateTime }); }, (e) => { }, (e) => { }, (e) => { }, cancellationTokenSource.Token); } public override void Stop(string symbol = "") { if (!IsConnected) return; IsConnected = false; cancellationTokenSource.Cancel(); binanceSocketClient.SpotStreams.Dispose(); cancellationTokenSource = null; _ = binanceClient.SpotApi.Account.CloseIsolatedMarginUserStreamAsync(symbol, listenKey).Result; listenKey = string.Empty; } } }