private void ProcessOrderBookUpdate(BitfinexChannel channel, string[] entries)
        {
            try
            {
                var symbol    = _symbolMapper.GetLeanSymbol(channel.Symbol);
                var orderBook = _orderBooks[symbol];

                var price  = decimal.Parse(entries[0], NumberStyles.Float, CultureInfo.InvariantCulture);
                var count  = int.Parse(entries[1]);
                var amount = decimal.Parse(entries[2], NumberStyles.Float, CultureInfo.InvariantCulture);

                if (count == 0)
                {
                    orderBook.RemovePriceLevel(price);
                }
                else
                {
                    if (amount > 0)
                    {
                        orderBook.UpdateBidRow(price, amount);
                    }
                    else if (amount < 0)
                    {
                        orderBook.UpdateAskRow(price, Math.Abs(amount));
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }
 private void OnSubscribe(Messages.ChannelSubscription data)
 {
     try
     {
         Channel existing = null;
         lock (channelLocker)
         {
             if (!ChannelList.TryGetValue(data.ChannelId, out existing))
             {
                 ChannelList[data.ChannelId] = new BitfinexChannel()
                 {
                     ChannelId = data.ChannelId, Name = data.Channel, Symbol = data.Symbol
                 };;
             }
             else
             {
                 BitfinexChannel typedChannel = existing as BitfinexChannel;
                 typedChannel.Name      = data.Channel;
                 typedChannel.ChannelId = data.ChannelId;
                 typedChannel.Symbol    = data.Symbol;
             }
         }
     }
     catch (Exception e)
     {
         Log.Error(e);
         throw;
     }
 }
        private void OnUpdate(string channelId, string[] entries)
        {
            try
            {
                BitfinexChannel channel = ChannelList[channelId] as BitfinexChannel;

                if (channel == null)
                {
                    OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message recieved from unknown channel Id {channelId}"));
                    return;
                }

                switch (channel.Name.ToLower())
                {
                case "book":
                    ProcessOrderBookUpdate(channel, entries);
                    return;

                case "trades":
                    ProcessTradeUpdate(channel, entries);
                    return;
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }
Пример #4
0
        private BitfinexWebSocketWrapper GetFreeWebSocket(BitfinexChannel channel)
        {
            int count;

            lock (_locker)
            {
                foreach (var kvp in _channelsByWebSocket)
                {
                    if (kvp.Value.Count < MaximumSubscriptionsPerSocket)
                    {
                        kvp.Value.Add(channel);

                        count = _channelsByWebSocket.Sum(x => x.Value.Count);
                        Log.Trace($"BitfinexSubscriptionManager.GetFreeWebSocket(): Channel added: Total channels:{count}");

                        return(kvp.Key);
                    }
                }
            }

            if (!_connectionRateLimiter.WaitToProceed(TimeSpan.Zero))
            {
                _connectionRateLimiter.WaitToProceed();
            }

            var webSocket = new BitfinexWebSocketWrapper(
                new DefaultConnectionHandler
            {
                MaximumIdleTimeSpan = TimeSpan.FromSeconds(15)
            });

            lock (_locker)
            {
                _channelsByWebSocket.TryAdd(webSocket, new List <BitfinexChannel> {
                    channel
                });

                count = _channelsByWebSocket.Sum(x => x.Value.Count);
                Log.Trace($"BitfinexSubscriptionManager.GetFreeWebSocket(): Channel added: Total channels:{count}");
            }

            webSocket.Initialize(_wssUrl);
            webSocket.Message += OnMessage;
            webSocket.Error   += OnError;

            Connect(webSocket);

            webSocket.ConnectionHandler.ConnectionLost     += OnConnectionLost;
            webSocket.ConnectionHandler.ConnectionRestored += OnConnectionRestored;
            webSocket.ConnectionHandler.ReconnectRequested += OnReconnectRequested;
            webSocket.ConnectionHandler.Initialize(webSocket.ConnectionId);

            Log.Trace("BitfinexSubscriptionManager.GetFreeWebSocket(): New websocket added: " +
                      $"Hashcode: {webSocket.GetHashCode()}, " +
                      $"WebSocket connections: {_channelsByWebSocket.Count}");

            return(webSocket);
        }
 private void ProcessTradesSnapshot(BitfinexChannel channel, string[][] entries)
 {
     try
     {
         var symbol = _symbolMapper.GetLeanSymbol(channel.Symbol);
         foreach (var entry in entries)
         {
             // pass time, price, amount
             EmitTradeTick(symbol, entry.Skip(1).ToArray());
         }
     }
     catch (Exception e)
     {
         Log.Error(e);
         throw;
     }
 }
Пример #6
0
        private BitfinexWebSocketWrapper SubscribeChannel(string channelName, Symbol symbol)
        {
            var ticker  = _symbolMapper.GetBrokerageSymbol(symbol);
            var channel = new BitfinexChannel {
                Name = channelName, Symbol = ticker, ChannelId = string.Empty
            };
            var webSocket = GetFreeWebSocket(channel);

            webSocket.Send(JsonConvert.SerializeObject(new
            {
                @event  = "subscribe",
                channel = channelName,
                pair    = ticker
            }));

            return(webSocket);
        }
Пример #7
0
        private void ProcessTradeUpdate(BitfinexChannel channel, string[] entries)
        {
            try
            {
                var symbol = _symbolMapper.GetLeanSymbol(channel.Symbol);
                var time   = Time.UnixMillisecondTimeStampToDateTime(double.Parse(entries[1], NumberStyles.Float, CultureInfo.InvariantCulture));
                var amount = decimal.Parse(entries[2], NumberStyles.Float, CultureInfo.InvariantCulture);
                var price  = decimal.Parse(entries[3], NumberStyles.Float, CultureInfo.InvariantCulture);

                EmitTradeTick(symbol, time, price, amount);
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }
 private void ProcessTradeUpdate(BitfinexChannel channel, string[] entries)
 {
     try
     {
         string eventType = entries[0];
         if (eventType == "tu")
         {
             var symbol = _symbolMapper.GetLeanSymbol(channel.Symbol);
             // pass time, price, amount
             EmitTradeTick(symbol, new[] { entries[3], entries[4], entries[5] });
         }
     }
     catch (Exception e)
     {
         Log.Error(e);
         throw;
     }
 }
        private void ProcessOrderBookSnapshot(BitfinexChannel channel, string[][] entries)
        {
            try
            {
                var symbol = _symbolMapper.GetLeanSymbol(channel.Symbol);

                OrderBook orderBook;
                if (!_orderBooks.TryGetValue(symbol, out orderBook))
                {
                    orderBook           = new OrderBook(symbol);
                    _orderBooks[symbol] = orderBook;
                }
                else
                {
                    orderBook.BestBidAskUpdated -= OnBestBidAskUpdated;
                    orderBook.Clear();
                }

                foreach (var entry in entries)
                {
                    var price  = decimal.Parse(entry[0], NumberStyles.Float, CultureInfo.InvariantCulture);
                    var amount = decimal.Parse(entry[2], NumberStyles.Float, CultureInfo.InvariantCulture);

                    if (amount > 0)
                    {
                        orderBook.UpdateBidRow(price, amount);
                    }
                    else
                    {
                        orderBook.UpdateAskRow(price, Math.Abs(amount));
                    }
                }

                orderBook.BestBidAskUpdated += OnBestBidAskUpdated;

                EmitQuoteTick(symbol, orderBook.BestBidPrice, orderBook.BestBidSize, orderBook.BestAskPrice, orderBook.BestAskSize);
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }