Example #1
0
        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;
        }
Example #2
0
        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);
                }
            }
        }
Example #3
0
        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);
                }
            }
        }
Example #4
0
        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);
 }
Example #15
0
        /// <inheritdoc />
        public CoinbaseOrderBookSource(CoinbaseWebsocketClient client)
        {
            _httpClient.BaseAddress = new Uri("https://api.pro.coinbase.com");

            ChangeClient(client);
        }