private static async Task<ICryptoOrderBook> StartBitfinex(string pair, bool optimized, bool l2Optimized) { var url = BitfinexValues.ApiWebsocketUrl; var communicator = new BitfinexWebsocketCommunicator(url) { Name = "Bitfinex" }; var client = new BitfinexWebsocketClient(communicator); var source = new BitfinexOrderBookSource(client); var orderBook = l2Optimized ? new CryptoOrderBookL2(pair, source) : (ICryptoOrderBook)new CryptoOrderBook(pair, source); if (optimized) { ConfigureOptimized(source, orderBook); } _ = communicator.Start(); // Send configuration request to enable server timestamps client.Send(new ConfigurationRequest(ConfigurationFlag.Sequencing | ConfigurationFlag.Timestamp)); // Send subscription request to order book data client.Send(new Bitfinex.Client.Websocket.Requests.Subscriptions.BookSubscribeRequest(pair, BitfinexPrecision.P0, BitfinexFrequency.Realtime, "100")); return orderBook; }
public async Task AutoSnapshotReloading_ShouldWorkAfterTimeout() { var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { using (var client = new BitfinexWebsocketClient(communicator)) { var pair = "LTCUSD"; var source = new BitfinexOrderBookSource(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 async Task PingPong() { var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { PongResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.PongStream.Subscribe(pong => { received = pong; receivedEvent.Set(); }); await communicator.Start(); client.Send(new PingRequest() { Cid = 123456 }); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); Assert.Equal(123456, received.Cid); Assert.True(DateTime.UtcNow.Subtract(received.Ts).TotalSeconds < 15); } } }
public async Task Authentication() { Skip.If(string.IsNullOrWhiteSpace(API_SECRET)); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { AuthenticationResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.AuthenticationStream.Subscribe(auth => { received = auth; receivedEvent.Set(); }); await communicator.Start(); client.Authenticate(API_KEY, API_SECRET); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); Assert.True(received.IsAuthenticated); } } }
public async Task ConnectToSource_ShouldHandleOrderBookCorrectly() { var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { using (var client = new BitfinexWebsocketClient(communicator)) { var pair = "BTCUSD"; var source = new BitfinexOrderBookSource(client); var orderBook = new CryptoOrderBook(pair, source); await communicator.Start(); client.Send(new BookSubscribeRequest(pair, BitfinexPrecision.P0, BitfinexFrequency.Realtime, "100")); await Task.Delay(TimeSpan.FromSeconds(5)); Assert.True(orderBook.BidPrice > 0); Assert.True(orderBook.AskPrice > 0); Assert.NotEmpty(orderBook.BidLevels); Assert.NotEmpty(orderBook.AskLevels); } } }
private static async Task <CryptoOrderBook> StartBitfinex(string pair, bool optimized) { var url = BitfinexValues.ApiWebsocketUrl; var communicator = new BitfinexWebsocketCommunicator(url) { Name = "Bitfinex" }; var client = new BitfinexWebsocketClient(communicator); var source = new BitfinexOrderBookL3Source(client); var orderBook = new CryptoOrderBook(pair, source, CryptoOrderBookType.L3); if (optimized) { ConfigureOptimized(source, orderBook); } _ = communicator.Start(); // Send configuration request to enable server timestamps client.Send(new ConfigurationRequest(ConfigurationFlag.Sequencing | ConfigurationFlag.Timestamp)); // Send subscription request to raw order book data client.Send(new Bitfinex.Client.Websocket.Requests.Subscriptions.RawBookSubscribeRequest(pair, "100")); return(orderBook); }
public BitfinexWebsocketClient(BitfinexWebsocketCommunicator communicator) { BfxValidations.ValidateInput(communicator, nameof(communicator)); _communicator = communicator; _channelIdToHandler[0] = Streams.HandleAccountInfo; _messageReceivedSubsciption = _communicator.MessageReceived.Subscribe(HandleMessage); }
public BitfinexWebsocketClient() { var url = BitfinexValues.ApiWebsocketUrl; _communicator = new BitfinexWebsocketCommunicator(url); _channelIdToHandler[0] = Streams.HandleAccountInfo; _messageReceivedSubsciption = _communicator.MessageReceived.Subscribe(HandleMessage); }
static void Main(string[] args) { InitLogging(); AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit; AssemblyLoadContext.Default.Unloading += DefaultOnUnloading; Console.CancelKeyPress += ConsoleOnCancelKeyPress; Console.WriteLine("|=======================|"); Console.WriteLine("| BITFINEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { communicator.Name = "Bitfinex-1"; communicator.ReconnectTimeout = TimeSpan.FromSeconds(30); communicator.ReconnectionHappened.Subscribe(info => Log.Information($"Reconnection happened, type: {info.Type}")); using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Log.Information( $"Info received version: {info.Version}, reconnection happened, resubscribing to streams"); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); 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("| BITFINEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); //var url = new Uri("wss://real.okex.com:10441/websocket"); var url = BitfinexValues.ApiWebsocketUrl; var communicator = new BitfinexWebsocketCommunicator(url); var client = new BitfinexWebsocketClient(communicator); client.Streams.InfoStream.Subscribe(info => { client.Authenticate(API_KEY, API_SECRET); client.Send(new PingRequest() { Cid = 123456 }); Log.Information($"Info received version: {info.Version}, reconnection happened, resubscribing to streams"); SendSubscriptionRequests(client); }); SubscribeToStreams(client); communicator.Start(); ExitEvent.WaitOne(); Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
public static void Start() { InitLogging(); AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit; Console.CancelKeyPress += ConsoleOnCancelKeyPress; Console.WriteLine("|=======================|"); Console.WriteLine("| BITFINEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { communicator.ReconnectTimeoutMs = (int)TimeSpan.FromSeconds(30).TotalMilliseconds; communicator.ReconnectionHappened.Subscribe(type => Log.Information($"Reconnection happened, type: {type}")); using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.InfoStream.Subscribe(info => { Log.Information($"Info received version: {info.Version}, reconnection happened, resubscribing to streams"); SendSubscriptionRequests(client).Wait(); }); SubscribeToStreams(client); communicator.Start(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
private static (ITradeSource, IWebsocketClient) GetBitfinex(string pair) { var url = BitfinexValues.ApiWebsocketUrl; var communicator = new BitfinexWebsocketCommunicator(url) { Name = "Bitfinex" }; var client = new BitfinexWebsocketClient(communicator); var source = new BitfinexTradeSource(client); communicator.ReconnectionHappened.Subscribe(x => { client.Send(new Bitfinex.Client.Websocket.Requests.Subscriptions.TradesSubscribeRequest(pair)); }); return(source, communicator); }
public async Task PingPong() { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.File(logPath, rollingInterval: RollingInterval.Day) .WriteTo.ColoredConsole(LogEventLevel.Verbose) .CreateLogger(); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { PongResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.PongStream.Subscribe(pong => { received = pong; receivedEvent.Set(); }); await communicator.Start(); await client.Send(new PingRequest() { Cid = 123456 }); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); Assert.Equal(123456, received.Cid); Assert.True(DateTime.UtcNow.Subtract(received.Ts).TotalSeconds < 15); } } }
public async Task OnStarting_ShouldGetInfoResponse() { var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(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); Assert.Contains("\"event\":\"info\",\"version\":2", received); } }
public async Task Authentication() { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.File(logPath, rollingInterval: RollingInterval.Day) .WriteTo.ColoredConsole(LogEventLevel.Verbose) .CreateLogger(); Skip.If(string.IsNullOrWhiteSpace(API_SECRET)); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { AuthenticationResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new BitfinexWebsocketClient(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.IsAuthenticated); } } }
static void Main(string[] args) { InitLogging(); AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit; AssemblyLoadContext.Default.Unloading += DefaultOnUnloading; Console.CancelKeyPress += ConsoleOnCancelKeyPress; Console.WriteLine("|=======================|"); Console.WriteLine("| BITFINEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.PongStream.Subscribe(pong => Log.Information($"Pong received! Id: {pong.Cid}")); client.Streams.TickerStream.Subscribe(ticker => Log.Information($"{ticker.Pair} - last price: {ticker.LastPrice}")); client.Streams.AuthenticationStream.Subscribe(auth => Log.Information($"Authenticated: {auth.IsAuthenticated}")); client.Streams.WalletsStream .Subscribe(wallets => wallets.ToList().ForEach(wallet => Log.Information($"Wallet {wallet.Currency} balance: {wallet.Balance}"))); communicator.Start().Wait(); client.Send(new PingRequest() { Cid = 123456 }); client.Send(new TickerSubscribeRequest("BTC/USD")); client.Send(new TickerSubscribeRequest("ETH/USD")); if (!string.IsNullOrWhiteSpace(API_SECRET)) { client.Authenticate(API_KEY, API_SECRET); // Place BUY order // client.Send(new NewOrderRequest(33, 1, "ETH/USD", OrderType.ExchangeLimit, 0.2, 100)); // Place SELL order // client.Send(new NewOrderRequest(33, 2, "ETH/USD", OrderType.ExchangeLimit, -0.2, 2000)); // Cancel order // client.Send(new CancelOrderRequest(1)); } 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("| BITFINEX CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = BitfinexValues.ApiWebsocketUrl; using (var communicator = new BitfinexWebsocketCommunicator(url)) { using (var client = new BitfinexWebsocketClient(communicator)) { client.Streams.PongStream.Subscribe(pong => Log.Information($"Pong received! Id: {pong.Cid}")); client.Streams.TickerStream.Subscribe(ticker => Log.Information($"{ticker.Pair} - last price: {ticker.LastPrice}, bid: {ticker.Bid}, ask: {ticker.Ask}")); client.Streams.TradesStream.Where(x => x.Type == TradeType.Executed).Subscribe(x => Log.Information($"Trade {x.Pair} executed. Time: {x.Mts:mm:ss.fff}, Amount: {x.Amount}, Price: {x.Price}")); client.Streams.CandlesStream.Subscribe(candles => { candles.CandleList.OrderBy(x => x.Mts).ToList().ForEach(x => { Log.Information( $"Candle(Pair : {candles.Pair} TimeFrame : {candles.TimeFrame.GetStringValue()}) --> {x.Mts} High : {x.High} Low : {x.Low} Open : {x.Open} Close : {x.Close}"); }); }); client.Streams.BookStream.Subscribe(book => Log.Information( $"Book | channel: {book.ChanId} pair: {book.Pair}, price: {book.Price}, amount {book.Amount}, count: {book.Count}")); client.Streams.CandlesStream.Subscribe(candles => { candles.CandleList.OrderBy(x => x.Mts).ToList().ForEach(x => { Log.Information( $"Candle(Pair : {candles.Pair} TimeFrame : {candles.TimeFrame.GetStringValue()}) --> {x.Mts} High : {x.High} Low : {x.Low} Open : {x.Open} Close : {x.Close}"); }); }); client.Streams.AuthenticationStream.Subscribe(auth => Log.Information($"Authenticated: {auth.IsAuthenticated}")); client.Streams.WalletStream .Subscribe(wallet => Log.Information($"Wallet {wallet.Currency} balance: {wallet.Balance} type: {wallet.Type}")); communicator.Start().Wait(); client.Send(new PingRequest() { Cid = 123456 }); client.Send(new TickerSubscribeRequest("BTC/USD")); client.Send(new TickerSubscribeRequest("ETH/USD")); //client.Send(new TradesSubscribeRequest("ETH/USD")); client.Send(new CandlesSubscribeRequest("BTC/USD", BitfinexTimeFrame.OneMinute)); client.Send(new CandlesSubscribeRequest("ETH/USD", BitfinexTimeFrame.OneMinute)); //client.Send(new BookSubscribeRequest("BTC/USD", BitfinexPrecision.P0, BitfinexFrequency.TwoSecDelay)); //client.Send(new BookSubscribeRequest("BTC/USD", BitfinexPrecision.P3, BitfinexFrequency.Realtime)); if (!string.IsNullOrWhiteSpace(API_SECRET)) { client.Authenticate(API_KEY, API_SECRET); // Place BUY order // client.Send(new NewOrderRequest(33, 1, "ETH/USD", OrderType.ExchangeLimit, 0.2, 100)); // Place SELL order // client.Send(new NewOrderRequest(33, 2, "ETH/USD", OrderType.ExchangeLimit, -0.2, 2000)); // Cancel order // client.Send(new CancelOrderRequest(1)); } ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }