private static async Task<ICryptoOrderBook> StartCoinbase(string pair, bool optimized, bool l2Optimized) { var url = CoinbaseValues.ApiWebsocketUrl; var communicator = new CoinbaseWebsocketCommunicator(url) { Name = "Coinbase" }; var client = new CoinbaseWebsocketClient(communicator); var source = new CoinbaseOrderBookSource(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 SubscribeRequest( new[] { pair }, ChannelSubscriptionType.Level2 )); return orderBook; }
public async Task Heartbeat() { var url = CoinbaseValues.ApiWebsocketUrl; using (var communicator = new CoinbaseWebsocketCommunicator(url)) { HeartbeatResponse received = null; var receivedEvent = new ManualResetEvent(false); using (var client = new CoinbaseWebsocketClient(communicator)) { client.Streams.HeartbeatStream.Subscribe(pong => { received = pong; receivedEvent.Set(); }); await communicator.Start(); client.Send(new SubscribeRequest(new [] { "BTC-EUR" }, ChannelSubscriptionType.Heartbeat)); receivedEvent.WaitOne(TimeSpan.FromSeconds(30)); Assert.NotNull(received); } } }
public async Task ConnectToSource_ShouldHandleOrderBookCorrectly() { var url = CoinbaseValues.ApiWebsocketUrl; using (var communicator = new CoinbaseWebsocketCommunicator(url)) { using (var client = new CoinbaseWebsocketClient(communicator)) { var pair = "BTC-USD"; var source = new CoinbaseOrderBookSource(client); var orderBook = new CryptoOrderBook(pair, source); await communicator.Start(); client.Send(new SubscribeRequest( new [] { pair }, ChannelSubscriptionType.Level2 )); await Task.Delay(TimeSpan.FromSeconds(5)); Assert.True(orderBook.BidPrice > 0); Assert.True(orderBook.AskPrice > 0); Assert.NotEmpty(orderBook.BidLevels); Assert.NotEmpty(orderBook.AskLevels); } } }
public async Task AutoSnapshotReloading_ShouldWorkAfterTimeout() { var url = CoinbaseValues.ApiWebsocketUrl; using (var communicator = new CoinbaseWebsocketCommunicator(url)) { using (var client = new CoinbaseWebsocketClient(communicator)) { var pair = "BTC-USD"; var source = new CoinbaseOrderBookSource(client) { LoadSnapshotEnabled = true }; var orderBook = new CryptoOrderBook(pair, source) { SnapshotReloadTimeout = TimeSpan.FromSeconds(2), SnapshotReloadEnabled = true }; await Task.Delay(TimeSpan.FromSeconds(20)); Assert.True(orderBook.BidPrice > 0); Assert.True(orderBook.AskPrice > 0); Assert.NotEmpty(orderBook.BidLevels); Assert.NotEmpty(orderBook.AskLevels); } } }
private static async Task SendSubscriptionRequestsAuthenticated(CoinbaseWebsocketClient client) { //create an authenticator with your apiKey, apiSecret and passphrase var authenticator = new CoinbaseAuthentication(API_KEY, API_SECRET, API_PASSPHRASE); var subscription = new SubscribeRequest( new[] { "BTC-EUR", "BTC-USD" }, new[] { ChannelSubscriptionType.Heartbeat, ChannelSubscriptionType.Ticker, ChannelSubscriptionType.Matches, ChannelSubscriptionType.Heartbeat, ChannelSubscriptionType.User, ChannelSubscriptionType.Level2, //ChannelSubscriptionType.Status }, authenticator); client.Send(subscription); }
/// <summary> /// Change client and resubscribe to the new streams /// </summary> public void ChangeClient(CoinbaseWebsocketClient client) { CryptoValidations.ValidateInput(client, nameof(client)); _client = client; _subscription?.Dispose(); Subscribe(); }
private static void SubscribeToStreams(CoinbaseWebsocketClient client) { client.Streams.ErrorStream.Subscribe(x => Log.Warning($"Error received, message: {x.Message}")); client.Streams.SubscribeStream.Subscribe(x => { Log.Information($"Subscribed, " + $"channels: {JsonConvert.SerializeObject(x.Channels, CoinbaseJsonSerializer.Settings)}"); }); client.Streams.HeartbeatStream.Subscribe(x => Log.Information($"Heartbeat received, product: {x.ProductId}, seq: {x.Sequence}, time: {x.Time}")); client.Streams.TickerStream.Subscribe(x => Log.Information($"Ticker {x.ProductId}. Bid: {x.BestBid} Ask: {x.BestAsk} Last size: {x.LastSize}, Price: {x.Price}") ); client.Streams.TradesStream.Subscribe(x => { Log.Information($"Trade executed [{x.ProductId}] {x.TradeSide} price: {x.Price} size: {x.Size}"); }); client.Streams.OrderBookSnapshotStream.Subscribe(x => { Log.Information($"OB snapshot [{x.ProductId}] bids: {x.Bids.Length}, asks: {x.Asks.Length}"); }); client.Streams.OrderBookUpdateStream.Subscribe(x => { Log.Information($"OB updates [{x.ProductId}] changes: {x.Changes.Length}"); }); client.Streams.OrderStream.Subscribe(orders => { Log.Information($"Order Stream.."); // foreach (var order in orders) //{ Log.Information($"Order: {orders.ProductId} {orders.Side} {orders.Price} {orders.OrderStatus} {orders.OrderType}"); // } }); // 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; AssemblyLoadContext.Default.Unloading += DefaultOnUnloading; Console.CancelKeyPress += ConsoleOnCancelKeyPress; Console.WriteLine("|=======================|"); Console.WriteLine("| COINBASE PRO CLIENT |"); Console.WriteLine("|=======================|"); Console.WriteLine(); Log.Debug("===================================="); Log.Debug(" STARTING "); Log.Debug("===================================="); var url = CoinbaseValues.ApiWebsocketUrl; using (var communicator = new CoinbaseWebsocketCommunicator(url)) { communicator.Name = "Coinbase-1"; communicator.ReconnectTimeout = TimeSpan.FromMinutes(1); using (var client = new CoinbaseWebsocketClient(communicator)) { SubscribeToStreams(client); communicator.ReconnectionHappened.Subscribe(async type => { Log.Information($"Reconnection happened, type: {type}, resubscribing.."); SendSubscriptionRequests(client); // Authenticated subscription // Fails without valid api key, secret and passphrase //await SendSubscriptionRequestsAuthenticated(client); }); communicator.Start().Wait(); ExitEvent.WaitOne(); } } Log.Debug("===================================="); Log.Debug(" STOPPING "); Log.Debug("===================================="); Log.CloseAndFlush(); }
private static async Task SendSubscriptionRequests(CoinbaseWebsocketClient client) { var subscription = new SubscribeRequest { ProductIds = new[] { "BTC-EUR", "BTC-USD" }, Channels = new[] { //ChannelSubscriptionType.Heartbeat, ChannelSubscriptionType.Ticker, ChannelSubscriptionType.Matches, //ChannelSubscriptionType.Level2 } }; client.Send(subscription); }
private static void SendSubscriptionRequests(CoinbaseWebsocketClient client) { var subscription = new SubscribeRequest( new[] { "BTC-EUR", "BTC-USD" }, new[] { ChannelSubscriptionType.Heartbeat, // ChannelSubscriptionType.Ticker, // ChannelSubscriptionType.Matches, // ChannelSubscriptionType.User, ChannelSubscriptionType.Level2, // ChannelSubscriptionType.Status }); client.Send(subscription); }
private static (ITradeSource, IWebsocketClient) GetCoinbase(string pair) { var url = CoinbaseValues.ApiWebsocketUrl; var communicator = new CoinbaseWebsocketCommunicator(url) { Name = "Coinbase" }; var client = new CoinbaseWebsocketClient(communicator); var source = new CoinbaseTradeSource(client); communicator.ReconnectionHappened.Subscribe(x => { client.Send(new SubscribeRequest( new[] { pair }, ChannelSubscriptionType.Matches )); }); return(source, communicator); }
/// <inheritdoc /> public CoinbaseTradeSource(CoinbaseWebsocketClient client) { ChangeClient(client); }
/// <inheritdoc /> public CoinbaseOrderSource(CoinbaseWebsocketClient client) { ChangeClient(client); }
/// <inheritdoc /> public CoinbaseWalletSource(CoinbaseWebsocketClient client) { ChangeClient(client); }
/// <inheritdoc /> public CoinbaseOrderBookSource(CoinbaseWebsocketClient client) { _httpClient.BaseAddress = new Uri("https://api.pro.coinbase.com"); ChangeClient(client); }