private static async Task SendSubscriptionRequests(BitmexWebsocketClient client) { client.Send(new PingRequest()); if (!string.IsNullOrWhiteSpace(AccessKeys.bitmexSecret)) { client.Send(new AuthenticationRequest(AccessKeys.bitmexKey, AccessKeys.bitmexSecret)); } }
/// <summary> /// Send the requests for the subscriptions needed. /// </summary> /// <param name="client"></param> /// <param name="pair"></param> /// <param name="acc"></param> /// <returns></returns> private async Task SendSubscriptions(BitmexWebsocketClient client, string pair, MTAccount acc) { var appSettings = ConfigurationManager.AppSettings; string api, sec; if (acc == MTAccount.A) { if (_view.isTest) { api = appSettings["API_KEY_BITMEX_A_TEST"] ?? string.Empty; sec = appSettings["API_SECRET_BITMEX_A_TEST"] ?? string.Empty; } else { api = appSettings["API_KEY_BITMEX_A_LIVE"] ?? string.Empty; sec = appSettings["API_SECRET_BITMEX_A_LIVE"] ?? string.Empty; } // Trade stats //await client.Send(new TradesSubscribeRequest(pair)); // Bid and Ask await client.Send(new BookSubscribeRequest(pair)); } else { if (_view.isTest) { api = appSettings["API_KEY_BITMEX_B_TEST"] ?? string.Empty; sec = appSettings["API_SECRET_BITMEX_B_TEST"] ?? string.Empty; } else { api = appSettings["API_KEY_BITMEX_B_LIVE"] ?? string.Empty; sec = appSettings["API_SECRET_BITMEX_B_LIVE"] ?? string.Empty; } } if (!string.IsNullOrEmpty(api) && !string.IsNullOrEmpty(sec)) { await client.Send(new AuthenticationRequest(api, sec)); } await client.Send(new OrderSubscribeRequest()); await client.Send(new PositionSubscribeRequest()); await client.Send(new MarginSubscribeRequest()); //await client.Send(new ExecutionSubscribeRequest()); }
private static async Task SendSubscriptionRequests(BitmexWebsocketClient client) { await client.Send(new PingRequest()); //await client.Send(new BookSubscribeRequest()); await client.Send(new TradesSubscribeRequest("XBTUSD")); //await client.Send(new QuoteSubscribeRequest("XBTUSD")); await client.Send(new LiquidationSubscribeRequest()); if (!string.IsNullOrWhiteSpace(API_SECRET)) { await client.Send(new AuthenticationRequest(API_KEY, API_SECRET)); } }
private static async Task <ICryptoOrderBook> StartBitmex(string pair, bool optimized, bool l2Optimized) { var url = BitmexValues.ApiWebsocketUrl; var communicator = new BitmexWebsocketCommunicator(url) { Name = "Bitmex" }; var client = new BitmexWebsocketClient(communicator); var source = new BitmexOrderBookSource(client); var orderBook = l2Optimized ? new CryptoOrderBookL2(pair, source) : (ICryptoOrderBook) new CryptoOrderBook(pair, source); if (optimized) { ConfigureOptimized(source, orderBook); } _ = communicator.Start(); // Send subscription request to order book data client.Send(new Bitmex.Client.Websocket.Requests.BookSubscribeRequest(pair)); return(orderBook); }
public async Task ConnectToSource_ShouldHandleOrderBookCorrectly() { var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { using (var client = new BitmexWebsocketClient(communicator)) { var pair = "XBTUSD"; var source = new BitmexOrderBookSource(client); var orderBook = new CryptoOrderBook(pair, source); await communicator.Start(); client.Send(new BookSubscribeRequest(pair)); await Task.Delay(TimeSpan.FromSeconds(10)); Assert.True(orderBook.BidPrice > 0); Assert.True(orderBook.AskPrice > 0); Assert.NotEmpty(orderBook.BidLevels); Assert.NotEmpty(orderBook.AskLevels); } } }
public async Task PingPong() { var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { PongResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.PongStream.Subscribe(pong => { received = pong; receivedEvent.Set(); }); await communicator.Start(); await client.Send(new PingRequest()); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); } } }
private void StartPingCheck(BitmexWebsocketClient client) { _pingSubscription = Observable .Interval(TimeSpan.FromSeconds(5)) .Subscribe(async x => { _pingRequest = DateTime.UtcNow; await client.Send(new PingRequest()); }); }
private static async Task <ICryptoOrders> StartBitmex(bool isTestnet, Action <CryptoOrder> handler, Action <CryptoWallet[]> walletHandler, Action <CryptoPosition[]> positionHandler) { var url = isTestnet ? BitmexValues.ApiWebsocketTestnetUrl : BitmexValues.ApiWebsocketUrl; var communicator = new BitmexWebsocketCommunicator(url) { Name = "Bitmex" }; var client = new BitmexWebsocketClient(communicator); var source = new BitmexOrderSource(client); var orders = new CryptoOrders(source); orders.OrderChangedStream.Subscribe(handler); var walletSource = new BitmexWalletSource(client); walletSource.WalletChangedStream.Subscribe(walletHandler); var positionSource = new BitmexPositionSource(client); positionSource.PositionsStream.Subscribe(positionHandler); client.Streams.AuthenticationStream.Subscribe(x => { Log.Information($"[Bitmex] Authenticated '{x.Success}'"); client.Send(new Bitmex.Client.Websocket.Requests.WalletSubscribeRequest()); client.Send(new Bitmex.Client.Websocket.Requests.MarginSubscribeRequest()); client.Send(new Bitmex.Client.Websocket.Requests.PositionSubscribeRequest()); client.Send(new Bitmex.Client.Websocket.Requests.OrderSubscribeRequest()); }); communicator.ReconnectionHappened.Subscribe(x => { client.Authenticate(API_KEY, API_SECRET); }); await communicator.Start(); return(orders); }
private static async Task SendSubscriptionRequests(BitmexWebsocketClient client) { await client.Send(new PingRequest()); //await client.Send(new BookSubscribeRequest(MainClass.pair)); //await client.Send(new TradesSubscribeRequest(MainClass.pair)); await client.Send(new TradeBinSubscribeRequest("1m", MainClass.pair)); await client.Send(new TradeBinSubscribeRequest("5m", MainClass.pair)); await client.Send(new TradeBinSubscribeRequest("1h", MainClass.pair)); //await client.Send(new InstrumentSubscribeRequest(MainClass.pair)); await client.Send(new QuoteSubscribeRequest(MainClass.pair)); //await client.Send(new LiquidationSubscribeRequest()); //if (!string.IsNullOrWhiteSpace(MainClass.bitmexKeyWebSocket)) //await client.Send(new AuthenticationRequest(MainClass.bitmexKeyWebSocket, MainClass.bitmexSecretWebSocket)); }
private static (ITradeSource, IWebsocketClient) GetBitmex(string pair, bool isTestnet) { var url = isTestnet ? BitmexValues.ApiWebsocketTestnetUrl : BitmexValues.ApiWebsocketUrl; var communicator = new BitmexWebsocketCommunicator(url) { Name = "Bitmex" }; var client = new BitmexWebsocketClient(communicator); var source = new BitmexTradeSource(client); communicator.ReconnectionHappened.Subscribe(x => { client.Send(new Bitmex.Client.Websocket.Requests.TradesSubscribeRequest(pair)); }); return(source, communicator); }
public static void run() { int failed = 0; while (true) { try { var url = new Uri(wsURl); using (var connector = new BitmexWebsocketCommunicator(url)) { using (var client = new BitmexWebsocketClient(connector)) { client.Streams.InfoStream.Subscribe(info => { Console.WriteLine($"Info received, reconnection happened."); client.Send(new PingRequest()).Wait(); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); connector.Start(); ExitEvent.WaitOne(); } } } catch (Exception e) { MainClass.log("WebSocket crashed due to: " + e.Message + e.StackTrace, ConsoleColor.White, "error"); if (failed >= MainClass.maxWebsocketsFail) { MainClass.log("Reverting to standard rest api calls...", ConsoleColor.Red); MainClass.useWebSockets = false; Thread.CurrentThread.Abort(); } MainClass.log("Waiting 1s before restarting!", ConsoleColor.Red); Thread.Sleep(1000); failed++; } } }
private static void SendSubscriptionRequests(BitmexWebsocketClient client) { client.Send(new PingRequest()); //client.Send(new BookSubscribeRequest("XBTUSD")); client.Send(new TradesSubscribeRequest("XBTUSD")); //client.Send(new TradeBinSubscribeRequest("1m", "XBTUSD")); //client.Send(new TradeBinSubscribeRequest("5m", "XBTUSD")); client.Send(new QuoteSubscribeRequest("XBTUSD")); client.Send(new LiquidationSubscribeRequest()); client.Send(new InstrumentSubscribeRequest("XBTUSD")); client.Send(new FundingsSubscribeRequest("XBTUSD")); //client.Send(new Book25SubscribeRequest("XBTUSD")); //client.Send(new Book10SubscribeRequest("XBTUSD")); if (!string.IsNullOrWhiteSpace(API_SECRET)) { client.Send(new AuthenticationRequest(API_KEY, API_SECRET)); } }
public async Task ConnectToSource_ShouldHandleOrderBookOneByOne() { var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { using (var client = new BitmexWebsocketClient(communicator)) { var pair = "XBTUSD"; var called = 0; var source = new BitmexOrderBookSource(client); var orderBook = new CryptoOrderBook(pair, source) { DebugEnabled = true }; orderBook.OrderBookUpdatedStream.Subscribe(x => { called++; Thread.Sleep(2000); }); await communicator.Start(); client.Send(new BookSubscribeRequest(pair)); await Task.Delay(TimeSpan.FromSeconds(5)); Assert.Equal(2, called); await Task.Delay(TimeSpan.FromSeconds(2)); Assert.Equal(3, called); } } }
private async Task SendSubscriptions(BitmexWebsocketClient client, string pair) { await client.Send(new TradesSubscribeRequest(pair)); await client.Send(new BookSubscribeRequest(pair)); }
private static void SubscribeToStreams(BitmexWebsocketClient client) { client.Streams.ErrorStream.Subscribe(x => Log.Warning($"Error received, message: {x.Error}, status: {x.Status}")); client.Streams.AuthenticationStream.Subscribe(x => { Log.Information($"Authentication happened, success: {x.Success}"); client.Send(new WalletSubscribeRequest()).Wait(); client.Send(new OrderSubscribeRequest()).Wait(); client.Send(new PositionSubscribeRequest()).Wait(); }); client.Streams.SubscribeStream.Subscribe(x => Log.Information($"Subscribed ({x.Success}) to {x.Subscribe}")); client.Streams.PongStream.Subscribe(x => Log.Information($"Pong received ({x.Message})")); client.Streams.WalletStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Wallet {x.Account}, {x.Currency} amount: {x.BalanceBtc}")) ); client.Streams.OrderStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Order {x.Symbol} updated. Time: {x.Timestamp:HH:mm:ss.fff}, Amount: {x.OrderQty}, " + $"Price: {x.Price}, Direction: {x.Side}, Working: {x.WorkingIndicator}, Status: {x.OrdStatus}")) ); client.Streams.PositionStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Position {x.Symbol}, {x.Currency} updated. Time: {x.Timestamp:HH:mm:ss.fff}, Amount: {x.CurrentQty}, " + $"Price: {x.LastPrice}, PNL: {x.UnrealisedPnl}")) ); client.Streams.TradesStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Trade {x.Symbol} executed. Time: {x.Timestamp:mm:ss.fff}, [{x.Side}] Amount: {x.Size}, " + $"Price: {x.Price}")) ); client.Streams.BookStream.Subscribe(book => book.Data.Take(100).ToList().ForEach(x => Log.Information( $"Book | {book.Action} pair: {x.Symbol}, price: {x.Price}, amount {x.Size}, side: {x.Side}")) ); client.Streams.QuoteStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Quote {x.Symbol}. Bid: {x.BidPrice} - {x.BidSize} Ask: {x.AskPrice} - {x.AskSize}")) ); client.Streams.LiquidationStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Liquadation Action: {y.Action}, OrderID: {x.OrderID}, Symbol: {x.Symbol}, Side: {x.Side}, Price: {x.Price}, LeavesQty: {x.leavesQty}")) ); client.Streams.TradeBinStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"TradeBin table:{y.Table} {x.Symbol} executed. Time: {x.Timestamp:mm:ss.fff}, Open: {x.Open}, " + $"Close: {x.Close}, Volume: {x.Volume}, Trades: {x.Trades}")) ); }
private static void SubscribeToStreams(BitmexWebsocketClient client) { client.Streams.ErrorStream.Subscribe(x => Log.Warning($"Error received, message: {x.Error}, status: {x.Status}")); client.Streams.AuthenticationStream.Subscribe(x => { Log.Information($"Authentication happened, success: {x.Success}"); client.Send(new WalletSubscribeRequest()).Wait(); client.Send(new OrderSubscribeRequest()).Wait(); client.Send(new PositionSubscribeRequest()).Wait(); }); client.Streams.SubscribeStream.Subscribe(x => { Log.Information(x.IsSubscription ? $"Subscribed ({x.Success}) to {x.Subscribe}" : $"Unsubscribed ({x.Success}) from {x.Unsubscribe}"); }); client.Streams.PongStream.Subscribe(x => Log.Information($"Pong received ({x.Message})")); client.Streams.WalletStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Wallet {x.Account}, {x.Currency} amount: {x.BalanceBtc}")) ); client.Streams.OrderStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Order {x.Symbol} updated. Time: {x.Timestamp:HH:mm:ss.fff}, Amount: {x.OrderQty}, " + $"Price: {x.Price}, Direction: {x.Side}, Working: {x.WorkingIndicator}, Status: {x.OrdStatus}")) ); client.Streams.PositionStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Position {x.Symbol}, {x.Currency} updated. Time: {x.Timestamp:HH:mm:ss.fff}, Amount: {x.CurrentQty}, " + $"Price: {x.LastPrice}, PNL: {x.UnrealisedPnl}")) ); client.Streams.TradesStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Trade {x.Symbol} executed. Time: {x.Timestamp:HH:mm:ss.fff}, [{x.Side}] Amount: {x.Size}, " + $"Price: {x.Price}")) ); client.Streams.BookStream.Subscribe(book => book.Data.Take(100).ToList().ForEach(x => Log.Information( $"Book | {book.Action} pair: {x.Symbol}, price: {x.Price}, amount {x.Size}, side: {x.Side}")) ); client.Streams.QuoteStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Quote {x.Symbol}. Bid: {x.BidPrice} - {x.BidSize} Ask: {x.AskPrice} - {x.AskSize}")) ); client.Streams.LiquidationStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Liquadation Action: {y.Action}, OrderID: {x.OrderID}, Symbol: {x.Symbol}, Side: {x.Side}, Price: {x.Price}, LeavesQty: {x.leavesQty}")) ); client.Streams.TradeBinStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"TradeBin table:{y.Table} {x.Symbol} executed. Time: {x.Timestamp:mm:ss.fff}, Open: {x.Open}, " + $"Close: {x.Close}, Volume: {x.Volume}, Trades: {x.Trades}")) ); client.Streams.InstrumentStream.Subscribe(x => { x.Data.ToList().ForEach(y => { Log.Information($"Instrument, {y.Symbol}, " + $"price: {y.MarkPrice}, last: {y.LastPrice}, " + $"mark: {y.MarkMethod}, fair: {y.FairMethod}, direction: {y.LastTickDirection}, " + $"funding: {y.FundingRate} i: {y.IndicativeFundingRate} s: {y.FundingQuoteSymbol}"); }); }); client.Streams.FundingStream.Subscribe(x => { x.Data.ToList().ForEach(f => { Log.Information($"Funding {f.Symbol}, Timestamp: {f.Timestamp}, Interval: {f.FundingInterval}, " + $"Rate: {f.FundingRate}, RateDaily: {f.FundingRateDaily}"); }); }); // example of unsubscribe requests //Task.Run(async () => //{ // await Task.Delay(5000); // await client.Send(new BookSubscribeRequest("XBTUSD") {IsUnsubscribe = true}); // await Task.Delay(5000); // await client.Send(new TradesSubscribeRequest() {IsUnsubscribe = true}); //}); }
static void Main(string[] args) { InitLogging(); AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit; Console.CancelKeyPress += ConsoleOnCancelKeyPress; Console.WriteLine("|=======================|"); Console.WriteLine("| BITMEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING (full .NET Framework) "); Log.Debug("===================================="); var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Log.Information($"Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); client.Send(new PingRequest()).Wait(); client.Send(new TradesSubscribeRequest("XBTUSD")).Wait(); if (!string.IsNullOrWhiteSpace(API_SECRET)) { client.Send(new AuthenticationRequest(API_KEY, API_SECRET)).Wait(); } }); client.Streams.ErrorStream.Subscribe(x => Log.Warning($"Error received, message: {x.Error}, status: {x.Status}")); client.Streams.AuthenticationStream.Subscribe(x => { Log.Information($"Authentication happened, success: {x.Success}"); client.Send(new WalletSubscribeRequest()).Wait(); client.Send(new OrderSubscribeRequest()).Wait(); client.Send(new PositionSubscribeRequest()).Wait(); }); client.Streams.PongStream.Subscribe(x => Log.Information($"Pong received ({x.Message})")); client.Streams.TradesStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Trade {x.Symbol} executed. Time: {x.Timestamp:mm:ss.fff}, Amount: {x.Size}, " + $"Price: {x.Price}, Direction: {x.TickDirection}")) ); communicator.Start(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
private void SendSubscriptions(BitmexWebsocketClient client, string pair) { client.Send(new TradesSubscribeRequest(pair)); client.Send(new BookSubscribeRequest(pair)); }
private static async Task StartPinging(BitmexWebsocketClient client) { await Task.Delay(TimeSpan.FromSeconds(30)); client.Send(new PingRequest()); }
static void Main(string[] args) { InitLogging(); AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit; AssemblyLoadContext.Default.Unloading += DefaultOnUnloading; Console.CancelKeyPress += ConsoleOnCancelKeyPress; Console.WriteLine("|=======================|"); Console.WriteLine("| BITMEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Log.Information($"Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); //client.Send(new PingRequest()); //client.Send(new BookSubscribeRequest()); client.Send(new TradesSubscribeRequest("XBTUSD")); //client.Send(new QuoteSubscribeRequest("XBTUSD")); client.Send(new LiquidationSubscribeRequest()); if (!string.IsNullOrWhiteSpace(API_SECRET)) { client.Send(new AuthenticationRequest(API_KEY, API_SECRET)); } }); client.Streams.ErrorStream.Subscribe(x => Log.Warning($"Error received, message: {x.Error}, status: {x.Status}")); client.Streams.AuthenticationStream.Subscribe(x => { Log.Information($"Authentication happened, success: {x.Success}"); client.Send(new WalletSubscribeRequest()); client.Send(new OrderSubscribeRequest()); client.Send(new PositionSubscribeRequest()); }); client.Streams.SubscribeStream.Subscribe(x => Log.Information($"Subscribed ({x.Success}) to {x.Subscribe}")); client.Streams.PongStream.Subscribe(x => Log.Information($"Pong received ({x.Message})")); client.Streams.WalletStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Wallet {x.Account}, {x.Currency} amount: {x.BalanceBtc}")) ); client.Streams.OrderStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Order {x.Symbol} updated. Time: {x.Timestamp:HH:mm:ss.fff}, Amount: {x.OrderQty}, " + $"Price: {x.Price}, Direction: {x.Side}, Working: {x.WorkingIndicator}, Status: {x.OrdStatus}")) ); client.Streams.PositionStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information( $"Position {x.Symbol}, {x.Currency} updated. Time: {x.Timestamp:HH:mm:ss.fff}, Amount: {x.CurrentQty}, " + $"Price: {x.LastPrice}, PNL: {x.UnrealisedPnl}")) ); client.Streams.TradesStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Trade {x.Symbol} executed. Time: {x.Timestamp:mm:ss.fff}, Amount: {x.Size}, " + $"Price: {x.Price}, Direction: {x.TickDirection}")) ); client.Streams.BookStream.Subscribe(book => book.Data.Take(100).ToList().ForEach(x => Log.Information( $"Book | {book.Action} pair: {x.Symbol}, price: {x.Price}, amount {x.Size}, side: {x.Side}")) ); client.Streams.QuoteStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Quote {x.Symbol}. Bid: {x.BidPrice} - {x.BidSize} Ask: {x.AskPrice} - {x.AskSize}")) ); client.Streams.LiquidationStream.Subscribe(y => y.Data.ToList().ForEach(x => Log.Information($"Liquadation Action:{y.Action} OrderID:{x.OrderID} Symbol:{x.Symbol} Side:{x.Side} Price:{x.Price} leavesQty:{x.leavesQty}")) ); communicator.Start(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }