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 BitmexWebsocketClient(BitmexWebsocketCommunicator communicator) { BmxValidations.ValidateInput(communicator, nameof(communicator)); _communicator = communicator; _messageReceivedSubsciption = _communicator.MessageReceived.Subscribe(HandleMessage); }
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); } } }
public async Task Authentication() { Skip.If(string.IsNullOrWhiteSpace(API_SECRET)); var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { AuthenticationResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.AuthenticationStream.Subscribe(auth => { received = auth; receivedEvent.Set(); }); await communicator.Start(); await client.Authenticate(API_KEY, API_SECRET); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); Assert.True(received.Success); } } }
public async Task AutoSnapshotReloading_ShouldWorkAfterTimeout() { var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { using (var client = new BitmexWebsocketClient(communicator)) { var pair = "XBTUSD"; var source = new BitmexOrderBookSource(client) { LoadSnapshotEnabled = true }; var orderBook = new CryptoOrderBook(pair, source) { SnapshotReloadTimeout = TimeSpan.FromSeconds(5), SnapshotReloadEnabled = true }; await Task.Delay(TimeSpan.FromSeconds(13)); Assert.True(orderBook.BidPrice > 0); Assert.True(orderBook.AskPrice > 0); Assert.NotEmpty(orderBook.BidLevels); Assert.NotEmpty(orderBook.AskLevels); } } }
public PositionsForm() { InitializeComponent(); Load += new EventHandler(Form1_Load); //Connecting to WebSocket var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { communicator.Name = "Bitmex-1"; communicator.ReconnectTimeout = TimeSpan.FromMinutes(10); communicator.ReconnectionHappened.Subscribe(type => Console.WriteLine($"Reconnection happened, type: {type.Type}")); using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Console.WriteLine($"Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); communicator.Start(); _ = StartPinging(client); } } }
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 static void RunSample(ManualResetEvent ExitEvent) { Console.WriteLine("|=================================|"); Console.WriteLine("| BITMEX MULTIPLEX CLIENT |"); Console.WriteLine("|=================================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = BitmexValues.ApiMultiplexingWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { communicator.Name = "Bitmex-Multiplex-1"; communicator.ReconnectTimeoutMs = (int)TimeSpan.FromMinutes(10).TotalMilliseconds; communicator.ReconnectionHappened.Subscribe(type => Log.Information($"Reconnection happened, type: {type}")); using (var client = new BitmexMultiplexClient(communicator)) { client.Channels.Subscribe(channel => channel.Streams.InfoStream.Subscribe(info => { Log.Information($"Channel = {channel.ChannelName} | Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); })); client.Channels.Subscribe(channel => channel.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}")) )); //List<BitmexWebsocketChannel> channels = CreateChannels(client).Result; var channels = new List <BitmexWebsocketChannel> { client.CreateChannel("test").Result }; SubscribeToStreams(client); SendSubscriptionRequests(client, channels); communicator.Start(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
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)) { communicator.Name = "Bitmex-1"; communicator.ReconnectTimeout = TimeSpan.FromMinutes(10); communicator.ReconnectionHappened.Subscribe(type => Log.Information($"Reconnection happened, type: {type.Type}")); var recordingPath = Path.Combine(ProjectDirectory, RecordingFile); using (var client = new BitmexWebsocketRecorderClient(communicator, recordingPath, delimiter: ";;")) { client.Streams.InfoStream.Subscribe(info => { Log.Information($"Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); communicator.Start(); _ = StartPinging(client); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
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)) { communicator.ReconnectTimeoutMs = (int)TimeSpan.FromSeconds(30).TotalMilliseconds; communicator.ReconnectionHappened.Subscribe(type => Log.Information($"Reconnection happened, type: {type}")); using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Log.Information($"Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); communicator.Start(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
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 RunSample(ManualResetEvent ExitEvent) { 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)) { communicator.Name = "Bitmex-1"; communicator.ReconnectTimeoutMs = (int)TimeSpan.FromMinutes(10).TotalMilliseconds; communicator.ReconnectionHappened.Subscribe(type => Log.Information($"Reconnection happened, type: {type}")); using (var client = new BitmexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Log.Information($"Reconnection happened, Message: {info.Info}, Version: {info.Version:D}"); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); communicator.Start(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
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 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); }
public async Task OnStarting_ShouldGetInfoResponse() { var url = BitmexValues.ApiWebsocketUrl; using (var communicator = new BitmexWebsocketCommunicator(url)) { string received = null; var receivedEvent = new ManualResetEvent(false); communicator.MessageReceived.Subscribe(msg => { received = msg; receivedEvent.Set(); }); await communicator.Start(); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); } }
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); } } }
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(); }
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(); }