BitfinexBrokerage updates (#5787)

* Update BinanceBrokerage to handle more than 512 symbols

* Address review

- fetch symbol weights only if required
- remove code duplication

* Add rate limiting for new connections

* Update WebSocketMessage to include the websocket instance

* Handle resubscriptions on reconnect

* Address review

* Address review

* Remove unnecessary locking

* WebSocketClientWrapper updates

- remove allocation of receive buffer on each message
- add missing lock in Close method
- log message data when message type is Close
- fix race condition after unexpected websocket close

* Set WebSocketClientWrapper task to LongRunning

* Add missing check in GetHistory

* Fix exceptions with Binance downloader

- closes #5794

* Update Bitfinex symbols in symbol properties database

* Update BitfinexBrokerage to use BrokerageMultiWebSocketSubscriptionManager

* Address review

* Remove unnecessary locking

* Remove old channels on resubscription
This commit is contained in:
Stefano Raggi
2021-07-28 16:10:12 +02:00
committed by GitHub
parent e823dfdfb7
commit 0c4e577885
13 changed files with 1234 additions and 923 deletions

View File

@@ -35,7 +35,7 @@ namespace QuantConnect.Brokerages.Binance
/// </summary>
protected readonly object TickLocker = new object();
private void OnMessageImpl(WebSocketMessage e)
private void OnUserMessage(WebSocketMessage e)
{
try
{
@@ -65,7 +65,39 @@ namespace QuantConnect.Brokerages.Binance
OnFillOrder(upd);
}
break;
}
}
}
catch (Exception exception)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, -1, $"Parsing wss message failed. Data: {e.Message} Exception: {exception}"));
throw;
}
}
private void OnDataMessage(WebSocketMessage e)
{
try
{
var obj = JObject.Parse(e.Message);
var objError = obj["error"];
if (objError != null)
{
var error = objError.ToObject<ErrorMessage>();
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, error.Code, error.Message));
return;
}
var objData = obj;
var objEventType = objData["e"];
if (objEventType != null)
{
var eventType = objEventType.ToObject<string>();
switch (eventType)
{
case "trade":
var trade = objData.ToObject<Trade>();
EmitTradeTick(

View File

@@ -25,6 +25,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QuantConnect.Configuration;
using QuantConnect.Util;
using Timer = System.Timers.Timer;
@@ -52,6 +54,8 @@ namespace QuantConnect.Brokerages.Binance
private readonly BinanceRestApiClient _apiClient;
private readonly BrokerageConcurrentMessageHandler<WebSocketMessage> _messageHandler;
private const int MaximumSymbolsPerConnection = 512;
/// <summary>
/// Constructor for brokerage
/// </summary>
@@ -66,15 +70,20 @@ namespace QuantConnect.Brokerages.Binance
_job = job;
_algorithm = algorithm;
_aggregator = aggregator;
_messageHandler = new BrokerageConcurrentMessageHandler<WebSocketMessage>(OnMessageImpl);
_messageHandler = new BrokerageConcurrentMessageHandler<WebSocketMessage>(OnUserMessage);
var subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
subscriptionManager.SubscribeImpl += (s, t) =>
{
Subscribe(s);
return true;
};
subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);
var maximumWebSocketConnections = Config.GetInt("binance-maximum-websocket-connections");
var symbolWeights = maximumWebSocketConnections > 0 ? FetchSymbolWeights() : null;
var subscriptionManager = new BrokerageMultiWebSocketSubscriptionManager(
WebSocketBaseUrl,
MaximumSymbolsPerConnection,
maximumWebSocketConnections,
symbolWeights,
() => new BinanceWebSocketWrapper(null),
Subscribe,
Unsubscribe,
OnDataMessage);
SubscriptionManager = subscriptionManager;
@@ -398,51 +407,55 @@ namespace QuantConnect.Brokerages.Binance
}
/// <summary>
/// Subscribes to the requested symbols (using an individual streaming channel)
/// Not used
/// </summary>
/// <param name="symbols">The list of symbols to subscribe</param>
public override void Subscribe(IEnumerable<Symbol> symbols)
{
foreach (var symbol in symbols)
{
Send(WebSocket,
new
{
method = "SUBSCRIBE",
@params = new[]
{
$"{symbol.Value.ToLowerInvariant()}@trade",
$"{symbol.Value.ToLowerInvariant()}@bookTicker"
},
id = GetNextRequestId()
}
);
}
// NOP
}
/// <summary>
/// Ends current subscriptions
/// Subscribes to the requested symbol (using an individual streaming channel)
/// </summary>
private bool Unsubscribe(IEnumerable<Symbol> symbols)
/// <param name="webSocket">The websocket instance</param>
/// <param name="symbol">The symbol to subscribe</param>
private bool Subscribe(IWebSocket webSocket, Symbol symbol)
{
if (WebSocket.IsOpen)
{
foreach (var symbol in symbols)
Send(webSocket,
new
{
Send(WebSocket,
new
{
method = "UNSUBSCRIBE",
@params = new[]
{
$"{symbol.Value.ToLowerInvariant()}@trade",
$"{symbol.Value.ToLowerInvariant()}@bookTicker"
},
id = GetNextRequestId()
}
);
method = "SUBSCRIBE",
@params = new[]
{
$"{symbol.Value.ToLowerInvariant()}@trade",
$"{symbol.Value.ToLowerInvariant()}@bookTicker"
},
id = GetNextRequestId()
}
}
);
return true;
}
/// <summary>
/// Ends current subscription
/// </summary>
/// <param name="webSocket">The websocket instance</param>
/// <param name="symbol">The symbol to unsubscribe</param>
private bool Unsubscribe(IWebSocket webSocket, Symbol symbol)
{
Send(webSocket,
new
{
method = "UNSUBSCRIBE",
@params = new[]
{
$"{symbol.Value.ToLowerInvariant()}@trade",
$"{symbol.Value.ToLowerInvariant()}@bookTicker"
},
id = GetNextRequestId()
}
);
return true;
}
@@ -485,5 +498,36 @@ namespace QuantConnect.Brokerages.Binance
CachedOrderIDs.TryAdd(order.Id, order);
}
}
/// <summary>
/// Returns the weights for each symbol (the weight value is the count of trades in the last 24 hours)
/// </summary>
private static Dictionary<Symbol, int> FetchSymbolWeights()
{
var dict = new Dictionary<Symbol, int>();
try
{
const string url = "https://api.binance.com/api/v3/ticker/24hr";
var json = url.DownloadData();
foreach (var row in JArray.Parse(json))
{
var ticker = row["symbol"].ToObject<string>();
var count = row["count"].ToObject<int>();
var symbol = Symbol.Create(ticker, SecurityType.Crypto, Market.Binance);
dict.Add(symbol, count);
}
}
catch (Exception exception)
{
Log.Error(exception);
throw;
}
return dict;
}
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -317,12 +317,18 @@ namespace QuantConnect.Brokerages.Binance
var klines = JsonConvert.DeserializeObject<object[][]>(response.Content)
.Select(entries => new Messages.Kline(entries))
.ToList();
startMs = klines.Last().OpenTime + resolutionInMs;
foreach (var kline in klines)
if (klines.Count > 0)
{
yield return kline;
startMs = klines.Last().OpenTime + resolutionInMs;
foreach (var kline in klines)
{
yield return kline;
}
}
else
{
startMs += resolutionInMs;
}
}
}
@@ -355,19 +361,17 @@ namespace QuantConnect.Brokerages.Binance
/// </summary>
public void StopSession()
{
if (string.IsNullOrEmpty(SessionId))
if (!string.IsNullOrEmpty(SessionId))
{
throw new Exception("BinanceBrokerage:UserStream. listenKey wasn't allocated or has been refused.");
var request = new RestRequest(UserDataStreamEndpoint, Method.DELETE);
request.AddHeader(KeyHeader, ApiKey);
request.AddParameter(
"application/x-www-form-urlencoded",
Encoding.UTF8.GetBytes($"listenKey={SessionId}"),
ParameterType.RequestBody
);
ExecuteRestRequest(request);
}
var request = new RestRequest(UserDataStreamEndpoint, Method.DELETE);
request.AddHeader(KeyHeader, ApiKey);
request.AddParameter(
"application/x-www-form-urlencoded",
Encoding.UTF8.GetBytes($"listenKey={SessionId}"),
ParameterType.RequestBody
);
ExecuteRestRequest(request);
}
/// <summary>

View File

@@ -0,0 +1,525 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.Linq;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QuantConnect.Brokerages.Bitfinex.Messages;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Logging;
using QuantConnect.Util;
namespace QuantConnect.Brokerages.Bitfinex
{
public partial class BitfinexBrokerage
{
private readonly RateGate _connectionRateLimiter = new(5, TimeSpan.FromMinutes(1));
private readonly ConcurrentDictionary<IWebSocket, BitfinexWebSocketChannels> _channelsByWebSocket = new();
private readonly ConcurrentDictionary<Symbol, DefaultOrderBook> _orderBooks = new();
private readonly ManualResetEvent _onSubscribeEvent = new(false);
private readonly ManualResetEvent _onUnsubscribeEvent = new(false);
private readonly object _locker = new();
private const int MaximumSymbolsPerConnection = 12;
/// <summary>
/// Subscribes to the requested symbol (using an individual streaming channel)
/// </summary>
/// <param name="webSocket">The websocket instance</param>
/// <param name="symbol">The symbol to subscribe</param>
private bool Subscribe(IWebSocket webSocket, Symbol symbol)
{
lock (_locker)
{
if (!_channelsByWebSocket.ContainsKey(webSocket))
{
_channelsByWebSocket.TryAdd(webSocket, new BitfinexWebSocketChannels());
}
}
var success = SubscribeChannel(webSocket, "trades", symbol);
success &= SubscribeChannel(webSocket, "book", symbol);
return success;
}
/// <summary>
/// Ends current subscription
/// </summary>
/// <param name="webSocket">The websocket instance</param>
/// <param name="symbol">The symbol to unsubscribe</param>
private bool Unsubscribe(IWebSocket webSocket, Symbol symbol)
{
BitfinexWebSocketChannels channels;
lock (_locker)
{
if (!_channelsByWebSocket.TryGetValue(webSocket, out channels))
{
return true;
}
}
var success = UnsubscribeChannel(webSocket, channels, new Channel("trades", symbol));
success &= UnsubscribeChannel(webSocket, channels, new Channel("book", symbol));
return success;
}
private bool SubscribeChannel(IWebSocket webSocket, string channelName, Symbol symbol)
{
_onSubscribeEvent.Reset();
webSocket.Send(JsonConvert.SerializeObject(new
{
@event = "subscribe",
channel = channelName,
pair = _symbolMapper.GetBrokerageSymbol(symbol)
}));
if (!_onSubscribeEvent.WaitOne(TimeSpan.FromSeconds(30)))
{
Log.Error($"BitfinexBrokerage.Unsubscribe(): Could not subscribe to {symbol.Value}/{channelName}.");
return false;
}
return true;
}
private bool UnsubscribeChannel(IWebSocket webSocket, BitfinexWebSocketChannels channels, Channel channel)
{
if (channels.Contains(channel))
{
var channelId = channels.GetChannelId(channel);
_onUnsubscribeEvent.Reset();
webSocket.Send(JsonConvert.SerializeObject(new
{
@event = "unsubscribe",
chanId = channelId.ToStringInvariant()
}));
if (!_onUnsubscribeEvent.WaitOne(TimeSpan.FromSeconds(30)))
{
Log.Error($"BitfinexBrokerage.Unsubscribe(): Could not unsubscribe from {channel.Symbol.Value}/{channel.Name}.");
return false;
}
}
return true;
}
private void OnDataMessage(WebSocketMessage e)
{
var webSocket = (BitfinexWebSocketWrapper)e.WebSocket;
try
{
var token = JToken.Parse(e.Message);
if (token is JArray)
{
var channel = token[0].ToObject<int>();
if (token[1].Type == JTokenType.String)
{
var type = token[1].Value<string>();
switch (type)
{
// heartbeat
case "hb":
return;
// trade execution
case "te":
OnUpdate(webSocket, channel, token[2].ToObject<string[]>());
break;
// ignored -- trades already handled in "te" message
// https://github.com/bitfinexcom/bitfinex-api-node#te-vs-tu-messages
case "tu":
break;
default:
Log.Error($"BitfinexBrokerage.OnDataMessage(): Unexpected message type: {type}");
return;
}
}
// public channels
else if (channel != 0 && token[1].Type == JTokenType.Array)
{
var tokens = (JArray)token[1];
if (tokens.Count > 0)
{
if (tokens[0].Type == JTokenType.Array)
{
OnSnapshot(
webSocket,
channel,
tokens.ToObject<string[][]>()
);
}
else
{
// pass channel id as separate arg
OnUpdate(
webSocket,
channel,
tokens.ToObject<string[]>()
);
}
}
}
}
else if (token is JObject)
{
var raw = token.ToObject<BaseMessage>();
switch (raw.Event.ToLowerInvariant())
{
case "subscribed":
OnSubscribe(webSocket, token.ToObject<ChannelSubscription>());
return;
case "unsubscribed":
OnUnsubscribe(webSocket, token.ToObject<ChannelUnsubscribing>());
return;
case "auth":
case "info":
case "ping":
return;
case "error":
var error = token.ToObject<ErrorMessage>();
// 10300 Subscription failed (generic) | 10301 : Already subscribed | 10302 : Unknown channel
// see https://docs.bitfinex.com/docs/ws-general
if (error.Code == 10300 || error.Code == 10301 || error.Code == 10302)
{
//_subscribeErrorCode = error.Code;
_onSubscribeEvent.Set();
}
Log.Error($"BitfinexBrokerage.OnDataMessage(): {e.Message}");
return;
default:
Log.Error($"BitfinexBrokerage.OnDataMessage(): Unexpected message format: {e.Message}");
break;
}
}
}
catch (Exception exception)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, -1, $"Parsing wss message failed. Data: {e.Message} Exception: {exception}"));
throw;
}
}
private void OnSubscribe(BitfinexWebSocketWrapper webSocket, ChannelSubscription data)
{
try
{
lock (_locker)
{
var symbol = _symbolMapper.GetLeanSymbol(data.Symbol, SecurityType.Crypto, Market.Bitfinex);
var channel = new Channel(data.Channel, symbol);
if (!_channelsByWebSocket.TryGetValue(webSocket, out var channels))
{
_onSubscribeEvent.Set();
return;
}
// we need to update the channel on re subscription
var channelsToRemove = channels
.Where(x => x.Value.Equals(channel))
.Select(x => x.Key)
.ToList();
foreach (var channelId in channelsToRemove)
{
channels.TryRemove(channelId, out _);
}
channels.AddOrUpdate(data.ChannelId, channel);
Log.Trace($"BitfinexBrokerage.OnSubscribe(): Channel subscribed: Id:{data.ChannelId} {channel.Symbol}/{channel.Name}");
_onSubscribeEvent.Set();
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnUnsubscribe(BitfinexWebSocketWrapper webSocket, ChannelUnsubscribing data)
{
try
{
lock (_locker)
{
if (!_channelsByWebSocket.TryGetValue(webSocket, out var channels))
{
_onUnsubscribeEvent.Set();
return;
}
if (!channels.TryRemove(data.ChannelId, out _))
{
_onUnsubscribeEvent.Set();
return;
}
_onUnsubscribeEvent.Set();
if (channels.Count != 0)
{
return;
}
_channelsByWebSocket.TryRemove(webSocket, out channels);
}
webSocket.Close();
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnSnapshot(BitfinexWebSocketWrapper webSocket, int channelId, string[][] entries)
{
try
{
Channel channel;
lock (_locker)
{
if (!_channelsByWebSocket.TryGetValue(webSocket, out var channels))
{
return;
}
if (!channels.TryGetValue(channelId, out channel))
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}"));
return;
}
}
switch (channel.Name.ToLowerInvariant())
{
case "book":
ProcessOrderBookSnapshot(channel, entries);
return;
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void ProcessOrderBookSnapshot(Channel channel, string[][] entries)
{
try
{
var symbol = channel.Symbol;
if (!_orderBooks.TryGetValue(symbol, out var orderBook))
{
orderBook = new DefaultOrderBook(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;
}
}
private void OnUpdate(BitfinexWebSocketWrapper webSocket, int channelId, string[] entries)
{
try
{
Channel channel;
lock (_locker)
{
if (!_channelsByWebSocket.TryGetValue(webSocket, out var channels))
{
return;
}
if (!channels.TryGetValue(channelId, out channel))
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}"));
return;
}
}
switch (channel.Name.ToLowerInvariant())
{
case "book":
ProcessOrderBookUpdate(channel, entries);
return;
case "trades":
ProcessTradeUpdate(channel, entries);
return;
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void ProcessOrderBookUpdate(Channel channel, string[] entries)
{
try
{
var symbol = channel.Symbol;
var orderBook = _orderBooks[symbol];
var price = decimal.Parse(entries[0], NumberStyles.Float, CultureInfo.InvariantCulture);
var count = Parse.Long(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, $"Entries: [{string.Join(",", entries)}]");
throw;
}
}
private void ProcessTradeUpdate(Channel channel, string[] entries)
{
try
{
var time = Time.UnixMillisecondTimeStampToDateTime(decimal.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(channel.Symbol, time, price, amount);
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void EmitTradeTick(Symbol symbol, DateTime time, decimal price, decimal amount)
{
try
{
lock (TickLocker)
{
EmitTick(new Tick
{
Value = price,
Time = time,
Symbol = symbol,
TickType = TickType.Trade,
Quantity = Math.Abs(amount)
});
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void EmitQuoteTick(Symbol symbol, decimal bidPrice, decimal bidSize, decimal askPrice, decimal askSize)
{
lock (TickLocker)
{
EmitTick(new Tick
{
AskPrice = askPrice,
BidPrice = bidPrice,
Value = (askPrice + bidPrice) / 2m,
Time = DateTime.UtcNow,
Symbol = symbol,
TickType = TickType.Quote,
AskSize = Math.Abs(askSize),
BidSize = Math.Abs(bidSize)
});
}
}
private void OnBestBidAskUpdated(object sender, BestBidAskUpdatedEventArgs e)
{
EmitQuoteTick(e.Symbol, e.BestBidPrice, e.BestBidSize, e.BestAskPrice, e.BestAskSize);
}
}
}

View File

@@ -93,7 +93,18 @@ namespace QuantConnect.Brokerages.Bitfinex
: base(WebSocketUrl, websocket, restClient, apiKey, apiSecret, "Bitfinex")
{
_job = job;
SubscriptionManager = new BitfinexSubscriptionManager(this, WebSocketUrl, _symbolMapper);
SubscriptionManager = new BrokerageMultiWebSocketSubscriptionManager(
WebSocketUrl,
MaximumSymbolsPerConnection,
0,
null,
() => new BitfinexWebSocketWrapper(null),
Subscribe,
Unsubscribe,
OnDataMessage,
_connectionRateLimiter);
_symbolPropertiesDatabase = SymbolPropertiesDatabase.FromDataFolder();
_algorithm = algorithm;
_aggregator = aggregator;
@@ -147,7 +158,7 @@ namespace QuantConnect.Brokerages.Bitfinex
}
/// <summary>
/// Should be empty, Bitfinex brokerage manages his public channels including subscribe/unsubscribe/reconnect methods using <see cref="BitfinexSubscriptionManager"/>
/// Should be empty, Bitfinex brokerage manages his public channels including subscribe/unsubscribe/reconnect methods using <see cref="BrokerageMultiWebSocketSubscriptionManager"/>
/// Not used in master
/// </summary>
/// <param name="symbols"></param>
@@ -248,8 +259,8 @@ namespace QuantConnect.Brokerages.Bitfinex
{
case "auth":
var auth = token.ToObject<AuthResponseMessage>();
var result = string.Equals(auth.Status, "OK", StringComparison.OrdinalIgnoreCase) ? "succeed" : "failed";
Log.Trace($"BitfinexWebsocketsBrokerage.OnMessage: Subscribing to authenticated channels {result}");
var result = string.Equals(auth.Status, "OK", StringComparison.OrdinalIgnoreCase) ? "successful" : "failed";
Log.Trace($"BitfinexBrokerage.OnMessage: Subscribing to authenticated channels {result}");
return;
case "info":
@@ -258,11 +269,11 @@ namespace QuantConnect.Brokerages.Bitfinex
case "error":
var error = token.ToObject<ErrorMessage>();
Log.Error($"BitfinexWebsocketsBrokerage.OnMessage: {error.Level}: {error.Message}");
Log.Error($"BitfinexBrokerage.OnMessage: {error.Level}: {error.Message}");
return;
default:
Log.Trace($"BitfinexWebsocketsBrokerage.OnMessage: Unexpected message format: {e.Message}");
Log.Error($"BitfinexBrokerage.OnMessage: Unexpected message format: {e.Message}");
break;
}
}
@@ -479,7 +490,7 @@ namespace QuantConnect.Brokerages.Bitfinex
}
/// <summary>
/// Should be empty. <see cref="BitfinexSubscriptionManager"/> manages each <see cref="BitfinexWebSocketWrapper"/> individually
/// Should be empty. <see cref="BrokerageMultiWebSocketSubscriptionManager"/> manages each <see cref="BitfinexWebSocketWrapper"/> individually
/// </summary>
/// <returns></returns>
protected override IEnumerable<Symbol> GetSubscribed() => new List<Symbol>();

View File

@@ -488,6 +488,9 @@ namespace QuantConnect.Brokerages.Bitfinex
{
_aggregator.Dispose();
_restRateLimiter.Dispose();
_connectionRateLimiter.Dispose();
_onSubscribeEvent.Dispose();
_onUnsubscribeEvent.Dispose();
}
}
}

View File

@@ -1,753 +0,0 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Logging;
using QuantConnect.Util;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using QuantConnect.Brokerages.Bitfinex.Messages;
namespace QuantConnect.Brokerages.Bitfinex
{
/// <summary>
/// Handles Bitfinex data subscriptions with multiple websocket connections
/// </summary>
public class BitfinexSubscriptionManager : DataQueueHandlerSubscriptionManager
{
/// <summary>
/// Maximum number of subscribed channels per websocket connection
/// </summary>
/// <remarks>
/// Source: https://medium.com/bitfinex/bitfinex-api-update-june-2019-661e806e6567
/// </remarks>
private const int MaximumSubscriptionsPerSocket = 30;
private const int ConnectionTimeout = 30000;
private readonly string _wssUrl;
private volatile int _subscribeErrorCode;
private readonly object _locker = new object();
private readonly BitfinexBrokerage _brokerage;
private readonly ISymbolMapper _symbolMapper;
private readonly RateGate _connectionRateLimiter = new RateGate(5, TimeSpan.FromMinutes(1));
private readonly ConcurrentDictionary<Symbol, List<BitfinexWebSocketWrapper>> _subscriptionsBySymbol = new ConcurrentDictionary<Symbol, List<BitfinexWebSocketWrapper>>();
private readonly ConcurrentDictionary<BitfinexWebSocketWrapper, BitfinexWebSocketChannels> _channelsByWebSocket = new ConcurrentDictionary<BitfinexWebSocketWrapper, BitfinexWebSocketChannels>();
private readonly ConcurrentDictionary<Symbol, DefaultOrderBook> _orderBooks = new ConcurrentDictionary<Symbol, DefaultOrderBook>();
private readonly IReadOnlyDictionary<TickType, string> _tickType2ChannelName = new Dictionary<TickType, string>
{
{ TickType.Trade, "trades"},
{ TickType.Quote, "book"}
};
private readonly ManualResetEvent _onSubscribeEvent = new ManualResetEvent(false);
private readonly ManualResetEvent _onUnsubscribeEvent = new ManualResetEvent(false);
/// <summary>
/// Initializes a new instance of the <see cref="BitfinexSubscriptionManager"/> class.
/// </summary>
public BitfinexSubscriptionManager(BitfinexBrokerage brokerage, string wssUrl, ISymbolMapper symbolMapper)
{
_brokerage = brokerage;
_wssUrl = wssUrl;
_symbolMapper = symbolMapper;
}
/// <summary>
/// Subscribes to the requested subscription (using an individual streaming channel)
/// </summary>
/// <param name="symbols">symbol list</param>
/// <param name="tickType">Type of tick data</param>
protected override bool Subscribe(IEnumerable<Symbol> symbols, TickType tickType)
{
try
{
var states = new List<bool>(symbols.Count());
foreach (var symbol in symbols)
{
_onSubscribeEvent.Reset();
_subscribeErrorCode = 0;
var subscription = SubscribeChannel(
ChannelNameFromTickType(tickType),
symbol);
_subscriptionsBySymbol.AddOrUpdate(
symbol,
new List<BitfinexWebSocketWrapper> { subscription },
(k, v) =>
{
if (!v.Contains(subscription))
{
v.Add(subscription);
}
return v;
});
Log.Trace($"BitfinexBrokerage.Subscribe(): Sent subscribe for {symbol.Value}/{tickType}.");
if (_onSubscribeEvent.WaitOne(TimeSpan.FromSeconds(10)) && _subscribeErrorCode == 0)
{
states.Add(true);
}
else
{
Log.Trace($"BitfinexBrokerage.Subscribe(): Could not subscribe to {symbol.Value}/{tickType}.");
states.Add(false);
}
}
return states.All(s => s);
}
catch (Exception exception)
{
Log.Error(exception);
throw;
}
}
/// <summary>
/// Removes the subscription for the requested symbol
/// </summary>
/// <param name="symbols">symbol list</param>
/// <param name="tickType">Type of tick data</param>
protected override bool Unsubscribe(IEnumerable<Symbol> symbols, TickType tickType)
{
var channelName = ChannelNameFromTickType(tickType);
var states = new List<bool>(symbols.Count());
foreach (var symbol in symbols)
{
List<BitfinexWebSocketWrapper> subscriptions;
if (_subscriptionsBySymbol.TryGetValue(symbol, out subscriptions))
{
for (var i = subscriptions.Count - 1; i >= 0; i--)
{
var webSocket = subscriptions[i];
_onUnsubscribeEvent.Reset();
try
{
var channel = new Channel(channelName, symbol);
BitfinexWebSocketChannels channels;
if (_channelsByWebSocket.TryGetValue(webSocket, out channels) && channels.Contains(channel))
{
UnsubscribeChannel(webSocket, channels, channel);
if (_onUnsubscribeEvent.WaitOne(TimeSpan.FromSeconds(30)))
{
states.Add(true);
}
else
{
Log.Trace($"BitfinexBrokerage.Unsubscribe(): Could not unsubscribe from {symbol.Value}.");
states.Add(false);
}
}
}
catch (Exception exception)
{
Log.Error(exception);
}
}
}
}
return states.All(s => s);
}
/// <summary>
/// Get channel name for a given <see cref="TickType"/>
/// </summary>
/// <param name="tickType"></param>
/// <returns>Channel name <see cref="string"/></returns>
protected override string ChannelNameFromTickType(TickType tickType)
{
string channelName;
if (_tickType2ChannelName.TryGetValue(tickType, out channelName))
{
return channelName;
}
else
{
throw new ArgumentOutOfRangeException("TickType", $"BitfinexSubscriptionManager.Subscribe(): Tick type {tickType} is not allowed for this brokerage.");
}
}
private BitfinexWebSocketWrapper SubscribeChannel(string channelName, Symbol symbol)
{
var channel = new Channel(channelName, symbol);
var webSocket = GetFreeWebSocket(channel);
webSocket.Send(JsonConvert.SerializeObject(new
{
@event = "subscribe",
channel = channelName,
pair = _symbolMapper.GetBrokerageSymbol(symbol)
}));
return webSocket;
}
private void UnsubscribeChannel(IWebSocket webSocket, BitfinexWebSocketChannels channels, Channel channel)
{
var channelId = channels.GetChannelId(channel);
webSocket.Send(JsonConvert.SerializeObject(new
{
@event = "unsubscribe",
chanId = channelId.ToStringInvariant()
}));
}
private BitfinexWebSocketWrapper GetFreeWebSocket(Channel channel)
{
lock (_locker)
{
foreach (var kvp in _channelsByWebSocket)
{
if (kvp.Value.Count < MaximumSubscriptionsPerSocket)
{
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 BitfinexWebSocketChannels());
}
webSocket.Initialize(_wssUrl);
webSocket.Message += OnMessage;
Connect(webSocket);
webSocket.ConnectionHandler.ReconnectRequested += OnReconnectRequested;
webSocket.ConnectionHandler.Initialize(webSocket.ConnectionId);
int connections;
lock (_locker)
{
connections = _channelsByWebSocket.Count;
}
Log.Trace("BitfinexSubscriptionManager.GetFreeWebSocket(): New websocket added: " +
$"Hashcode: {webSocket.GetHashCode()}, " +
$"WebSocket connections: {connections}");
return webSocket;
}
private void Connect(IWebSocket webSocket)
{
var connectedEvent = new ManualResetEvent(false);
EventHandler onOpenAction = (s, e) =>
{
connectedEvent.Set();
};
webSocket.Open += onOpenAction;
try
{
webSocket.Connect();
if (!connectedEvent.WaitOne(ConnectionTimeout))
{
throw new Exception("BitfinexSubscriptionManager.Connect(): WebSocket connection timeout.");
}
}
finally
{
webSocket.Open -= onOpenAction;
connectedEvent.DisposeSafely();
}
}
private void OnReconnectRequested(object sender, EventArgs e)
{
var connectionHandler = (DefaultConnectionHandler)sender;
Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): WebSocket reconnection requested [Id: {connectionHandler.ConnectionId}]");
BitfinexWebSocketWrapper webSocket = null;
lock (_locker)
{
webSocket = _channelsByWebSocket.Keys
.FirstOrDefault(connection => connection.ConnectionId == connectionHandler.ConnectionId);
}
if (webSocket == null)
{
Log.Error($"BitfinexSubscriptionManager.OnReconnectRequested(): WebSocket ConnectionId not found: {connectionHandler.ConnectionId}");
return;
}
Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): IsOpen:{webSocket.IsOpen} [Id: {connectionHandler.ConnectionId}]");
if (!webSocket.IsOpen)
{
Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Websocket connecting. [Id: {connectionHandler.ConnectionId}]");
webSocket.Connect();
}
if (!webSocket.IsOpen)
{
Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Websocket not open: IsOpen:{webSocket.IsOpen} [Id: {connectionHandler.ConnectionId}]");
return;
}
Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Reconnected: IsOpen:{webSocket.IsOpen} [Id: {connectionHandler.ConnectionId}]");
BitfinexWebSocketChannels channels;
lock (_locker)
{
if (!_channelsByWebSocket.TryGetValue(webSocket, out channels))
{
return;
}
}
Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Resubscribing channels. [Id: {connectionHandler.ConnectionId}]");
foreach (var channel in channels.Values)
{
webSocket.Send(JsonConvert.SerializeObject(new
{
@event = "subscribe",
channel = channel.Name,
pair = _symbolMapper.GetBrokerageSymbol(channel.Symbol)
}));
}
}
private void OnMessage(object sender, WebSocketMessage e)
{
var webSocket = (BitfinexWebSocketWrapper)sender;
try
{
var token = JToken.Parse(e.Message);
webSocket.ConnectionHandler.KeepAlive(DateTime.UtcNow);
if (token is JArray)
{
var channel = token[0].ToObject<int>();
if (token[1].Type == JTokenType.String)
{
var type = token[1].Value<string>();
switch (type)
{
// heartbeat
case "hb":
return;
// trade execution
case "te":
OnUpdate(webSocket, channel, token[2].ToObject<string[]>());
break;
// ignored -- trades already handled in "te" message
// https://github.com/bitfinexcom/bitfinex-api-node#te-vs-tu-messages
case "tu":
break;
default:
Log.Trace($"BitfinexSubscriptionManager.OnMessage(): Unexpected message type: {type}");
return;
}
}
// public channels
else if (channel != 0 && token[1].Type == JTokenType.Array)
{
if (token[1][0].Type == JTokenType.Array)
{
OnSnapshot(
webSocket,
channel,
token[1].ToObject<string[][]>()
);
}
else
{
// pass channel id as separate arg
OnUpdate(
webSocket,
channel,
token[1].ToObject<string[]>()
);
}
}
}
else if (token is JObject)
{
var raw = token.ToObject<BaseMessage>();
switch (raw.Event.ToLowerInvariant())
{
case "subscribed":
OnSubscribe(webSocket, token.ToObject<ChannelSubscription>());
return;
case "unsubscribed":
OnUnsubscribe(webSocket, token.ToObject<ChannelUnsubscribing>());
return;
case "auth":
case "info":
case "ping":
return;
case "error":
var error = token.ToObject<ErrorMessage>();
// 10300 Subscription failed (generic) | 10301 : Already subscribed | 10302 : Unknown channel
// see https://docs.bitfinex.com/docs/ws-general
if (error.Code == 10300 || error.Code == 10301 || error.Code == 10302)
{
_subscribeErrorCode = error.Code;
_onSubscribeEvent.Set();
}
Log.Error($"BitfinexSubscriptionManager.OnMessage(): {e.Message}");
return;
default:
Log.Trace($"BitfinexSubscriptionManager.OnMessage(): Unexpected message format: {e.Message}");
break;
}
}
}
catch (Exception exception)
{
_brokerage.OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, -1, $"Parsing wss message failed. Data: {e.Message} Exception: {exception}"));
throw;
}
}
private void OnSubscribe(BitfinexWebSocketWrapper webSocket, ChannelSubscription data)
{
try
{
lock (_locker)
{
var channel = new Channel(data.Channel, _symbolMapper.GetLeanSymbol(data.Symbol, SecurityType.Crypto, Market.Bitfinex));
BitfinexWebSocketChannels channels;
if (!_channelsByWebSocket.TryGetValue(webSocket, out channels))
{
_onSubscribeEvent.Set();
return;
}
// we need to update the channel on re subscription
channels.AddOrUpdate(data.ChannelId, channel);
Log.Trace($"BitfinexSubscriptionManager.OnSubscribe(): Channel subscribed: Id:{data.ChannelId} {channel.Symbol}/{channel.Name}");
_onSubscribeEvent.Set();
webSocket.ConnectionHandler.EnableMonitoring(true);
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnUnsubscribe(BitfinexWebSocketWrapper webSocket, ChannelUnsubscribing data)
{
try
{
lock (_locker)
{
BitfinexWebSocketChannels channels;
if (!_channelsByWebSocket.TryGetValue(webSocket, out channels))
{
return;
}
Channel channel;
if (!channels.TryRemove(data.ChannelId, out channel))
{
return;
}
_onUnsubscribeEvent.Set();
if (channels.Values.Count(c => c.Symbol.Equals(channel.Symbol)) == 0)
{
List<BitfinexWebSocketWrapper> subscriptions;
if (_subscriptionsBySymbol.TryGetValue(channel.Symbol, out subscriptions))
{
subscriptions.Remove(webSocket);
if (subscriptions.Count == 0)
{
_subscriptionsBySymbol.TryRemove(channel.Symbol, out subscriptions);
}
}
}
if (channels.Count != 0)
{
return;
}
_channelsByWebSocket.TryRemove(webSocket, out channels);
}
webSocket.Close();
webSocket.ConnectionHandler.DisposeSafely();
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnSnapshot(BitfinexWebSocketWrapper webSocket, int channelId, string[][] entries)
{
try
{
Channel channel;
lock (_locker)
{
BitfinexWebSocketChannels channels;
if (!_channelsByWebSocket.TryGetValue(webSocket, out channels))
{
return;
}
if (!channels.TryGetValue(channelId, out channel))
{
_brokerage.OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}"));
return;
}
}
switch (channel.Name.ToLowerInvariant())
{
case "book":
ProcessOrderBookSnapshot(channel, entries);
return;
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void ProcessOrderBookSnapshot(Channel channel, string[][] entries)
{
try
{
var symbol = channel.Symbol;
DefaultOrderBook orderBook;
if (!_orderBooks.TryGetValue(symbol, out orderBook))
{
orderBook = new DefaultOrderBook(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;
}
}
private void OnUpdate(BitfinexWebSocketWrapper webSocket, int channelId, string[] entries)
{
try
{
Channel channel;
lock (_locker)
{
BitfinexWebSocketChannels channels;
if (!_channelsByWebSocket.TryGetValue(webSocket, out channels))
{
return;
}
if (!channels.TryGetValue(channelId, out channel))
{
_brokerage.OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}"));
return;
}
}
switch (channel.Name.ToLowerInvariant())
{
case "book":
ProcessOrderBookUpdate(channel, entries);
return;
case "trades":
ProcessTradeUpdate(channel, entries);
return;
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void ProcessOrderBookUpdate(Channel channel, string[] entries)
{
try
{
var symbol = channel.Symbol;
var orderBook = _orderBooks[symbol];
var price = decimal.Parse(entries[0], NumberStyles.Float, CultureInfo.InvariantCulture);
var count = Parse.Long(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, $"Entries: [{string.Join(",", entries)}]");
throw;
}
}
private void ProcessTradeUpdate(Channel channel, string[] entries)
{
try
{
var time = Time.UnixMillisecondTimeStampToDateTime(decimal.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(channel.Symbol, time, price, amount);
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void EmitTradeTick(Symbol symbol, DateTime time, decimal price, decimal amount)
{
try
{
lock (_brokerage.TickLocker)
{
_brokerage.EmitTick(new Tick
{
Value = price,
Time = time,
Symbol = symbol,
TickType = TickType.Trade,
Quantity = Math.Abs(amount)
});
}
}
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void EmitQuoteTick(Symbol symbol, decimal bidPrice, decimal bidSize, decimal askPrice, decimal askSize)
{
lock (_brokerage.TickLocker)
{
_brokerage.EmitTick(new Tick
{
AskPrice = askPrice,
BidPrice = bidPrice,
Value = (askPrice + bidPrice) / 2m,
Time = DateTime.UtcNow,
Symbol = symbol,
TickType = TickType.Quote,
AskSize = Math.Abs(askSize),
BidSize = Math.Abs(bidSize)
});
}
}
private void OnBestBidAskUpdated(object sender, BestBidAskUpdatedEventArgs e)
{
EmitQuoteTick(e.Symbol, e.BestBidPrice, e.BestBidSize, e.BestAskPrice, e.BestAskSize);
}
}
}

View File

@@ -0,0 +1,138 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using System.Linq;
namespace QuantConnect.Brokerages
{
/// <summary>
/// Helper class for <see cref="BrokerageMultiWebSocketSubscriptionManager"/>
/// </summary>
public class BrokerageMultiWebSocketEntry
{
private readonly Dictionary<Symbol, int> _symbolWeights;
private readonly List<Symbol> _symbols;
private readonly object _locker = new();
/// <summary>
/// Gets the web socket instance
/// </summary>
public IWebSocket WebSocket { get; }
/// <summary>
/// Gets the sum of symbol weights for this web socket
/// </summary>
public int TotalWeight { get; private set; }
/// <summary>
/// Gets the number of symbols subscribed
/// </summary>
public int SymbolCount
{
get
{
lock (_locker)
{
return _symbols.Count;
}
}
}
/// <summary>
/// Returns whether the symbol is subscribed
/// </summary>
/// <param name="symbol"></param>
/// <returns></returns>
public bool Contains(Symbol symbol)
{
lock (_locker)
{
return _symbols.Contains(symbol);
}
}
/// <summary>
/// Returns the list of subscribed symbols
/// </summary>
/// <returns></returns>
public IReadOnlyCollection<Symbol> Symbols
{
get
{
lock (_locker)
{
return _symbols.ToList();
}
}
}
/// <summary>
/// Initializes a new instance of the <see cref="BrokerageMultiWebSocketEntry"/> class
/// </summary>
/// <param name="symbolWeights">A dictionary of symbol weights</param>
/// <param name="webSocket">The web socket instance</param>
public BrokerageMultiWebSocketEntry(Dictionary<Symbol, int> symbolWeights, IWebSocket webSocket)
{
_symbolWeights = symbolWeights;
_symbols = new List<Symbol>();
WebSocket = webSocket;
}
/// <summary>
/// Initializes a new instance of the <see cref="BrokerageMultiWebSocketEntry"/> class
/// </summary>
/// <param name="webSocket">The web socket instance</param>
public BrokerageMultiWebSocketEntry(IWebSocket webSocket)
: this(null, webSocket)
{
}
/// <summary>
/// Adds a symbol to the entry
/// </summary>
/// <param name="symbol">The symbol to add</param>
public void AddSymbol(Symbol symbol)
{
lock (_locker)
{
_symbols.Add(symbol);
}
if (_symbolWeights != null && _symbolWeights.TryGetValue(symbol, out var weight))
{
TotalWeight += weight;
}
}
/// <summary>
/// Removes a symbol from the entry
/// </summary>
/// <param name="symbol">The symbol to remove</param>
public void RemoveSymbol(Symbol symbol)
{
lock (_locker)
{
_symbols.Remove(symbol);
}
if (_symbolWeights != null && _symbolWeights.TryGetValue(symbol, out var weight))
{
TotalWeight -= weight;
}
}
}
}

View File

@@ -0,0 +1,255 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using QuantConnect.Data;
using QuantConnect.Logging;
using QuantConnect.Util;
namespace QuantConnect.Brokerages
{
/// <summary>
/// Handles brokerage data subscriptions with multiple websocket connections, with optional symbol weighting
/// </summary>
public class BrokerageMultiWebSocketSubscriptionManager : EventBasedDataQueueHandlerSubscriptionManager
{
private readonly string _webSocketUrl;
private readonly int _maximumSymbolsPerWebSocket;
private readonly int _maximumWebSocketConnections;
private readonly Func<WebSocketClientWrapper> _webSocketFactory;
private readonly Func<IWebSocket, Symbol, bool> _subscribeFunc;
private readonly Func<IWebSocket, Symbol, bool> _unsubscribeFunc;
private readonly Action<WebSocketMessage> _messageHandler;
private readonly RateGate _connectionRateLimiter;
private const int ConnectionTimeout = 30000;
private readonly object _locker = new();
private readonly List<BrokerageMultiWebSocketEntry> _webSocketEntries = new();
/// <summary>
/// Initializes a new instance of the <see cref="BrokerageMultiWebSocketSubscriptionManager"/> class
/// </summary>
/// <param name="webSocketUrl">The URL for websocket connections</param>
/// <param name="maximumSymbolsPerWebSocket">The maximum number of symbols per websocket connection</param>
/// <param name="maximumWebSocketConnections">The maximum number of websocket connections allowed (if zero, symbol weighting is disabled)</param>
/// <param name="connectionRateLimiter">The rate limiter for creating new websocket connections</param>
/// <param name="symbolWeights">A dictionary for the symbol weights</param>
/// <param name="webSocketFactory">A function which returns a new websocket instance</param>
/// <param name="subscribeFunc">A function which subscribes a symbol</param>
/// <param name="unsubscribeFunc">A function which unsubscribes a symbol</param>
/// <param name="messageHandler">The websocket message handler</param>
public BrokerageMultiWebSocketSubscriptionManager(
string webSocketUrl,
int maximumSymbolsPerWebSocket,
int maximumWebSocketConnections,
Dictionary<Symbol, int> symbolWeights,
Func<WebSocketClientWrapper> webSocketFactory,
Func<IWebSocket, Symbol, bool> subscribeFunc,
Func<IWebSocket, Symbol, bool> unsubscribeFunc,
Action<WebSocketMessage> messageHandler,
RateGate connectionRateLimiter = null)
{
_webSocketUrl = webSocketUrl;
_maximumSymbolsPerWebSocket = maximumSymbolsPerWebSocket;
_maximumWebSocketConnections = maximumWebSocketConnections;
_webSocketFactory = webSocketFactory;
_subscribeFunc = subscribeFunc;
_unsubscribeFunc = unsubscribeFunc;
_messageHandler = messageHandler;
_connectionRateLimiter = connectionRateLimiter;
if (_maximumWebSocketConnections > 0)
{
// symbol weighting enabled, create all websocket instances
for (var i = 0; i < _maximumWebSocketConnections; i++)
{
var webSocket = _webSocketFactory();
webSocket.Open += OnOpen;
_webSocketEntries.Add(new BrokerageMultiWebSocketEntry(symbolWeights, webSocket));
}
}
}
/// <summary>
/// Subscribes to the symbols
/// </summary>
/// <param name="symbols">Symbols to subscribe</param>
/// <param name="tickType">Type of tick data</param>
protected override bool Subscribe(IEnumerable<Symbol> symbols, TickType tickType)
{
Log.Trace($"BrokerageMultiWebSocketSubscriptionManager.Subscribe(): {string.Join(",", symbols.Select(x => x.Value))}");
var success = true;
foreach (var symbol in symbols)
{
var webSocket = GetWebSocketForSymbol(symbol);
success &= _subscribeFunc(webSocket, symbol);
}
return success;
}
/// <summary>
/// Unsubscribes from the symbols
/// </summary>
/// <param name="symbols">Symbols to subscribe</param>
/// <param name="tickType">Type of tick data</param>
protected override bool Unsubscribe(IEnumerable<Symbol> symbols, TickType tickType)
{
Log.Trace($"BrokerageMultiWebSocketSubscriptionManager.Unsubscribe(): {string.Join(",", symbols.Select(x => x.Value))}");
var success = true;
foreach (var symbol in symbols)
{
var entry = GetWebSocketEntryBySymbol(symbol);
if (entry != null)
{
entry.RemoveSymbol(symbol);
success &= _unsubscribeFunc(entry.WebSocket, symbol);
}
}
return success;
}
private BrokerageMultiWebSocketEntry GetWebSocketEntryBySymbol(Symbol symbol)
{
lock (_locker)
{
foreach (var entry in _webSocketEntries.Where(entry => entry.Contains(symbol)))
{
return entry;
}
}
return null;
}
/// <summary>
/// Adds a symbol to an existing or new websocket connection
/// </summary>
private IWebSocket GetWebSocketForSymbol(Symbol symbol)
{
BrokerageMultiWebSocketEntry entry;
lock (_locker)
{
if (_webSocketEntries.All(x => x.SymbolCount >= _maximumSymbolsPerWebSocket))
{
if (_maximumWebSocketConnections > 0)
{
throw new NotSupportedException($"Maximum symbol count reached for the current configuration [MaxSymbolsPerWebSocket={_maximumSymbolsPerWebSocket}, MaxWebSocketConnections:{_maximumWebSocketConnections}]");
}
// symbol limit reached on all, create new websocket instance
var webSocket = _webSocketFactory();
webSocket.Open += OnOpen;
_webSocketEntries.Add(new BrokerageMultiWebSocketEntry(webSocket));
}
// sort by weight ascending, taking into account the symbol limit per websocket
_webSocketEntries.Sort((x, y) =>
x.SymbolCount >= _maximumSymbolsPerWebSocket
? 1
: y.SymbolCount >= _maximumSymbolsPerWebSocket
? -1
: Math.Sign(x.TotalWeight - y.TotalWeight));
entry = _webSocketEntries.First();
}
if (!entry.WebSocket.IsOpen)
{
Connect(entry.WebSocket);
}
entry.AddSymbol(symbol);
Log.Trace($"BrokerageMultiWebSocketSubscriptionManager.GetWebSocketForSymbol(): added symbol: {symbol} to websocket: {entry.WebSocket.GetHashCode()} - Count: {entry.SymbolCount}");
return entry.WebSocket;
}
private void Connect(IWebSocket webSocket)
{
webSocket.Initialize(_webSocketUrl);
webSocket.Message += (s, e) => _messageHandler(e);
var connectedEvent = new ManualResetEvent(false);
EventHandler onOpenAction = (_, _) =>
{
connectedEvent.Set();
};
webSocket.Open += onOpenAction;
if (_connectionRateLimiter is { IsRateLimited: false })
{
_connectionRateLimiter.WaitToProceed();
}
try
{
webSocket.Connect();
if (!connectedEvent.WaitOne(ConnectionTimeout))
{
throw new TimeoutException($"BrokerageMultiWebSocketSubscriptionManager.Connect(): WebSocket connection timeout: {webSocket.GetHashCode()}");
}
}
finally
{
webSocket.Open -= onOpenAction;
connectedEvent.DisposeSafely();
}
}
private void OnOpen(object sender, EventArgs e)
{
var webSocket = (IWebSocket)sender;
lock (_locker)
{
foreach (var entry in _webSocketEntries)
{
if (entry.WebSocket == webSocket && entry.Symbols.Count > 0)
{
Log.Trace($"BrokerageMultiWebSocketSubscriptionManager.Connect(): WebSocket opened: {webSocket.GetHashCode()} - Resubscribing existing symbols: {entry.Symbols.Count}");
Task.Factory.StartNew(() =>
{
foreach (var symbol in entry.Symbols)
{
_subscribeFunc(webSocket, symbol);
}
});
}
}
}
}
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -70,6 +70,8 @@ namespace QuantConnect.Brokerages
{
_cts = new CancellationTokenSource();
_client = null;
_taskConnect = Task.Factory.StartNew(
() =>
{
@@ -93,7 +95,18 @@ namespace QuantConnect.Brokerages
Log.Trace($"WebSocketClientWrapper connection task ended: {_url}");
},
_cts.Token);
_cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
var count = 0;
do
{
// wait for _client to be not null
if (_client != null || _cts.Token.WaitHandle.WaitOne(50))
{
break;
}
}
while (++count < 100);
}
}
}
@@ -103,24 +116,30 @@ namespace QuantConnect.Brokerages
/// </summary>
public void Close()
{
try
lock (_locker)
{
_client?.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", _cts.Token).SynchronouslyAwaitTask();
try
{
_client?.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", _cts.Token).SynchronouslyAwaitTask();
_cts?.Cancel();
_cts?.Cancel();
_taskConnect?.Wait(TimeSpan.FromSeconds(5));
_taskConnect?.Wait(TimeSpan.FromSeconds(5));
_cts.DisposeSafely();
}
catch (Exception e)
{
Log.Error($"WebSocketClientWrapper.Close({_url}): {e}");
_cts.DisposeSafely();
}
catch (Exception e)
{
Log.Error($"WebSocketClientWrapper.Close({_url}): {e}");
}
_cts = null;
}
_cts = null;
OnClose(new WebSocketCloseData(0, string.Empty, true));
if (_client != null)
{
OnClose(new WebSocketCloseData(0, string.Empty, true));
}
}
/// <summary>
@@ -196,22 +215,35 @@ namespace QuantConnect.Brokerages
await _client.ConnectAsync(new Uri(_url), connectionCts.Token);
OnOpen();
var receiveBuffer = new byte[ReceiveBufferSize];
while ((_client.State == WebSocketState.Open || _client.State == WebSocketState.CloseSent) &&
!connectionCts.IsCancellationRequested)
{
var messageData = await ReceiveMessage(_client, connectionCts.Token);
var messageData = await ReceiveMessage(_client, connectionCts.Token, receiveBuffer);
if (messageData.MessageType == WebSocketMessageType.Close)
{
Log.Trace($"WebSocketClientWrapper.HandleConnection({_url}): WebSocketMessageType.Close");
var data = string.Empty;
if (messageData.Data != null)
{
data = Encoding.UTF8.GetString(messageData.Data);
}
Log.Trace($"WebSocketClientWrapper.HandleConnection({_url}): WebSocketMessageType.Close - Data: {data}");
return;
}
var message = Encoding.UTF8.GetString(messageData.Data);
OnMessage(new WebSocketMessage(message));
OnMessage(new WebSocketMessage(this, message));
}
}
catch (OperationCanceledException) { }
catch (WebSocketException ex)
{
OnError(new WebSocketError(ex.Message, ex));
connectionCts.Token.WaitHandle.WaitOne(2000);
}
catch (Exception ex)
{
OnError(new WebSocketError(ex.Message, ex));
@@ -222,9 +254,10 @@ namespace QuantConnect.Brokerages
private async Task<MessageData> ReceiveMessage(
WebSocket webSocket,
CancellationToken ct,
byte[] receiveBuffer,
long maxSize = long.MaxValue)
{
var buffer = new ArraySegment<byte>(new byte[ReceiveBufferSize]);
var buffer = new ArraySegment<byte>(receiveBuffer);
using (var ms = new MemoryStream())
{

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -20,6 +20,11 @@ namespace QuantConnect.Brokerages
/// </summary>
public class WebSocketMessage
{
/// <summary>
/// Gets the sender websocket instance
/// </summary>
public IWebSocket WebSocket { get; }
/// <summary>
/// Gets the raw message data as text
/// </summary>
@@ -28,10 +33,12 @@ namespace QuantConnect.Brokerages
/// <summary>
/// Initializes a new instance of the <see cref="WebSocketMessage"/> class
/// </summary>
/// <param name="webSocket">The sender websocket instance</param>
/// <param name="message">The message</param>
public WebSocketMessage(string message)
public WebSocketMessage(IWebSocket webSocket, string message)
{
WebSocket = webSocket;
Message = message;
}
}
}
}

View File

@@ -467,13 +467,15 @@ gdax,ZRXBTC,crypto,0x-Bitcoin,BTC,1,0.00000001,0.00001,ZRX-BTC
gdax,ZRXEUR,crypto,0x-Euro,EUR,1,0.000001,0.00001,ZRX-EUR
gdax,ZRXUSD,crypto,0x-United States Dollar,USD,1,0.000001,0.00001,ZRX-USD
bitfinex,ABYSSUSD,crypto,The Abyss-US Dollar,USD,1,0.00001,0.00000001,tABSUSD
bitfinex,1INCHUSD,crypto,1INCH-US Dollar,USD,1,0.00001,0.00000001,t1INCH:USD
bitfinex,1INCHUSDT,crypto,1INCH-Tether USDt,USDT,1,0.00001,0.00000001,t1INCH:UST
bitfinex,AAVEUSD,crypto,AAVE-US Dollar,USD,1,0.00001,0.00000001,tAAVE:USD
bitfinex,AAVEUSDT,crypto,AAVE-Tether USDt,USDT,1,0.00001,0.00000001,tAAVE:UST
bitfinex,ADABTC,crypto,Cardano ADA-Bitcoin,BTC,1,0.00001,0.00000001,tADABTC
bitfinex,ADAUSD,crypto,Cardano ADA-US Dollar,USD,1,0.00001,0.00000001,tADAUSD
bitfinex,ADAUSDT,crypto,Cardano ADA-Tether USDt,USDT,1,0.00001,0.00000001,tADAUST
bitfinex,AGIUSD,crypto,SingularityNET-US Dollar,USD,1,0.00001,0.00000001,tAGIUSD
bitfinex,AIDUSD,crypto,AidCoin-US Dollar,USD,1,0.00001,0.00000001,tAIDUSD
bitfinex,AIONUSD,crypto,Aion-US Dollar,USD,1,0.00001,0.00000001,tAIOUSD
bitfinex,ALBTUSD,crypto,AllianceBlock-US Dollar,USD,1,0.00001,0.00000001,tALBT:USD
bitfinex,ALBTUSDT,crypto,AllianceBlock-Tether USDt,USDT,1,0.00001,0.00000001,tALBT:UST
bitfinex,ALGOBTC,crypto,Algorand-Bitcoin,BTC,1,0.00001,0.00000001,tALGBTC
bitfinex,ALGOUSD,crypto,Algorand-US Dollar,USD,1,0.00001,0.00000001,tALGUSD
bitfinex,ALGOUSDT,crypto,Algorand-Tether USDt,USDT,1,0.00001,0.00000001,tALGUST
@@ -483,18 +485,13 @@ bitfinex,AMPLUSDT,crypto,Ampleforth-Tether USDt,USDT,1,0.00001,0.00000001,tAMPUS
bitfinex,ANTBTC,crypto,Aragon-Bitcoin,BTC,1,0.00001,0.00000001,tANTBTC
bitfinex,ANTETH,crypto,Aragon-Ethereum,ETH,1,0.00001,0.00000001,tANTETH
bitfinex,ANTUSD,crypto,Aragon-US Dollar,USD,1,0.00001,0.00000001,tANTUSD
bitfinex,ASTUSD,crypto,AirSwap-US Dollar,USD,1,0.00001,0.00000001,tASTUSD
bitfinex,ATMUSD,crypto,Atonomi-US Dollar,USD,1,0.00001,0.00000001,tATMUSD
bitfinex,ATOMBTC,crypto,Cosmos-Atom-Bitcoin,BTC,1,0.00001,0.00000001,tATOBTC
bitfinex,ATOMETH,crypto,Cosmos-Atom-Ethereum,ETH,1,0.00001,0.00000001,tATOETH
bitfinex,ATOMUSD,crypto,Cosmos-Atom-US Dollar,USD,1,0.00001,0.00000001,tATOUSD
bitfinex,AUCUSD,crypto,Auctus-US Dollar,USD,1,0.00001,0.00000001,tAUCUSD
bitfinex,AVAXUSD,crypto,Avalanche-US Dollar,USD,1,0.00001,0.00000001,tAVAX:USD
bitfinex,AVAXUSDT,crypto,Avalanche-Tether USDt,USDT,1,0.00001,0.00000001,tAVAX:UST
bitfinex,AVTUSD,crypto,Aventus-US Dollar,USD,1,0.00001,0.00000001,tAVTUSD
bitfinex,BCHBTC,crypto,Bitcoin Cash-Bitcoin,BTC,1,0.00001,0.00000001,tBABBTC
bitfinex,BCHUSD,crypto,Bitcoin Cash-US Dollar,USD,1,0.00001,0.00000001,tBABUSD
bitfinex,BCHUSDT,crypto,Bitcoin Cash-Tether USDt,USDT,1,0.00001,0.00000001,tBABUST
bitfinex,B21USD,crypto,B21-US Dollar,USD,1,0.00001,0.00000001,tB21X:USD
bitfinex,B21USDT,crypto,B21-Tether USDt,USDT,1,0.00001,0.00000001,tB21X:UST
bitfinex,BALUSD,crypto,Balancer-US Dollar,USD,1,0.00001,0.00000001,tBALUSD
bitfinex,BALUSDT,crypto,Balancer-Tether USDt,USDT,1,0.00001,0.00000001,tBALUST
bitfinex,BANDUSD,crypto,Band-US Dollar,USD,1,0.00001,0.00000001,tBAND:USD
@@ -502,9 +499,15 @@ bitfinex,BANDUSDT,crypto,Band-Tether USDt,USDT,1,0.00001,0.00000001,tBAND:UST
bitfinex,BATBTC,crypto,Basic Attention Token-Bitcoin,BTC,1,0.00001,0.00000001,tBATBTC
bitfinex,BATETH,crypto,Basic Attention Token-Ethereum,ETH,1,0.00001,0.00000001,tBATETH
bitfinex,BATUSD,crypto,Basic Attention Token-US Dollar,USD,1,0.00001,0.00000001,tBATUSD
bitfinex,BCHABCUSD,crypto,xec-US Dollar,USD,1,0.00001,0.00000001,tBCHABC:USD
bitfinex,BCHNUSD,crypto,BCH Node-US Dollar,USD,1,0.00001,0.00000001,tBCHN:USD
bitfinex,BESTUSD,crypto,Bitpanda-US Dollar,USD,1,0.00001,0.00000001,tBEST:USD
bitfinex,BFTUSD,crypto,BnkToTheFuture-US Dollar,USD,1,0.00001,0.00000001,tBFTUSD
bitfinex,BMIUSD,crypto,BridgeMutual-US Dollar,USD,1,0.00001,0.00000001,tBMIUSD
bitfinex,BMIUSDT,crypto,BridgeMutual-Tether USDt,USDT,1,0.00001,0.00000001,tBMIUST
bitfinex,BNTUSD,crypto,Bancor-US Dollar,USD,1,0.00001,0.00000001,tBNTUSD
bitfinex,BOXUSD,crypto,ContentBox-US Dollar,USD,1,0.00001,0.00000001,tBOXUSD
bitfinex,BOSONUSD,crypto,Boson Token-US Dollar,USD,1,0.00001,0.00000001,tBOSON:USD
bitfinex,BOSONUSDT,crypto,Boson Token-Tether USDt,USDT,1,0.00001,0.00000001,tBOSON:UST
bitfinex,BSVBTC,crypto,Bitcoin SV-Bitcoin,BTC,1,0.00001,0.00000001,tBSVBTC
bitfinex,BSVUSD,crypto,Bitcoin SV-US Dollar,USD,1,0.00001,0.00000001,tBSVUSD
bitfinex,BTCCNHT,crypto,Bitcoin-Tether CNHt,CNHT,1,0.00001,0.00000001,tBTC:CNHT
@@ -518,37 +521,33 @@ bitfinex,BTGBTC,crypto,Bitcoin Gold-Bitcoin,BTC,1,0.00001,0.00000001,tBTGBTC
bitfinex,BTGUSD,crypto,Bitcoin Gold-US Dollar,USD,1,0.00001,0.00000001,tBTGUSD
bitfinex,BTSEUSD,crypto,BTSE-US Dollar,USD,1,0.00001,0.00000001,tBTSE:USD
bitfinex,BTTUSD,crypto,BitTorrent-US Dollar,USD,1,0.00001,0.00000001,tBTTUSD
bitfinex,CBTUSD,crypto,CommerceBlock-US Dollar,USD,1,0.00001,0.00000001,tCBTUSD
bitfinex,CELUSD,crypto,Celsius-US Dollar,USD,1,0.00001,0.00000001,tCELUSD
bitfinex,CELUSDT,crypto,Celsius-Tether USDt,USDT,1,0.00001,0.00000001,tCELUST
bitfinex,CHEXUSD,crypto,CHEX-US Dollar,USD,1,0.00001,0.00000001,tCHEX:USD
bitfinex,CHZUSD,crypto,socios.com Chiliz-US Dollar,USD,1,0.00001,0.00000001,tCHZUSD
bitfinex,CHZUSDT,crypto,socios.com Chiliz-Tether USDt,USDT,1,0.00001,0.00000001,tCHZUST
bitfinex,CLOUSD,crypto,Callisto-US Dollar,USD,1,0.00001,0.00000001,tCLOUSD
bitfinex,CNDUSD,crypto,Cindicator-US Dollar,USD,1,0.00001,0.00000001,tCNDUSD
bitfinex,CNHCNHT,crypto,CNH-Tether CNHt,CNHT,1,0.00001,0.00000001,tCNH:CNHT
bitfinex,CNNUSD,crypto,Content Neutrality Network-US Dollar,USD,1,0.00001,0.00000001,tCNNUSD
bitfinex,COMPUSD,crypto,Compound-US Dollar,USD,1,0.00001,0.00000001,tCOMP:USD
bitfinex,COMPUSDT,crypto,Compound-Tether USDt,USDT,1,0.00001,0.00000001,tCOMP:UST
bitfinex,CSUSD,crypto,Credits-US Dollar,USD,1,0.00001,0.00000001,tCSXUSD
bitfinex,CTXCUSD,crypto,Cortex-US Dollar,USD,1,0.00001,0.00000001,tCTXUSD
bitfinex,CTKUSD,crypto,CERTIK-US Dollar,USD,1,0.00001,0.00000001,tCTKUSD
bitfinex,CTKUSDT,crypto,CERTIK-Tether USDt,USDT,1,0.00001,0.00000001,tCTKUST
bitfinex,DAIBTC,crypto,Dai Stablecoin-Bitcoin,BTC,1,0.00001,0.00000001,tDAIBTC
bitfinex,DAIETH,crypto,Dai Stablecoin-Ethereum,ETH,1,0.00001,0.00000001,tDAIETH
bitfinex,DAIUSD,crypto,Dai Stablecoin-US Dollar,USD,1,0.00001,0.00000001,tDAIUSD
bitfinex,DAPPUSD,crypto,DAPP-US Dollar,USD,1,0.00001,0.00000001,tDAPP:USD
bitfinex,DAPPUSDT,crypto,DAPP-Tether USDt,USDT,1,0.00001,0.00000001,tDAPP:UST
bitfinex,DATABTC,crypto,Streamr-Bitcoin,BTC,1,0.00001,0.00000001,tDATBTC
bitfinex,DATAUSD,crypto,Streamr-US Dollar,USD,1,0.00001,0.00000001,tDATUSD
bitfinex,DGBUSD,crypto,Digibyte-US Dollar,USD,1,0.00001,0.00000001,tDGBUSD
bitfinex,DGXUSD,crypto,Digix Gold Token-US Dollar,USD,1,0.00001,0.00000001,tDGXUSD
bitfinex,MDOGEBTC,crypto,MegaDOGE-Bitcoin,BTC,1,0.00001,0.00000001,tDOGBTC
bitfinex,DOGEUSD,crypto,DOGE-US Dollar,USD,1,0.00001,0.00000001,tDOGE:USD
bitfinex,DOGEUSDT,crypto,DOGE-Tether USDt,USDT,1,0.00001,0.00000001,tDOGE:UST
bitfinex,MDOGEUSD,crypto,MegaDOGE-US Dollar,USD,1,0.00001,0.00000001,tDOGUSD
bitfinex,MDOGEUSDT,crypto,MegaDOGE-Tether USDt,USDT,1,0.00001,0.00000001,tDOGUST
bitfinex,DOTBTC,crypto,Polkadot-Bitcoin,BTC,1,0.00001,0.00000001,tDOTBTC
bitfinex,DOTUSD,crypto,Polkadot-US Dollar,USD,1,0.00001,0.00000001,tDOTUSD
bitfinex,DOTUSDT,crypto,Polkadot-Tether USDt,USDT,1,0.00001,0.00000001,tDOTUST
bitfinex,DRGNUSD,crypto,Dragonchain-US Dollar,USD,1,0.00001,0.00000001,tDRNUSD
bitfinex,DASHBTC,crypto,Dash-Bitcoin,BTC,1,0.00001,0.00000001,tDSHBTC
bitfinex,DASHUSD,crypto,Dash-US Dollar,USD,1,0.00001,0.00000001,tDSHUSD
bitfinex,DTAUSD,crypto,Data-US Dollar,USD,1,0.00001,0.00000001,tDTAUSD
bitfinex,DTHUSD,crypto,Dether-US Dollar,USD,1,0.00001,0.00000001,tDTHUSD
bitfinex,DTUSD,crypto,DragonToken-US Dollar,USD,1,0.00001,0.00000001,tDTXUSD
bitfinex,DUSKBTC,crypto,Dusk Network-Bitcoin,BTC,1,0.00001,0.00000001,tDUSK:BTC
bitfinex,DUSKUSD,crypto,Dusk Network-US Dollar,USD,1,0.00001,0.00000001,tDUSK:USD
bitfinex,PNTBTC,crypto,pNetwork-Bitcoin,BTC,1,0.00001,0.00000001,tEDOBTC
@@ -556,7 +555,6 @@ bitfinex,PNTETH,crypto,pNetwork-Ethereum,ETH,1,0.00001,0.00000001,tEDOETH
bitfinex,PNTUSD,crypto,pNetwork-US Dollar,USD,1,0.00001,0.00000001,tEDOUSD
bitfinex,EGLDUSD,crypto,Elrond-US Dollar,USD,1,0.00001,0.00000001,tEGLD:USD
bitfinex,EGLDUSDT,crypto,Elrond-Tether USDt,USDT,1,0.00001,0.00000001,tEGLD:UST
bitfinex,ELFUSD,crypto,aelf-US Dollar,USD,1,0.00001,0.00000001,tELFUSD
bitfinex,ENJUSD,crypto,Enjin-US Dollar,USD,1,0.00001,0.00000001,tENJUSD
bitfinex,EOSBTC,crypto,EOS-Bitcoin,BTC,1,0.00001,0.00000001,tEOSBTC
bitfinex,EOSDTUSD,crypto,EOSDT-US Dollar,USD,1,0.00001,0.00000001,tEOSDT:USD
@@ -570,6 +568,9 @@ bitfinex,EOSUSDT,crypto,EOS-Tether USDt,USDT,1,0.00001,0.00000001,tEOSUST
bitfinex,ESSUSD,crypto,Essentia-US Dollar,USD,1,0.00001,0.00000001,tESSUSD
bitfinex,ETCBTC,crypto,Ethereum Classic-Bitcoin,BTC,1,0.00001,0.00000001,tETCBTC
bitfinex,ETCUSD,crypto,Ethereum Classic-US Dollar,USD,1,0.00001,0.00000001,tETCUSD
bitfinex,ETH2ETH,crypto,ETH2X-Ethereum,ETH,1,0.00001,0.00000001,tETH2X:ETH
bitfinex,ETH2USD,crypto,ETH2X-US Dollar,USD,1,0.00001,0.00000001,tETH2X:USD
bitfinex,ETH2USDT,crypto,ETH2X-Tether USDt,USDT,1,0.00001,0.00000001,tETH2X:UST
bitfinex,ETHBTC,crypto,Ethereum-Bitcoin,BTC,1,0.00001,0.00000001,tETHBTC
bitfinex,ETHEUR,crypto,Ethereum-Euro,EUR,1,0.00001,0.00000001,tETHEUR
bitfinex,ETHGBP,crypto,Ethereum-Pound Sterling,GBP,1,0.00001,0.00000001,tETHGBP
@@ -582,37 +583,49 @@ bitfinex,ETPUSD,crypto,ETP-US Dollar,USD,1,0.00001,0.00000001,tETPUSD
bitfinex,EURSUSD,crypto,EURS-US Dollar,USD,1,0.00001,0.00000001,tEUSUSD
bitfinex,EURTEUR,crypto,Tether EURt-Euro,EUR,1,0.00001,0.00000001,tEUTEUR
bitfinex,EURTUSD,crypto,Tether EURt-US Dollar,USD,1,0.00001,0.00000001,tEUTUSD
bitfinex,EVTUSD,crypto,Ethfinex Voting Token-US Dollar,USD,1,0.00001,0.00000001,tEVTUSD
bitfinex,EURTUSDT,crypto,Tether EURt-Tether USDt,USDT,1,0.00001,0.00000001,tEUTUST
bitfinex,EXRDBTC,crypto,E-RADIX-Bitcoin,BTC,1,0.00001,0.00000001,tEXRD:BTC
bitfinex,EXRDUSD,crypto,E-RADIX-US Dollar,USD,1,0.00001,0.00000001,tEXRD:USD
bitfinex,FCLUSD,crypto,Fractal-US Dollar,USD,1,0.00001,0.00000001,tFCLUSD
bitfinex,FCLUSDT,crypto,Fractal-Tether USDt,USDT,1,0.00001,0.00000001,tFCLUST
bitfinex,FETUSD,crypto,Fetch.AI-US Dollar,USD,1,0.00001,0.00000001,tFETUSD
bitfinex,FETUSDT,crypto,Fetch.AI-Tether USDt,USDT,1,0.00001,0.00000001,tFETUST
bitfinex,FILUSD,crypto,Filecoin-US Dollar,USD,1,0.00001,0.00000001,tFILUSD
bitfinex,FILUSDT,crypto,Filecoin-Tether USDt,USDT,1,0.00001,0.00000001,tFILUST
bitfinex,FOAUSD,crypto,FOAM-US Dollar,USD,1,0.00001,0.00000001,tFOAUSD
bitfinex,FSNUSD,crypto,Fusion-US Dollar,USD,1,0.00001,0.00000001,tFSNUSD
bitfinex,FORTHUSD,crypto,FORTH-US Dollar,USD,1,0.00001,0.00000001,tFORTH:USD
bitfinex,FORTHUSDT,crypto,FORTH-Tether USDt,USDT,1,0.00001,0.00000001,tFORTH:UST
bitfinex,FTMUSD,crypto,Fantom-US Dollar,USD,1,0.00001,0.00000001,tFTMUSD
bitfinex,FTMUSDT,crypto,Fantom-Tether USDt,USDT,1,0.00001,0.00000001,tFTMUST
bitfinex,FTTUSD,crypto,FTX.com-US Dollar,USD,1,0.00001,0.00000001,tFTTUSD
bitfinex,FTTUSDT,crypto,FTX.com-Tether USDt,USDT,1,0.00001,0.00000001,tFTTUST
bitfinex,FUNUSD,crypto,FunFair-US Dollar,USD,1,0.00001,0.00000001,tFUNUSD
bitfinex,GENUSD,crypto,DAOstack-US Dollar,USD,1,0.00001,0.00000001,tGENUSD
bitfinex,GNOUSD,crypto,Gnosis-US Dollar,USD,1,0.00001,0.00000001,tGNOUSD
bitfinex,GNTBTC,crypto,Golem-Bitcoin,BTC,1,0.00001,0.00000001,tGNTBTC
bitfinex,GNTETH,crypto,Golem-Ethereum,ETH,1,0.00001,0.00000001,tGNTETH
bitfinex,GNTUSD,crypto,Golem-US Dollar,USD,1,0.00001,0.00000001,tGNTUSD
bitfinex,GLMUSD,crypto,Golem-US Dollar,USD,1,0.00001,0.00000001,tGNTUSD
bitfinex,GOTEUR,crypto,ParkinGO-Euro,EUR,1,0.00001,0.00000001,tGOTEUR
bitfinex,GOTUSD,crypto,ParkinGO-US Dollar,USD,1,0.00001,0.00000001,tGOTUSD
bitfinex,GUSDUSD,crypto,GUSD-US Dollar,USD,1,0.00001,0.00000001,tGSDUSD
bitfinex,GRTUSD,crypto,The Graph-US Dollar,USD,1,0.00001,0.00000001,tGRTUSD
bitfinex,GRTUSDT,crypto,The Graph-Tether USDt,USDT,1,0.00001,0.00000001,tGRTUST
bitfinex,GTXUSD,crypto,Gate.IO-US Dollar,USD,1,0.00001,0.00000001,tGTXUSD
bitfinex,GTXUSDT,crypto,Gate.IO-Tether USDt,USDT,1,0.00001,0.00000001,tGTXUST
bitfinex,HOTUSD,crypto,Hydro Protocol-US Dollar,USD,1,0.00001,0.00000001,tHOTUSD
bitfinex,IMPUSD,crypto,Ether Kingdoms-US Dollar,USD,1,0.00001,0.00000001,tIMPUSD
bitfinex,IOSTUSD,crypto,IOSToken-US Dollar,USD,1,0.00001,0.00000001,tIOSUSD
bitfinex,HEZUSD,crypto,Hermez-US Dollar,USD,1,0.00001,0.00000001,tHEZUSD
bitfinex,HEZUSDT,crypto,Hermez-Tether USDt,USDT,1,0.00001,0.00000001,tHEZUST
bitfinex,ICEUSD,crypto,ICE-US Dollar,USD,1,0.00001,0.00000001,tICEUSD
bitfinex,ICPBTC,crypto,Dfinity-Bitcoin,BTC,1,0.00001,0.00000001,tICPBTC
bitfinex,ICPUSD,crypto,Dfinity-US Dollar,USD,1,0.00001,0.00000001,tICPUSD
bitfinex,ICPUSDT,crypto,Dfinity-Tether USDt,USDT,1,0.00001,0.00000001,tICPUST
bitfinex,IDUSD,crypto,Everest (ID)-US Dollar,USD,1,0.00001,0.00000001,tIDXUSD
bitfinex,IDUSDT,crypto,Everest (ID)-Tether USDt,USDT,1,0.00001,0.00000001,tIDXUST
bitfinex,IOTABTC,crypto,Iota-Bitcoin,BTC,1,0.00001,0.00000001,tIOTBTC
bitfinex,IOTAETH,crypto,Iota-Ethereum,ETH,1,0.00001,0.00000001,tIOTETH
bitfinex,IOTAEUR,crypto,Iota-Euro,EUR,1,0.00001,0.00000001,tIOTEUR
bitfinex,IOTAGBP,crypto,Iota-Pound Sterling,GBP,1,0.00001,0.00000001,tIOTGBP
bitfinex,IOTAJPY,crypto,Iota-Japanese Yen,JPY,1,0.00001,0.00000001,tIOTJPY
bitfinex,IOTAUSD,crypto,Iota-US Dollar,USD,1,0.00001,0.00000001,tIOTUSD
bitfinex,IQXEOS,crypto,Everipedia-EOS,EOS,1,0.00001,0.00000001,tIQXEOS
bitfinex,IQXUSD,crypto,Everipedia-US Dollar,USD,1,0.00001,0.00000001,tIQXUSD
bitfinex,IQXUSDT,crypto,Everipedia-Tether USDt,USDT,1,0.00001,0.00000001,tIQXUST
bitfinex,JSTBTC,crypto,JST-Bitcoin,BTC,1,0.00001,0.00000001,tJSTBTC
bitfinex,JSTUSD,crypto,JST-US Dollar,USD,1,0.00001,0.00000001,tJSTUSD
bitfinex,JSTUSDT,crypto,JST-Tether USDt,USDT,1,0.00001,0.00000001,tJSTUST
bitfinex,KANUSD,crypto,BitKan-US Dollar,USD,1,0.00001,0.00000001,tKANUSD
bitfinex,KANUSDT,crypto,BitKan-Tether USDt,USDT,1,0.00001,0.00000001,tKANUST
bitfinex,KNCBTC,crypto,Kyber-Bitcoin,BTC,1,0.00001,0.00000001,tKNCBTC
@@ -626,25 +639,23 @@ bitfinex,LEOUSD,crypto,Unus Sed LEO-US Dollar,USD,1,0.00001,0.00000001,tLEOUSD
bitfinex,LEOUSDT,crypto,Unus Sed LEO-Tether USDt,USDT,1,0.00001,0.00000001,tLEOUST
bitfinex,LINKUSD,crypto,ChainLink-US Dollar,USD,1,0.00001,0.00000001,tLINK:USD
bitfinex,LINKUSDT,crypto,ChainLink-Tether USDt,USDT,1,0.00001,0.00000001,tLINK:UST
bitfinex,LOOUSD,crypto,Loom-US Dollar,USD,1,0.00001,0.00000001,tLOOUSD
bitfinex,LRCBTC,crypto,Loopring-Bitcoin,BTC,1,0.00001,0.00000001,tLRCBTC
bitfinex,LRCUSD,crypto,Loopring-US Dollar,USD,1,0.00001,0.00000001,tLRCUSD
bitfinex,LTCBTC,crypto,Litecoin-Bitcoin,BTC,1,0.00001,0.00000001,tLTCBTC
bitfinex,LTCUSD,crypto,Litecoin-US Dollar,USD,1,0.00001,0.00000001,tLTCUSD
bitfinex,LTCUSDT,crypto,Litecoin-Tether USDt,USDT,1,0.00001,0.00000001,tLTCUST
bitfinex,LUNAUSD,crypto,LUNA-US Dollar,USD,1,0.00001,0.00000001,tLUNA:USD
bitfinex,LUNAUSDT,crypto,LUNA-Tether USDt,USDT,1,0.00001,0.00000001,tLUNA:UST
bitfinex,LYMUSD,crypto,Lympo-US Dollar,USD,1,0.00001,0.00000001,tLYMUSD
bitfinex,MANUSD,crypto,Matrix-US Dollar,USD,1,0.00001,0.00000001,tMANUSD
bitfinex,MGOUSD,crypto,MobileGo-US Dollar,USD,1,0.00001,0.00000001,tMGOUSD
bitfinex,MITHUSD,crypto,Mithril-US Dollar,USD,1,0.00001,0.00000001,tMITUSD
bitfinex,MKRBTC,crypto,Maker-Bitcoin,BTC,1,0.00001,0.00000001,tMKRBTC
bitfinex,MKRETH,crypto,Maker-Ethereum,ETH,1,0.00001,0.00000001,tMKRETH
bitfinex,MIRUSD,crypto,Mirror Protocol-US Dollar,USD,1,0.00001,0.00000001,tMIRUSD
bitfinex,MIRUSDT,crypto,Mirror Protocol-Tether USDt,USDT,1,0.00001,0.00000001,tMIRUST
bitfinex,MKRUSD,crypto,Maker-US Dollar,USD,1,0.00001,0.00000001,tMKRUSD
bitfinex,MLNUSD,crypto,Melon-US Dollar,USD,1,0.00001,0.00000001,tMLNUSD
bitfinex,MANABTC,crypto,Decentraland-Bitcoin,BTC,1,0.00001,0.00000001,tMNABTC
bitfinex,MANAUSD,crypto,Decentraland-US Dollar,USD,1,0.00001,0.00000001,tMNAUSD
bitfinex,MTNUSD,crypto,Medicalchain-US Dollar,USD,1,0.00001,0.00000001,tMTNUSD
bitfinex,NCASHUSD,crypto,Nucleus Vision-US Dollar,USD,1,0.00001,0.00000001,tNCAUSD
bitfinex,NECETH,crypto,Ethfinex Nectar Token-Ethereum,ETH,1,0.00001,0.00000001,tNECETH
bitfinex,MOBUSD,crypto,Mobilecoin-US Dollar,USD,1,0.00001,0.00000001,tMOBUSD
bitfinex,MOBUSDT,crypto,Mobilecoin-Tether USDt,USDT,1,0.00001,0.00000001,tMOBUST
bitfinex,NEARUSD,crypto,Near-US Dollar,USD,1,0.00001,0.00000001,tNEAR:USD
bitfinex,NEARUSDT,crypto,Near-Tether USDt,USDT,1,0.00001,0.00000001,tNEAR:UST
bitfinex,NECUSD,crypto,Ethfinex Nectar Token-US Dollar,USD,1,0.00001,0.00000001,tNECUSD
bitfinex,NEOBTC,crypto,NEO-Bitcoin,BTC,1,0.00001,0.00000001,tNEOBTC
bitfinex,NEOETH,crypto,NEO-Ethereum,ETH,1,0.00001,0.00000001,tNEOETH
@@ -652,59 +663,59 @@ bitfinex,NEOEUR,crypto,NEO-Euro,EUR,1,0.00001,0.00000001,tNEOEUR
bitfinex,NEOGBP,crypto,NEO-Pound Sterling,GBP,1,0.00001,0.00000001,tNEOGBP
bitfinex,NEOJPY,crypto,NEO-Japanese Yen,JPY,1,0.00001,0.00000001,tNEOJPY
bitfinex,NEOUSD,crypto,NEO-US Dollar,USD,1,0.00001,0.00000001,tNEOUSD
bitfinex,NUTUSD,crypto,Native Utility Token-US Dollar,USD,1,0.00001,0.00000001,tNUTUSD
bitfinex,NUTUSDT,crypto,Native Utility Token-Tether USDt,USDT,1,0.00001,0.00000001,tNUTUST
bitfinex,NEXOBTC,crypto,NEXO-Bitcoin,BTC,1,0.00001,0.00000001,tNEXO:BTC
bitfinex,NEXOUSD,crypto,NEXO-US Dollar,USD,1,0.00001,0.00000001,tNEXO:USD
bitfinex,NEXOUSDT,crypto,NEXO-Tether USDt,USDT,1,0.00001,0.00000001,tNEXO:UST
bitfinex,OCEANUSD,crypto,OCEAN protocol-US Dollar,USD,1,0.00001,0.00000001,tOCEAN:USD
bitfinex,OCEANUSDT,crypto,OCEAN protocol-Tether USDt,USDT,1,0.00001,0.00000001,tOCEAN:UST
bitfinex,ODEUSD,crypto,Odem-US Dollar,USD,1,0.00001,0.00000001,tODEUSD
bitfinex,OKBUSD,crypto,OKB-US Dollar,USD,1,0.00001,0.00000001,tOKBUSD
bitfinex,OKBUSDT,crypto,OKB-Tether USDt,USDT,1,0.00001,0.00000001,tOKBUST
bitfinex,OMGBTC,crypto,OmiseGO-Bitcoin,BTC,1,0.00001,0.00000001,tOMGBTC
bitfinex,OMGETH,crypto,OmiseGO-Ethereum,ETH,1,0.00001,0.00000001,tOMGETH
bitfinex,OMGUSD,crypto,OmiseGO-US Dollar,USD,1,0.00001,0.00000001,tOMGUSD
bitfinex,OMNIBTC,crypto,Omni-Bitcoin,BTC,1,0.00001,0.00000001,tOMNBTC
bitfinex,OMNIUSD,crypto,Omni-US Dollar,USD,1,0.00001,0.00000001,tOMNUSD
bitfinex,ONLUSD,crypto,On.Live-US Dollar,USD,1,0.00001,0.00000001,tONLUSD
bitfinex,ORSUSD,crypto,ORS-US Dollar,USD,1,0.00001,0.00000001,tORSUSD
bitfinex,PAIUSD,crypto,PAI Project-US Dollar,USD,1,0.00001,0.00000001,tPAIUSD
bitfinex,OXYUSD,crypto,Oxygen-US Dollar,USD,1,0.00001,0.00000001,tOXYUSD
bitfinex,OXYUSDT,crypto,Oxygen-Tether USDt,USDT,1,0.00001,0.00000001,tOXYUST
bitfinex,PASSUSD,crypto,Blockpass-US Dollar,USD,1,0.00001,0.00000001,tPASUSD
bitfinex,PAXUSD,crypto,Paxos-US Dollar,USD,1,0.00001,0.00000001,tPAXUSD
bitfinex,PAXUSDT,crypto,Paxos-Tether USDt,USDT,1,0.00001,0.00000001,tPAXUST
bitfinex,PLANETSUSD,crypto,PLANETS-US Dollar,USD,1,0.00001,0.00000001,tPLANETS:USD
bitfinex,PLANETSUSDT,crypto,PLANETS-Tether USDt,USDT,1,0.00001,0.00000001,tPLANETS:UST
bitfinex,PLUUSD,crypto,Pluton-US Dollar,USD,1,0.00001,0.00000001,tPLUUSD
bitfinex,PNKETH,crypto,Kleros-Ethereum,ETH,1,0.00001,0.00000001,tPNKETH
bitfinex,PNKUSD,crypto,Kleros-US Dollar,USD,1,0.00001,0.00000001,tPNKUSD
bitfinex,POAUSD,crypto,POA Network (erc20)-US Dollar,USD,1,0.00001,0.00000001,tPOAUSD
bitfinex,POLYUSD,crypto,Polymath-US Dollar,USD,1,0.00001,0.00000001,tPOYUSD
bitfinex,QASHUSD,crypto,QASH-US Dollar,USD,1,0.00001,0.00000001,tQSHUSD
bitfinex,QTFBTC,crypto,Quantfury-Bitcoin,BTC,1,0.00001,0.00000001,tQTFBTC
bitfinex,QTFUSD,crypto,Quantfury-US Dollar,USD,1,0.00001,0.00000001,tQTFUSD
bitfinex,QTUMBTC,crypto,Qtum-Bitcoin,BTC,1,0.00001,0.00000001,tQTMBTC
bitfinex,QTUMUSD,crypto,Qtum-US Dollar,USD,1,0.00001,0.00000001,tQTMUSD
bitfinex,RBTCBTC,crypto,RBTC-Bitcoin,BTC,1,0.00001,0.00000001,tRBTBTC
bitfinex,RBTCUSD,crypto,RBTC-US Dollar,USD,1,0.00001,0.00000001,tRBTUSD
bitfinex,RCNUSD,crypto,RCN-US Dollar,USD,1,0.00001,0.00000001,tRCNUSD
bitfinex,RDNUSD,crypto,Raiden-US Dollar,USD,1,0.00001,0.00000001,tRDNUSD
bitfinex,REP2BTC,crypto,Augur-Bitcoin,BTC,1,0.00001,0.00000001,tREPBTC
bitfinex,REP2USD,crypto,Augur-US Dollar,USD,1,0.00001,0.00000001,tREPUSD
bitfinex,REQUSD,crypto,Request Network-US Dollar,USD,1,0.00001,0.00000001,tREQUSD
bitfinex,RIFUSD,crypto,RIF-US Dollar,USD,1,0.00001,0.00000001,tRIFUSD
bitfinex,RINGXUSD,crypto,RingX-US Dollar,USD,1,0.00001,0.00000001,tRINGX:USD
bitfinex,RLCBTC,crypto,iExec-Bitcoin,BTC,1,0.00001,0.00000001,tRLCBTC
bitfinex,RLCUSD,crypto,iExec-US Dollar,USD,1,0.00001,0.00000001,tRLCUSD
bitfinex,RRBUSD,crypto,RenrenBit-US Dollar,USD,1,0.00001,0.00000001,tRRBUSD
bitfinex,RRBUSDT,crypto,RenrenBit-Tether USDt,USDT,1,0.00001,0.00000001,tRRBUST
bitfinex,RRTUSD,crypto,Recovery Right Tokens-US Dollar,USD,1,0.00001,0.00000001,tRRTUSD
bitfinex,RTEUSD,crypto,Rate3-US Dollar,USD,1,0.00001,0.00000001,tRTEUSD
bitfinex,SANBTC,crypto,Santiment-Bitcoin,BTC,1,0.00001,0.00000001,tSANBTC
bitfinex,SANETH,crypto,Santiment-Ethereum,ETH,1,0.00001,0.00000001,tSANETH
bitfinex,SANUSD,crypto,Santiment-US Dollar,USD,1,0.00001,0.00000001,tSANUSD
bitfinex,XDUSD,crypto,Data Transaction Token-US Dollar,USD,1,0.00001,0.00000001,tSCRUSD
bitfinex,SEEUSD,crypto,Seer-US Dollar,USD,1,0.00001,0.00000001,tSEEUSD
bitfinex,SNGLSUSD,crypto,SingularDTV-US Dollar,USD,1,0.00001,0.00000001,tSNGUSD
bitfinex,SNTUSD,crypto,Status-US Dollar,USD,1,0.00001,0.00000001,tSNTUSD
bitfinex,SNXUSD,crypto,Synthetix Network-US Dollar,USD,1,0.00001,0.00000001,tSNXUSD
bitfinex,SNXUSDT,crypto,Synthetix Network-Tether USDt,USDT,1,0.00001,0.00000001,tSNXUST
bitfinex,SPANKUSD,crypto,SpankChain-US Dollar,USD,1,0.00001,0.00000001,tSPKUSD
bitfinex,SOLUSD,crypto,Solana-US Dollar,USD,1,0.00001,0.00000001,tSOLUSD
bitfinex,SOLUSDT,crypto,Solana-Tether USDt,USDT,1,0.00001,0.00000001,tSOLUST
bitfinex,STORJUSD,crypto,Storj-US Dollar,USD,1,0.00001,0.00000001,tSTJUSD
bitfinex,SWMUSD,crypto,Swarm-US Dollar,USD,1,0.00001,0.00000001,tSWMUSD
bitfinex,TKNUSD,crypto,TokenCard-US Dollar,USD,1,0.00001,0.00000001,tTKNUSD
bitfinex,TNBUSD,crypto,Time New Bank-US Dollar,USD,1,0.00001,0.00000001,tTNBUSD
bitfinex,TRIUSD,crypto,Tripio-US Dollar,USD,1,0.00001,0.00000001,tTRIUSD
bitfinex,SUKUUSD,crypto,SUKU-US Dollar,USD,1,0.00001,0.00000001,tSUKU:USD
bitfinex,SUKUUSDT,crypto,SUKU-Tether USDt,USDT,1,0.00001,0.00000001,tSUKU:UST
bitfinex,SUNUSD,crypto,SUN-US Dollar,USD,1,0.00001,0.00000001,tSUNUSD
bitfinex,SUNUSDT,crypto,SUN-Tether USDt,USDT,1,0.00001,0.00000001,tSUNUST
bitfinex,SUSHIUSD,crypto,SUSHI-US Dollar,USD,1,0.00001,0.00000001,tSUSHI:USD
bitfinex,SUSHIUSDT,crypto,SUSHI-Tether USDt,USDT,1,0.00001,0.00000001,tSUSHI:UST
bitfinex,TERRAUSTUSD,crypto,TerraUST-US Dollar,USD,1,0.00001,0.00000001,tTERRAUST:USD
bitfinex,TERRAUSTUSDT,crypto,TerraUST-Tether USDt,USDT,1,0.00001,0.00000001,tTERRAUST:UST
bitfinex,TRXBTC,crypto,TRON-Bitcoin,BTC,1,0.00001,0.00000001,tTRXBTC
bitfinex,TRXETH,crypto,TRON-Ethereum,ETH,1,0.00001,0.00000001,tTRXETH
bitfinex,TRXEUR,crypto,TRON-Euro,EUR,1,0.00001,0.00000001,tTRXEUR
@@ -713,51 +724,52 @@ bitfinex,TUSDUSD,crypto,TrueUSD-US Dollar,USD,1,0.00001,0.00000001,tTSDUSD
bitfinex,TUSDUSDT,crypto,TrueUSD-Tether USDt,USDT,1,0.00001,0.00000001,tTSDUST
bitfinex,USDCUSD,crypto,USDc-US Dollar,USD,1,0.00001,0.00000001,tUDCUSD
bitfinex,USDCUSDT,crypto,USDc-Tether USDt,USDT,1,0.00001,0.00000001,tUDCUST
bitfinex,UFRUSD,crypto,Upfiring-US Dollar,USD,1,0.00001,0.00000001,tUFRUSD
bitfinex,UNIUSD,crypto,Uniswap-US Dollar,USD,1,0.00001,0.00000001,tUNIUSD
bitfinex,UNIUSDT,crypto,Uniswap-Tether USDt,USDT,1,0.00001,0.00000001,tUNIUST
bitfinex,UOPUSD,crypto,Utopia-US Dollar,USD,1,0.00001,0.00000001,tUOPUSD
bitfinex,UOPUSDT,crypto,Utopia-Tether USDt,USDT,1,0.00001,0.00000001,tUOPUST
bitfinex,UOSBTC,crypto,Ultra-Bitcoin,BTC,1,0.00001,0.00000001,tUOSBTC
bitfinex,UOSUSD,crypto,Ultra-US Dollar,USD,1,0.00001,0.00000001,tUOSUSD
bitfinex,USDKUSD,crypto,USDk-US Dollar,USD,1,0.00001,0.00000001,tUSKUSD
bitfinex,USDTCNHT,crypto,Tether USDt-Tether CNHt,CNHT,1,0.00001,0.00000001,tUST:CNHT
bitfinex,USDTUSD,crypto,Tether USDt-US Dollar,USD,1,0.00001,0.00000001,tUSTUSD
bitfinex,UTKUSD,crypto,UTRUST-US Dollar,USD,1,0.00001,0.00000001,tUTKUSD
bitfinex,UTNPUSD,crypto,Universa-US Dollar,USD,1,0.00001,0.00000001,tUTNUSD
bitfinex,VEEUSD,crypto,BLOCKv-US Dollar,USD,1,0.00001,0.00000001,tVEEUSD
bitfinex,VELOUSD,crypto,VELO-US Dollar,USD,1,0.00001,0.00000001,tVELO:USD
bitfinex,VELOUSDT,crypto,VELO-Tether USDt,USDT,1,0.00001,0.00000001,tVELO:UST
bitfinex,VETBTC,crypto,VeChain-Bitcoin,BTC,1,0.00001,0.00000001,tVETBTC
bitfinex,VETUSD,crypto,VeChain-US Dollar,USD,1,0.00001,0.00000001,tVETUSD
bitfinex,VLDUSD,crypto,Vetri-US Dollar,USD,1,0.00001,0.00000001,tVLDUSD
bitfinex,VSYSBTC,crypto,V-SYSTEMS-Bitcoin,BTC,1,0.00001,0.00000001,tVSYBTC
bitfinex,VSYSUSD,crypto,V-SYSTEMS-US Dollar,USD,1,0.00001,0.00000001,tVSYUSD
bitfinex,WAXUSD,crypto,WAX-US Dollar,USD,1,0.00001,0.00000001,tWAXUSD
bitfinex,WBTCETH,crypto,Wrapped Bitcoin-Ethereum,ETH,1,0.00001,0.00000001,tWBTETH
bitfinex,WBTCUSD,crypto,Wrapped Bitcoin-US Dollar,USD,1,0.00001,0.00000001,tWBTUSD
bitfinex,WPRUSD,crypto,WePower-US Dollar,USD,1,0.00001,0.00000001,tWPRUSD
bitfinex,WTCUSD,crypto,Walton-US Dollar,USD,1,0.00001,0.00000001,tWTCUSD
bitfinex,XAUTBTC,crypto,Tether XAUt-Bitcoin,BTC,1,0.00001,0.00000001,tXAUT:BTC
bitfinex,XAUTUSD,crypto,Tether XAUt-US Dollar,USD,1,0.00001,0.00000001,tXAUT:USD
bitfinex,XAUTUSDT,crypto,Tether XAUt-Tether USDt,USDT,1,0.00001,0.00000001,tXAUT:UST
bitfinex,XCHFETH,crypto,CryptoFranc-Ethereum,ETH,1,0.00001,0.00000001,tXCHETH
bitfinex,XCHFUSD,crypto,CryptoFranc-US Dollar,USD,1,0.00001,0.00000001,tXCHUSD
bitfinex,XDCUSD,crypto,XinFin-US Dollar,USD,1,0.00001,0.00000001,tXDCUSD
bitfinex,XDCUSDT,crypto,XinFin-Tether USDt,USDT,1,0.00001,0.00000001,tXDCUST
bitfinex,XLMBTC,crypto,Stellar Lumen-Bitcoin,BTC,1,0.00001,0.00000001,tXLMBTC
bitfinex,XLMETH,crypto,Stellar Lumen-Ethereum,ETH,1,0.00001,0.00000001,tXLMETH
bitfinex,XLMUSD,crypto,Stellar Lumen-US Dollar,USD,1,0.00001,0.00000001,tXLMUSD
bitfinex,XLMUSDT,crypto,Stellar Lumen-Tether USDt,USDT,1,0.00001,0.00000001,tXLMUST
bitfinex,XMRBTC,crypto,Monero-Bitcoin,BTC,1,0.00001,0.00000001,tXMRBTC
bitfinex,XMRUSD,crypto,Monero-US Dollar,USD,1,0.00001,0.00000001,tXMRUSD
bitfinex,XMRUSDT,crypto,Monero-Tether USDt,USDT,1,0.00001,0.00000001,tXMRUST
bitfinex,XRAUSD,crypto,Xriba-US Dollar,USD,1,0.00001,0.00000001,tXRAUSD
bitfinex,XRPBTC,crypto,Ripple-Bitcoin,BTC,1,0.00001,0.00000001,tXRPBTC
bitfinex,XRPUSD,crypto,Ripple-US Dollar,USD,1,0.00001,0.00000001,tXRPUSD
bitfinex,XRPUSDT,crypto,Ripple-Tether USDt,USDT,1,0.00001,0.00000001,tXRPUST
bitfinex,XSNUSD,crypto,Stakenet-US Dollar,USD,1,0.00001,0.00000001,tXSNUSD
bitfinex,XTZBTC,crypto,Tezos-Bitcoin,BTC,1,0.00001,0.00000001,tXTZBTC
bitfinex,XTZUSD,crypto,Tezos-US Dollar,USD,1,0.00001,0.00000001,tXTZUSD
bitfinex,XVGUSD,crypto,Verge-US Dollar,USD,1,0.00001,0.00000001,tXVGUSD
bitfinex,YFIUSD,crypto,Yearn.Finance-US Dollar,USD,1,0.00001,0.00000001,tYFIUSD
bitfinex,YFIUSDT,crypto,Yearn.Finance-Tether USDt,USDT,1,0.00001,0.00000001,tYFIUST
bitfinex,YEEDUSD,crypto,Yggdrash-US Dollar,USD,1,0.00001,0.00000001,tYGGUSD
bitfinex,YOYOWUSD,crypto,YOYOW-US Dollar,USD,1,0.00001,0.00000001,tYYWUSD
bitfinex,ZBTUSD,crypto,ZB Token-US Dollar,USD,1,0.00001,0.00000001,tZBTUSD
bitfinex,MCSUSD,crypto,MCS-US Dollar,USD,1,0.00001,0.00000001,tYGGUSD
bitfinex,ZCNUSD,crypto,0Chain-US Dollar,USD,1,0.00001,0.00000001,tZCNUSD
bitfinex,ZECBTC,crypto,Zcash-Bitcoin,BTC,1,0.00001,0.00000001,tZECBTC
bitfinex,ZECUSD,crypto,Zcash-US Dollar,USD,1,0.00001,0.00000001,tZECUSD
bitfinex,ZILBTC,crypto,Zilliqa-Bitcoin,BTC,1,0.00001,0.00000001,tZILBTC
bitfinex,ZILUSD,crypto,Zilliqa-US Dollar,USD,1,0.00001,0.00000001,tZILUSD
bitfinex,ZRXBTC,crypto,0x-Bitcoin,BTC,1,0.00001,0.00000001,tZRXBTC
bitfinex,ZRXETH,crypto,0x-Ethereum,ETH,1,0.00001,0.00000001,tZRXETH
1 market,symbol,type,description,quote_currency,contract_multiplier,minimum_price_variation,lot_size,market_ticker
467 bitfinex,AMPLBTC,crypto,Ampleforth-Bitcoin,BTC,1,0.00001,0.00000001,tAMPBTC bitfinex,ALGOUSD,crypto,Algorand-US Dollar,USD,1,0.00001,0.00000001,tALGUSD
468 bitfinex,AMPLUSD,crypto,Ampleforth-US Dollar,USD,1,0.00001,0.00000001,tAMPUSD bitfinex,ALGOUSDT,crypto,Algorand-Tether USDt,USDT,1,0.00001,0.00000001,tALGUST
469 bitfinex,AMPLUSDT,crypto,Ampleforth-Tether USDt,USDT,1,0.00001,0.00000001,tAMPUST bitfinex,AMPLBTC,crypto,Ampleforth-Bitcoin,BTC,1,0.00001,0.00000001,tAMPBTC
470 bitfinex,ANTBTC,crypto,Aragon-Bitcoin,BTC,1,0.00001,0.00000001,tANTBTC bitfinex,AMPLUSD,crypto,Ampleforth-US Dollar,USD,1,0.00001,0.00000001,tAMPUSD
471 bitfinex,AMPLUSDT,crypto,Ampleforth-Tether USDt,USDT,1,0.00001,0.00000001,tAMPUST
472 bitfinex,ANTBTC,crypto,Aragon-Bitcoin,BTC,1,0.00001,0.00000001,tANTBTC
473 bitfinex,ANTETH,crypto,Aragon-Ethereum,ETH,1,0.00001,0.00000001,tANTETH
474 bitfinex,ANTETH,crypto,Aragon-Ethereum,ETH,1,0.00001,0.00000001,tANTETH bitfinex,ANTUSD,crypto,Aragon-US Dollar,USD,1,0.00001,0.00000001,tANTUSD
475 bitfinex,ANTUSD,crypto,Aragon-US Dollar,USD,1,0.00001,0.00000001,tANTUSD bitfinex,ATOMBTC,crypto,Cosmos-Atom-Bitcoin,BTC,1,0.00001,0.00000001,tATOBTC
476 bitfinex,ASTUSD,crypto,AirSwap-US Dollar,USD,1,0.00001,0.00000001,tASTUSD bitfinex,ATOMETH,crypto,Cosmos-Atom-Ethereum,ETH,1,0.00001,0.00000001,tATOETH
477 bitfinex,ATMUSD,crypto,Atonomi-US Dollar,USD,1,0.00001,0.00000001,tATMUSD bitfinex,ATOMUSD,crypto,Cosmos-Atom-US Dollar,USD,1,0.00001,0.00000001,tATOUSD
478 bitfinex,ATOMBTC,crypto,Cosmos-Atom-Bitcoin,BTC,1,0.00001,0.00000001,tATOBTC bitfinex,AVAXUSD,crypto,Avalanche-US Dollar,USD,1,0.00001,0.00000001,tAVAX:USD
bitfinex,ATOMETH,crypto,Cosmos-Atom-Ethereum,ETH,1,0.00001,0.00000001,tATOETH
479 bitfinex,ATOMUSD,crypto,Cosmos-Atom-US Dollar,USD,1,0.00001,0.00000001,tATOUSD bitfinex,AVAXUSDT,crypto,Avalanche-Tether USDt,USDT,1,0.00001,0.00000001,tAVAX:UST
480 bitfinex,AUCUSD,crypto,Auctus-US Dollar,USD,1,0.00001,0.00000001,tAUCUSD bitfinex,B21USD,crypto,B21-US Dollar,USD,1,0.00001,0.00000001,tB21X:USD
481 bitfinex,AVAXUSD,crypto,Avalanche-US Dollar,USD,1,0.00001,0.00000001,tAVAX:USD bitfinex,B21USDT,crypto,B21-Tether USDt,USDT,1,0.00001,0.00000001,tB21X:UST
485 bitfinex,BCHUSD,crypto,Bitcoin Cash-US Dollar,USD,1,0.00001,0.00000001,tBABUSD bitfinex,BANDUSDT,crypto,Band-Tether USDt,USDT,1,0.00001,0.00000001,tBAND:UST
486 bitfinex,BCHUSDT,crypto,Bitcoin Cash-Tether USDt,USDT,1,0.00001,0.00000001,tBABUST bitfinex,BATBTC,crypto,Basic Attention Token-Bitcoin,BTC,1,0.00001,0.00000001,tBATBTC
487 bitfinex,BALUSD,crypto,Balancer-US Dollar,USD,1,0.00001,0.00000001,tBALUSD bitfinex,BATETH,crypto,Basic Attention Token-Ethereum,ETH,1,0.00001,0.00000001,tBATETH
bitfinex,BALUSDT,crypto,Balancer-Tether USDt,USDT,1,0.00001,0.00000001,tBALUST
bitfinex,BANDUSD,crypto,Band-US Dollar,USD,1,0.00001,0.00000001,tBAND:USD
488 bitfinex,BANDUSDT,crypto,Band-Tether USDt,USDT,1,0.00001,0.00000001,tBAND:UST bitfinex,BATUSD,crypto,Basic Attention Token-US Dollar,USD,1,0.00001,0.00000001,tBATUSD
489 bitfinex,BATBTC,crypto,Basic Attention Token-Bitcoin,BTC,1,0.00001,0.00000001,tBATBTC bitfinex,BCHABCUSD,crypto,xec-US Dollar,USD,1,0.00001,0.00000001,tBCHABC:USD
490 bitfinex,BATETH,crypto,Basic Attention Token-Ethereum,ETH,1,0.00001,0.00000001,tBATETH bitfinex,BCHNUSD,crypto,BCH Node-US Dollar,USD,1,0.00001,0.00000001,tBCHN:USD
bitfinex,BATUSD,crypto,Basic Attention Token-US Dollar,USD,1,0.00001,0.00000001,tBATUSD
491 bitfinex,BFTUSD,crypto,BnkToTheFuture-US Dollar,USD,1,0.00001,0.00000001,tBFTUSD bitfinex,BESTUSD,crypto,Bitpanda-US Dollar,USD,1,0.00001,0.00000001,tBEST:USD
492 bitfinex,BNTUSD,crypto,Bancor-US Dollar,USD,1,0.00001,0.00000001,tBNTUSD bitfinex,BFTUSD,crypto,BnkToTheFuture-US Dollar,USD,1,0.00001,0.00000001,tBFTUSD
493 bitfinex,BOXUSD,crypto,ContentBox-US Dollar,USD,1,0.00001,0.00000001,tBOXUSD bitfinex,BMIUSD,crypto,BridgeMutual-US Dollar,USD,1,0.00001,0.00000001,tBMIUSD
494 bitfinex,BSVBTC,crypto,Bitcoin SV-Bitcoin,BTC,1,0.00001,0.00000001,tBSVBTC bitfinex,BMIUSDT,crypto,BridgeMutual-Tether USDt,USDT,1,0.00001,0.00000001,tBMIUST
bitfinex,BSVUSD,crypto,Bitcoin SV-US Dollar,USD,1,0.00001,0.00000001,tBSVUSD
bitfinex,BTCCNHT,crypto,Bitcoin-Tether CNHt,CNHT,1,0.00001,0.00000001,tBTC:CNHT
495 bitfinex,BTCEUR,crypto,Bitcoin-Euro,EUR,1,0.00001,0.00000001,tBTCEUR bitfinex,BNTUSD,crypto,Bancor-US Dollar,USD,1,0.00001,0.00000001,tBNTUSD
496 bitfinex,BTCGBP,crypto,Bitcoin-Pound Sterling,GBP,1,0.00001,0.00000001,tBTCGBP bitfinex,BOSONUSD,crypto,Boson Token-US Dollar,USD,1,0.00001,0.00000001,tBOSON:USD
497 bitfinex,BTCJPY,crypto,Bitcoin-Japanese Yen,JPY,1,0.00001,0.00000001,tBTCJPY bitfinex,BOSONUSDT,crypto,Boson Token-Tether USDt,USDT,1,0.00001,0.00000001,tBOSON:UST
499 bitfinex,BTCUSDT,crypto,Bitcoin-Tether USDt,USDT,1,0.00001,0.00000001,tBTCUST bitfinex,BSVUSD,crypto,Bitcoin SV-US Dollar,USD,1,0.00001,0.00000001,tBSVUSD
500 bitfinex,BTCXCHF,crypto,Bitcoin-CryptoFranc,XCHF,1,0.00001,0.00000001,tBTCXCH bitfinex,BTCCNHT,crypto,Bitcoin-Tether CNHt,CNHT,1,0.00001,0.00000001,tBTC:CNHT
501 bitfinex,BTGBTC,crypto,Bitcoin Gold-Bitcoin,BTC,1,0.00001,0.00000001,tBTGBTC bitfinex,BTCEUR,crypto,Bitcoin-Euro,EUR,1,0.00001,0.00000001,tBTCEUR
502 bitfinex,BTCGBP,crypto,Bitcoin-Pound Sterling,GBP,1,0.00001,0.00000001,tBTCGBP
503 bitfinex,BTCJPY,crypto,Bitcoin-Japanese Yen,JPY,1,0.00001,0.00000001,tBTCJPY
504 bitfinex,BTCUSD,crypto,Bitcoin-US Dollar,USD,1,0.00001,0.00000001,tBTCUSD
505 bitfinex,BTGUSD,crypto,Bitcoin Gold-US Dollar,USD,1,0.00001,0.00000001,tBTGUSD bitfinex,BTCUSDT,crypto,Bitcoin-Tether USDt,USDT,1,0.00001,0.00000001,tBTCUST
506 bitfinex,BTCXCHF,crypto,Bitcoin-CryptoFranc,XCHF,1,0.00001,0.00000001,tBTCXCH
507 bitfinex,BTGBTC,crypto,Bitcoin Gold-Bitcoin,BTC,1,0.00001,0.00000001,tBTGBTC
508 bitfinex,BTSEUSD,crypto,BTSE-US Dollar,USD,1,0.00001,0.00000001,tBTSE:USD bitfinex,BTGUSD,crypto,Bitcoin Gold-US Dollar,USD,1,0.00001,0.00000001,tBTGUSD
509 bitfinex,BTTUSD,crypto,BitTorrent-US Dollar,USD,1,0.00001,0.00000001,tBTTUSD bitfinex,BTSEUSD,crypto,BTSE-US Dollar,USD,1,0.00001,0.00000001,tBTSE:USD
510 bitfinex,BTTUSD,crypto,BitTorrent-US Dollar,USD,1,0.00001,0.00000001,tBTTUSD
511 bitfinex,CBTUSD,crypto,CommerceBlock-US Dollar,USD,1,0.00001,0.00000001,tCBTUSD bitfinex,CELUSD,crypto,Celsius-US Dollar,USD,1,0.00001,0.00000001,tCELUSD
512 bitfinex,CHZUSD,crypto,socios.com Chiliz-US Dollar,USD,1,0.00001,0.00000001,tCHZUSD bitfinex,CELUSDT,crypto,Celsius-Tether USDt,USDT,1,0.00001,0.00000001,tCELUST
513 bitfinex,CHZUSDT,crypto,socios.com Chiliz-Tether USDt,USDT,1,0.00001,0.00000001,tCHZUST bitfinex,CHEXUSD,crypto,CHEX-US Dollar,USD,1,0.00001,0.00000001,tCHEX:USD
521 bitfinex,CTXCUSD,crypto,Cortex-US Dollar,USD,1,0.00001,0.00000001,tCTXUSD bitfinex,CTKUSDT,crypto,CERTIK-Tether USDt,USDT,1,0.00001,0.00000001,tCTKUST
522 bitfinex,DAIBTC,crypto,Dai Stablecoin-Bitcoin,BTC,1,0.00001,0.00000001,tDAIBTC
523 bitfinex,DAIETH,crypto,Dai Stablecoin-Ethereum,ETH,1,0.00001,0.00000001,tDAIETH
524 bitfinex,DAIUSD,crypto,Dai Stablecoin-US Dollar,USD,1,0.00001,0.00000001,tDAIUSD
525 bitfinex,DATABTC,crypto,Streamr-Bitcoin,BTC,1,0.00001,0.00000001,tDATBTC
526 bitfinex,DATAUSD,crypto,Streamr-US Dollar,USD,1,0.00001,0.00000001,tDATUSD
527 bitfinex,DAPPUSD,crypto,DAPP-US Dollar,USD,1,0.00001,0.00000001,tDAPP:USD bitfinex,DGBUSD,crypto,Digibyte-US Dollar,USD,1,0.00001,0.00000001,tDGBUSD
528 bitfinex,DAPPUSDT,crypto,DAPP-Tether USDt,USDT,1,0.00001,0.00000001,tDAPP:UST bitfinex,MDOGEBTC,crypto,MegaDOGE-Bitcoin,BTC,1,0.00001,0.00000001,tDOGBTC
529 bitfinex,DATABTC,crypto,Streamr-Bitcoin,BTC,1,0.00001,0.00000001,tDATBTC bitfinex,DOGEUSD,crypto,DOGE-US Dollar,USD,1,0.00001,0.00000001,tDOGE:USD
bitfinex,DATAUSD,crypto,Streamr-US Dollar,USD,1,0.00001,0.00000001,tDATUSD
530 bitfinex,DGBUSD,crypto,Digibyte-US Dollar,USD,1,0.00001,0.00000001,tDGBUSD bitfinex,DOGEUSDT,crypto,DOGE-Tether USDt,USDT,1,0.00001,0.00000001,tDOGE:UST
bitfinex,DGXUSD,crypto,Digix Gold Token-US Dollar,USD,1,0.00001,0.00000001,tDGXUSD
531 bitfinex,MDOGEBTC,crypto,MegaDOGE-Bitcoin,BTC,1,0.00001,0.00000001,tDOGBTC bitfinex,MDOGEUSD,crypto,MegaDOGE-US Dollar,USD,1,0.00001,0.00000001,tDOGUSD
532 bitfinex,MDOGEUSD,crypto,MegaDOGE-US Dollar,USD,1,0.00001,0.00000001,tDOGUSD bitfinex,MDOGEUSDT,crypto,MegaDOGE-Tether USDt,USDT,1,0.00001,0.00000001,tDOGUST
533 bitfinex,MDOGEUSDT,crypto,MegaDOGE-Tether USDt,USDT,1,0.00001,0.00000001,tDOGUST bitfinex,DOTBTC,crypto,Polkadot-Bitcoin,BTC,1,0.00001,0.00000001,tDOTBTC
534 bitfinex,DOTUSD,crypto,Polkadot-US Dollar,USD,1,0.00001,0.00000001,tDOTUSD
535 bitfinex,DOTUSDT,crypto,Polkadot-Tether USDt,USDT,1,0.00001,0.00000001,tDOTUST
536 bitfinex,DRGNUSD,crypto,Dragonchain-US Dollar,USD,1,0.00001,0.00000001,tDRNUSD bitfinex,DASHBTC,crypto,Dash-Bitcoin,BTC,1,0.00001,0.00000001,tDSHBTC
537 bitfinex,DASHBTC,crypto,Dash-Bitcoin,BTC,1,0.00001,0.00000001,tDSHBTC bitfinex,DASHUSD,crypto,Dash-US Dollar,USD,1,0.00001,0.00000001,tDSHUSD
bitfinex,DASHUSD,crypto,Dash-US Dollar,USD,1,0.00001,0.00000001,tDSHUSD
bitfinex,DTAUSD,crypto,Data-US Dollar,USD,1,0.00001,0.00000001,tDTAUSD
538 bitfinex,DTHUSD,crypto,Dether-US Dollar,USD,1,0.00001,0.00000001,tDTHUSD bitfinex,DUSKBTC,crypto,Dusk Network-Bitcoin,BTC,1,0.00001,0.00000001,tDUSK:BTC
539 bitfinex,DTUSD,crypto,DragonToken-US Dollar,USD,1,0.00001,0.00000001,tDTXUSD bitfinex,DUSKUSD,crypto,Dusk Network-US Dollar,USD,1,0.00001,0.00000001,tDUSK:USD
540 bitfinex,DUSKBTC,crypto,Dusk Network-Bitcoin,BTC,1,0.00001,0.00000001,tDUSK:BTC bitfinex,PNTBTC,crypto,pNetwork-Bitcoin,BTC,1,0.00001,0.00000001,tEDOBTC
bitfinex,DUSKUSD,crypto,Dusk Network-US Dollar,USD,1,0.00001,0.00000001,tDUSK:USD
541 bitfinex,PNTBTC,crypto,pNetwork-Bitcoin,BTC,1,0.00001,0.00000001,tEDOBTC bitfinex,PNTETH,crypto,pNetwork-Ethereum,ETH,1,0.00001,0.00000001,tEDOETH
542 bitfinex,PNTUSD,crypto,pNetwork-US Dollar,USD,1,0.00001,0.00000001,tEDOUSD
543 bitfinex,EGLDUSD,crypto,Elrond-US Dollar,USD,1,0.00001,0.00000001,tEGLD:USD
544 bitfinex,PNTETH,crypto,pNetwork-Ethereum,ETH,1,0.00001,0.00000001,tEDOETH bitfinex,EGLDUSDT,crypto,Elrond-Tether USDt,USDT,1,0.00001,0.00000001,tEGLD:UST
545 bitfinex,PNTUSD,crypto,pNetwork-US Dollar,USD,1,0.00001,0.00000001,tEDOUSD bitfinex,ENJUSD,crypto,Enjin-US Dollar,USD,1,0.00001,0.00000001,tENJUSD
546 bitfinex,EOSBTC,crypto,EOS-Bitcoin,BTC,1,0.00001,0.00000001,tEOSBTC
547 bitfinex,EGLDUSD,crypto,Elrond-US Dollar,USD,1,0.00001,0.00000001,tEGLD:USD bitfinex,EOSDTUSD,crypto,EOSDT-US Dollar,USD,1,0.00001,0.00000001,tEOSDT:USD
548 bitfinex,EGLDUSDT,crypto,Elrond-Tether USDt,USDT,1,0.00001,0.00000001,tEGLD:UST bitfinex,EOSDTUSDT,crypto,EOSDT-Tether USDt,USDT,1,0.00001,0.00000001,tEOSDT:UST
bitfinex,ELFUSD,crypto,aelf-US Dollar,USD,1,0.00001,0.00000001,tELFUSD
549 bitfinex,ENJUSD,crypto,Enjin-US Dollar,USD,1,0.00001,0.00000001,tENJUSD bitfinex,EOSETH,crypto,EOS-Ethereum,ETH,1,0.00001,0.00000001,tEOSETH
550 bitfinex,EOSBTC,crypto,EOS-Bitcoin,BTC,1,0.00001,0.00000001,tEOSBTC bitfinex,EOSEUR,crypto,EOS-Euro,EUR,1,0.00001,0.00000001,tEOSEUR
bitfinex,EOSDTUSD,crypto,EOSDT-US Dollar,USD,1,0.00001,0.00000001,tEOSDT:USD
bitfinex,EOSDTUSDT,crypto,EOSDT-Tether USDt,USDT,1,0.00001,0.00000001,tEOSDT:UST
bitfinex,EOSETH,crypto,EOS-Ethereum,ETH,1,0.00001,0.00000001,tEOSETH
551 bitfinex,EOSEUR,crypto,EOS-Euro,EUR,1,0.00001,0.00000001,tEOSEUR bitfinex,EOSGBP,crypto,EOS-Pound Sterling,GBP,1,0.00001,0.00000001,tEOSGBP
552 bitfinex,EOSGBP,crypto,EOS-Pound Sterling,GBP,1,0.00001,0.00000001,tEOSGBP bitfinex,EOSJPY,crypto,EOS-Japanese Yen,JPY,1,0.00001,0.00000001,tEOSJPY
553 bitfinex,EOSJPY,crypto,EOS-Japanese Yen,JPY,1,0.00001,0.00000001,tEOSJPY bitfinex,EOSUSD,crypto,EOS-US Dollar,USD,1,0.00001,0.00000001,tEOSUSD
555 bitfinex,EOSUSDT,crypto,EOS-Tether USDt,USDT,1,0.00001,0.00000001,tEOSUST bitfinex,ESSUSD,crypto,Essentia-US Dollar,USD,1,0.00001,0.00000001,tESSUSD
556 bitfinex,ESSUSD,crypto,Essentia-US Dollar,USD,1,0.00001,0.00000001,tESSUSD bitfinex,ETCBTC,crypto,Ethereum Classic-Bitcoin,BTC,1,0.00001,0.00000001,tETCBTC
557 bitfinex,ETCBTC,crypto,Ethereum Classic-Bitcoin,BTC,1,0.00001,0.00000001,tETCBTC bitfinex,ETCUSD,crypto,Ethereum Classic-US Dollar,USD,1,0.00001,0.00000001,tETCUSD
bitfinex,ETCUSD,crypto,Ethereum Classic-US Dollar,USD,1,0.00001,0.00000001,tETCUSD
558 bitfinex,ETHBTC,crypto,Ethereum-Bitcoin,BTC,1,0.00001,0.00000001,tETHBTC bitfinex,ETH2ETH,crypto,ETH2X-Ethereum,ETH,1,0.00001,0.00000001,tETH2X:ETH
559 bitfinex,ETHEUR,crypto,Ethereum-Euro,EUR,1,0.00001,0.00000001,tETHEUR bitfinex,ETH2USD,crypto,ETH2X-US Dollar,USD,1,0.00001,0.00000001,tETH2X:USD
560 bitfinex,ETHGBP,crypto,Ethereum-Pound Sterling,GBP,1,0.00001,0.00000001,tETHGBP bitfinex,ETH2USDT,crypto,ETH2X-Tether USDt,USDT,1,0.00001,0.00000001,tETH2X:UST
568 bitfinex,EURTEUR,crypto,Tether EURt-Euro,EUR,1,0.00001,0.00000001,tEUTEUR bitfinex,ETPETH,crypto,ETP-Ethereum,ETH,1,0.00001,0.00000001,tETPETH
569 bitfinex,EURTUSD,crypto,Tether EURt-US Dollar,USD,1,0.00001,0.00000001,tEUTUSD bitfinex,ETPUSD,crypto,ETP-US Dollar,USD,1,0.00001,0.00000001,tETPUSD
570 bitfinex,EVTUSD,crypto,Ethfinex Voting Token-US Dollar,USD,1,0.00001,0.00000001,tEVTUSD bitfinex,EURSUSD,crypto,EURS-US Dollar,USD,1,0.00001,0.00000001,tEUSUSD
571 bitfinex,EURTEUR,crypto,Tether EURt-Euro,EUR,1,0.00001,0.00000001,tEUTEUR
572 bitfinex,EURTUSD,crypto,Tether EURt-US Dollar,USD,1,0.00001,0.00000001,tEUTUSD
573 bitfinex,EURTUSDT,crypto,Tether EURt-Tether USDt,USDT,1,0.00001,0.00000001,tEUTUST
574 bitfinex,FETUSD,crypto,Fetch.AI-US Dollar,USD,1,0.00001,0.00000001,tFETUSD bitfinex,EXRDBTC,crypto,E-RADIX-Bitcoin,BTC,1,0.00001,0.00000001,tEXRD:BTC
575 bitfinex,FETUSDT,crypto,Fetch.AI-Tether USDt,USDT,1,0.00001,0.00000001,tFETUST bitfinex,EXRDUSD,crypto,E-RADIX-US Dollar,USD,1,0.00001,0.00000001,tEXRD:USD
576 bitfinex,FILUSD,crypto,Filecoin-US Dollar,USD,1,0.00001,0.00000001,tFILUSD bitfinex,FCLUSD,crypto,Fractal-US Dollar,USD,1,0.00001,0.00000001,tFCLUSD
583 bitfinex,GENUSD,crypto,DAOstack-US Dollar,USD,1,0.00001,0.00000001,tGENUSD bitfinex,FORTHUSDT,crypto,FORTH-Tether USDt,USDT,1,0.00001,0.00000001,tFORTH:UST
584 bitfinex,GNOUSD,crypto,Gnosis-US Dollar,USD,1,0.00001,0.00000001,tGNOUSD bitfinex,FTMUSD,crypto,Fantom-US Dollar,USD,1,0.00001,0.00000001,tFTMUSD
585 bitfinex,GNTBTC,crypto,Golem-Bitcoin,BTC,1,0.00001,0.00000001,tGNTBTC bitfinex,FTMUSDT,crypto,Fantom-Tether USDt,USDT,1,0.00001,0.00000001,tFTMUST
586 bitfinex,GNTETH,crypto,Golem-Ethereum,ETH,1,0.00001,0.00000001,tGNTETH bitfinex,FTTUSD,crypto,FTX.com-US Dollar,USD,1,0.00001,0.00000001,tFTTUSD
587 bitfinex,FTTUSDT,crypto,FTX.com-Tether USDt,USDT,1,0.00001,0.00000001,tFTTUST
588 bitfinex,FUNUSD,crypto,FunFair-US Dollar,USD,1,0.00001,0.00000001,tFUNUSD
589 bitfinex,GNOUSD,crypto,Gnosis-US Dollar,USD,1,0.00001,0.00000001,tGNOUSD
590 bitfinex,GLMUSD,crypto,Golem-US Dollar,USD,1,0.00001,0.00000001,tGNTUSD
591 bitfinex,GNTUSD,crypto,Golem-US Dollar,USD,1,0.00001,0.00000001,tGNTUSD bitfinex,GOTEUR,crypto,ParkinGO-Euro,EUR,1,0.00001,0.00000001,tGOTEUR
592 bitfinex,GOTEUR,crypto,ParkinGO-Euro,EUR,1,0.00001,0.00000001,tGOTEUR bitfinex,GOTUSD,crypto,ParkinGO-US Dollar,USD,1,0.00001,0.00000001,tGOTUSD
593 bitfinex,GOTUSD,crypto,ParkinGO-US Dollar,USD,1,0.00001,0.00000001,tGOTUSD bitfinex,GRTUSD,crypto,The Graph-US Dollar,USD,1,0.00001,0.00000001,tGRTUSD
594 bitfinex,GUSDUSD,crypto,GUSD-US Dollar,USD,1,0.00001,0.00000001,tGSDUSD bitfinex,GRTUSDT,crypto,The Graph-Tether USDt,USDT,1,0.00001,0.00000001,tGRTUST
595 bitfinex,GTXUSD,crypto,Gate.IO-US Dollar,USD,1,0.00001,0.00000001,tGTXUSD
596 bitfinex,GTXUSDT,crypto,Gate.IO-Tether USDt,USDT,1,0.00001,0.00000001,tGTXUST
597 bitfinex,HEZUSD,crypto,Hermez-US Dollar,USD,1,0.00001,0.00000001,tHEZUSD
598 bitfinex,HEZUSDT,crypto,Hermez-Tether USDt,USDT,1,0.00001,0.00000001,tHEZUST
599 bitfinex,HOTUSD,crypto,Hydro Protocol-US Dollar,USD,1,0.00001,0.00000001,tHOTUSD bitfinex,ICEUSD,crypto,ICE-US Dollar,USD,1,0.00001,0.00000001,tICEUSD
600 bitfinex,IMPUSD,crypto,Ether Kingdoms-US Dollar,USD,1,0.00001,0.00000001,tIMPUSD bitfinex,ICPBTC,crypto,Dfinity-Bitcoin,BTC,1,0.00001,0.00000001,tICPBTC
601 bitfinex,IOSTUSD,crypto,IOSToken-US Dollar,USD,1,0.00001,0.00000001,tIOSUSD bitfinex,ICPUSD,crypto,Dfinity-US Dollar,USD,1,0.00001,0.00000001,tICPUSD
bitfinex,IOTABTC,crypto,Iota-Bitcoin,BTC,1,0.00001,0.00000001,tIOTBTC
602 bitfinex,IOTAETH,crypto,Iota-Ethereum,ETH,1,0.00001,0.00000001,tIOTETH bitfinex,ICPUSDT,crypto,Dfinity-Tether USDt,USDT,1,0.00001,0.00000001,tICPUST
603 bitfinex,IOTAEUR,crypto,Iota-Euro,EUR,1,0.00001,0.00000001,tIOTEUR bitfinex,IDUSD,crypto,Everest (ID)-US Dollar,USD,1,0.00001,0.00000001,tIDXUSD
bitfinex,IOTAGBP,crypto,Iota-Pound Sterling,GBP,1,0.00001,0.00000001,tIOTGBP
bitfinex,IOTAJPY,crypto,Iota-Japanese Yen,JPY,1,0.00001,0.00000001,tIOTJPY
604 bitfinex,IOTAUSD,crypto,Iota-US Dollar,USD,1,0.00001,0.00000001,tIOTUSD bitfinex,IDUSDT,crypto,Everest (ID)-Tether USDt,USDT,1,0.00001,0.00000001,tIDXUST
605 bitfinex,IQXEOS,crypto,Everipedia-EOS,EOS,1,0.00001,0.00000001,tIQXEOS bitfinex,IOTABTC,crypto,Iota-Bitcoin,BTC,1,0.00001,0.00000001,tIOTBTC
606 bitfinex,IQXUSD,crypto,Everipedia-US Dollar,USD,1,0.00001,0.00000001,tIQXUSD bitfinex,IOTAETH,crypto,Iota-Ethereum,ETH,1,0.00001,0.00000001,tIOTETH
607 bitfinex,IOTAEUR,crypto,Iota-Euro,EUR,1,0.00001,0.00000001,tIOTEUR
608 bitfinex,KANUSD,crypto,BitKan-US Dollar,USD,1,0.00001,0.00000001,tKANUSD bitfinex,IOTAGBP,crypto,Iota-Pound Sterling,GBP,1,0.00001,0.00000001,tIOTGBP
609 bitfinex,KANUSDT,crypto,BitKan-Tether USDt,USDT,1,0.00001,0.00000001,tKANUST bitfinex,IOTAJPY,crypto,Iota-Japanese Yen,JPY,1,0.00001,0.00000001,tIOTJPY
610 bitfinex,KNCBTC,crypto,Kyber-Bitcoin,BTC,1,0.00001,0.00000001,tKNCBTC bitfinex,IOTAUSD,crypto,Iota-US Dollar,USD,1,0.00001,0.00000001,tIOTUSD
611 bitfinex,KNCUSD,crypto,Kyber-US Dollar,USD,1,0.00001,0.00000001,tKNCUSD bitfinex,IQXUSD,crypto,Everipedia-US Dollar,USD,1,0.00001,0.00000001,tIQXUSD
612 bitfinex,KSMUSD,crypto,Kusama-US Dollar,USD,1,0.00001,0.00000001,tKSMUSD bitfinex,IQXUSDT,crypto,Everipedia-Tether USDt,USDT,1,0.00001,0.00000001,tIQXUST
613 bitfinex,JSTBTC,crypto,JST-Bitcoin,BTC,1,0.00001,0.00000001,tJSTBTC
614 bitfinex,JSTUSD,crypto,JST-US Dollar,USD,1,0.00001,0.00000001,tJSTUSD
615 bitfinex,JSTUSDT,crypto,JST-Tether USDt,USDT,1,0.00001,0.00000001,tJSTUST
616 bitfinex,KANUSD,crypto,BitKan-US Dollar,USD,1,0.00001,0.00000001,tKANUSD
617 bitfinex,KANUSDT,crypto,BitKan-Tether USDt,USDT,1,0.00001,0.00000001,tKANUST
618 bitfinex,KSMUSDT,crypto,Kusama-Tether USDt,USDT,1,0.00001,0.00000001,tKSMUST bitfinex,KNCBTC,crypto,Kyber-Bitcoin,BTC,1,0.00001,0.00000001,tKNCBTC
619 bitfinex,LEOBTC,crypto,Unus Sed LEO-Bitcoin,BTC,1,0.00001,0.00000001,tLEOBTC bitfinex,KNCUSD,crypto,Kyber-US Dollar,USD,1,0.00001,0.00000001,tKNCUSD
620 bitfinex,LEOEOS,crypto,Unus Sed LEO-EOS,EOS,1,0.00001,0.00000001,tLEOEOS bitfinex,KSMUSD,crypto,Kusama-US Dollar,USD,1,0.00001,0.00000001,tKSMUSD
621 bitfinex,LEOETH,crypto,Unus Sed LEO-Ethereum,ETH,1,0.00001,0.00000001,tLEOETH bitfinex,KSMUSDT,crypto,Kusama-Tether USDt,USDT,1,0.00001,0.00000001,tKSMUST
622 bitfinex,LEOUSD,crypto,Unus Sed LEO-US Dollar,USD,1,0.00001,0.00000001,tLEOUSD bitfinex,LEOBTC,crypto,Unus Sed LEO-Bitcoin,BTC,1,0.00001,0.00000001,tLEOBTC
623 bitfinex,LEOUSDT,crypto,Unus Sed LEO-Tether USDt,USDT,1,0.00001,0.00000001,tLEOUST bitfinex,LEOEOS,crypto,Unus Sed LEO-EOS,EOS,1,0.00001,0.00000001,tLEOEOS
bitfinex,LINKUSD,crypto,ChainLink-US Dollar,USD,1,0.00001,0.00000001,tLINK:USD
624 bitfinex,LINKUSDT,crypto,ChainLink-Tether USDt,USDT,1,0.00001,0.00000001,tLINK:UST bitfinex,LEOETH,crypto,Unus Sed LEO-Ethereum,ETH,1,0.00001,0.00000001,tLEOETH
625 bitfinex,LEOUSD,crypto,Unus Sed LEO-US Dollar,USD,1,0.00001,0.00000001,tLEOUSD
626 bitfinex,LEOUSDT,crypto,Unus Sed LEO-Tether USDt,USDT,1,0.00001,0.00000001,tLEOUST
627 bitfinex,LINKUSD,crypto,ChainLink-US Dollar,USD,1,0.00001,0.00000001,tLINK:USD
628 bitfinex,LINKUSDT,crypto,ChainLink-Tether USDt,USDT,1,0.00001,0.00000001,tLINK:UST
629 bitfinex,LOOUSD,crypto,Loom-US Dollar,USD,1,0.00001,0.00000001,tLOOUSD bitfinex,LRCUSD,crypto,Loopring-US Dollar,USD,1,0.00001,0.00000001,tLRCUSD
630 bitfinex,LRCBTC,crypto,Loopring-Bitcoin,BTC,1,0.00001,0.00000001,tLRCBTC bitfinex,LTCBTC,crypto,Litecoin-Bitcoin,BTC,1,0.00001,0.00000001,tLTCBTC
631 bitfinex,LRCUSD,crypto,Loopring-US Dollar,USD,1,0.00001,0.00000001,tLRCUSD bitfinex,LTCUSD,crypto,Litecoin-US Dollar,USD,1,0.00001,0.00000001,tLTCUSD
639 bitfinex,MKRBTC,crypto,Maker-Bitcoin,BTC,1,0.00001,0.00000001,tMKRBTC bitfinex,MLNUSD,crypto,Melon-US Dollar,USD,1,0.00001,0.00000001,tMLNUSD
640 bitfinex,MKRETH,crypto,Maker-Ethereum,ETH,1,0.00001,0.00000001,tMKRETH bitfinex,MANABTC,crypto,Decentraland-Bitcoin,BTC,1,0.00001,0.00000001,tMNABTC
641 bitfinex,MKRUSD,crypto,Maker-US Dollar,USD,1,0.00001,0.00000001,tMKRUSD bitfinex,MANAUSD,crypto,Decentraland-US Dollar,USD,1,0.00001,0.00000001,tMNAUSD
bitfinex,MLNUSD,crypto,Melon-US Dollar,USD,1,0.00001,0.00000001,tMLNUSD
bitfinex,MANABTC,crypto,Decentraland-Bitcoin,BTC,1,0.00001,0.00000001,tMNABTC
642 bitfinex,MANAUSD,crypto,Decentraland-US Dollar,USD,1,0.00001,0.00000001,tMNAUSD bitfinex,MOBUSD,crypto,Mobilecoin-US Dollar,USD,1,0.00001,0.00000001,tMOBUSD
643 bitfinex,MTNUSD,crypto,Medicalchain-US Dollar,USD,1,0.00001,0.00000001,tMTNUSD bitfinex,MOBUSDT,crypto,Mobilecoin-Tether USDt,USDT,1,0.00001,0.00000001,tMOBUST
644 bitfinex,NCASHUSD,crypto,Nucleus Vision-US Dollar,USD,1,0.00001,0.00000001,tNCAUSD bitfinex,NEARUSD,crypto,Near-US Dollar,USD,1,0.00001,0.00000001,tNEAR:USD
645 bitfinex,NECETH,crypto,Ethfinex Nectar Token-Ethereum,ETH,1,0.00001,0.00000001,tNECETH bitfinex,NEARUSDT,crypto,Near-Tether USDt,USDT,1,0.00001,0.00000001,tNEAR:UST
646 bitfinex,NECUSD,crypto,Ethfinex Nectar Token-US Dollar,USD,1,0.00001,0.00000001,tNECUSD
647 bitfinex,NEOBTC,crypto,NEO-Bitcoin,BTC,1,0.00001,0.00000001,tNEOBTC
648 bitfinex,NECUSD,crypto,Ethfinex Nectar Token-US Dollar,USD,1,0.00001,0.00000001,tNECUSD bitfinex,NEOETH,crypto,NEO-Ethereum,ETH,1,0.00001,0.00000001,tNEOETH
649 bitfinex,NEOBTC,crypto,NEO-Bitcoin,BTC,1,0.00001,0.00000001,tNEOBTC bitfinex,NEOEUR,crypto,NEO-Euro,EUR,1,0.00001,0.00000001,tNEOEUR
650 bitfinex,NEOETH,crypto,NEO-Ethereum,ETH,1,0.00001,0.00000001,tNEOETH bitfinex,NEOGBP,crypto,NEO-Pound Sterling,GBP,1,0.00001,0.00000001,tNEOGBP
bitfinex,NEOEUR,crypto,NEO-Euro,EUR,1,0.00001,0.00000001,tNEOEUR
bitfinex,NEOGBP,crypto,NEO-Pound Sterling,GBP,1,0.00001,0.00000001,tNEOGBP
bitfinex,NEOJPY,crypto,NEO-Japanese Yen,JPY,1,0.00001,0.00000001,tNEOJPY
651 bitfinex,NEOUSD,crypto,NEO-US Dollar,USD,1,0.00001,0.00000001,tNEOUSD bitfinex,NEOJPY,crypto,NEO-Japanese Yen,JPY,1,0.00001,0.00000001,tNEOJPY
652 bitfinex,NUTUSD,crypto,Native Utility Token-US Dollar,USD,1,0.00001,0.00000001,tNUTUSD bitfinex,NEOUSD,crypto,NEO-US Dollar,USD,1,0.00001,0.00000001,tNEOUSD
653 bitfinex,NUTUSDT,crypto,Native Utility Token-Tether USDt,USDT,1,0.00001,0.00000001,tNUTUST bitfinex,NEXOBTC,crypto,NEXO-Bitcoin,BTC,1,0.00001,0.00000001,tNEXO:BTC
654 bitfinex,ODEUSD,crypto,Odem-US Dollar,USD,1,0.00001,0.00000001,tODEUSD bitfinex,NEXOUSD,crypto,NEXO-US Dollar,USD,1,0.00001,0.00000001,tNEXO:USD
655 bitfinex,OKBUSD,crypto,OKB-US Dollar,USD,1,0.00001,0.00000001,tOKBUSD bitfinex,NEXOUSDT,crypto,NEXO-Tether USDt,USDT,1,0.00001,0.00000001,tNEXO:UST
656 bitfinex,OKBUSDT,crypto,OKB-Tether USDt,USDT,1,0.00001,0.00000001,tOKBUST bitfinex,OCEANUSD,crypto,OCEAN protocol-US Dollar,USD,1,0.00001,0.00000001,tOCEAN:USD
657 bitfinex,OMGBTC,crypto,OmiseGO-Bitcoin,BTC,1,0.00001,0.00000001,tOMGBTC bitfinex,OCEANUSDT,crypto,OCEAN protocol-Tether USDt,USDT,1,0.00001,0.00000001,tOCEAN:UST
658 bitfinex,ODEUSD,crypto,Odem-US Dollar,USD,1,0.00001,0.00000001,tODEUSD
659 bitfinex,OMGETH,crypto,OmiseGO-Ethereum,ETH,1,0.00001,0.00000001,tOMGETH bitfinex,OMGBTC,crypto,OmiseGO-Bitcoin,BTC,1,0.00001,0.00000001,tOMGBTC
660 bitfinex,OMGUSD,crypto,OmiseGO-US Dollar,USD,1,0.00001,0.00000001,tOMGUSD bitfinex,OMGETH,crypto,OmiseGO-Ethereum,ETH,1,0.00001,0.00000001,tOMGETH
661 bitfinex,OMNIBTC,crypto,Omni-Bitcoin,BTC,1,0.00001,0.00000001,tOMNBTC bitfinex,OMGUSD,crypto,OmiseGO-US Dollar,USD,1,0.00001,0.00000001,tOMGUSD
663 bitfinex,ONLUSD,crypto,On.Live-US Dollar,USD,1,0.00001,0.00000001,tONLUSD bitfinex,ORSUSD,crypto,ORS-US Dollar,USD,1,0.00001,0.00000001,tORSUSD
664 bitfinex,ORSUSD,crypto,ORS-US Dollar,USD,1,0.00001,0.00000001,tORSUSD bitfinex,OXYUSD,crypto,Oxygen-US Dollar,USD,1,0.00001,0.00000001,tOXYUSD
665 bitfinex,PAIUSD,crypto,PAI Project-US Dollar,USD,1,0.00001,0.00000001,tPAIUSD bitfinex,OXYUSDT,crypto,Oxygen-Tether USDt,USDT,1,0.00001,0.00000001,tOXYUST
666 bitfinex,PASSUSD,crypto,Blockpass-US Dollar,USD,1,0.00001,0.00000001,tPASUSD
667 bitfinex,PAXUSD,crypto,Paxos-US Dollar,USD,1,0.00001,0.00000001,tPAXUSD
668 bitfinex,PAXUSDT,crypto,Paxos-Tether USDt,USDT,1,0.00001,0.00000001,tPAXUST
669 bitfinex,PLANETSUSD,crypto,PLANETS-US Dollar,USD,1,0.00001,0.00000001,tPLANETS:USD
670 bitfinex,PLANETSUSDT,crypto,PLANETS-Tether USDt,USDT,1,0.00001,0.00000001,tPLANETS:UST
671 bitfinex,PAXUSDT,crypto,Paxos-Tether USDt,USDT,1,0.00001,0.00000001,tPAXUST bitfinex,PLUUSD,crypto,Pluton-US Dollar,USD,1,0.00001,0.00000001,tPLUUSD
bitfinex,PNKETH,crypto,Kleros-Ethereum,ETH,1,0.00001,0.00000001,tPNKETH
bitfinex,PNKUSD,crypto,Kleros-US Dollar,USD,1,0.00001,0.00000001,tPNKUSD
672 bitfinex,POAUSD,crypto,POA Network (erc20)-US Dollar,USD,1,0.00001,0.00000001,tPOAUSD bitfinex,PNKETH,crypto,Kleros-Ethereum,ETH,1,0.00001,0.00000001,tPNKETH
673 bitfinex,POLYUSD,crypto,Polymath-US Dollar,USD,1,0.00001,0.00000001,tPOYUSD bitfinex,PNKUSD,crypto,Kleros-US Dollar,USD,1,0.00001,0.00000001,tPNKUSD
674 bitfinex,QASHUSD,crypto,QASH-US Dollar,USD,1,0.00001,0.00000001,tQSHUSD
bitfinex,QTUMBTC,crypto,Qtum-Bitcoin,BTC,1,0.00001,0.00000001,tQTMBTC
675 bitfinex,QTUMUSD,crypto,Qtum-US Dollar,USD,1,0.00001,0.00000001,tQTMUSD bitfinex,QTFBTC,crypto,Quantfury-Bitcoin,BTC,1,0.00001,0.00000001,tQTFBTC
bitfinex,RBTCBTC,crypto,RBTC-Bitcoin,BTC,1,0.00001,0.00000001,tRBTBTC
676 bitfinex,RBTCUSD,crypto,RBTC-US Dollar,USD,1,0.00001,0.00000001,tRBTUSD bitfinex,QTFUSD,crypto,Quantfury-US Dollar,USD,1,0.00001,0.00000001,tQTFUSD
677 bitfinex,RCNUSD,crypto,RCN-US Dollar,USD,1,0.00001,0.00000001,tRCNUSD bitfinex,QTUMBTC,crypto,Qtum-Bitcoin,BTC,1,0.00001,0.00000001,tQTMBTC
678 bitfinex,QTUMUSD,crypto,Qtum-US Dollar,USD,1,0.00001,0.00000001,tQTMUSD
679 bitfinex,RDNUSD,crypto,Raiden-US Dollar,USD,1,0.00001,0.00000001,tRDNUSD bitfinex,RBTCBTC,crypto,RBTC-Bitcoin,BTC,1,0.00001,0.00000001,tRBTBTC
680 bitfinex,REP2BTC,crypto,Augur-Bitcoin,BTC,1,0.00001,0.00000001,tREPBTC bitfinex,RBTCUSD,crypto,RBTC-US Dollar,USD,1,0.00001,0.00000001,tRBTUSD
681 bitfinex,REP2USD,crypto,Augur-US Dollar,USD,1,0.00001,0.00000001,tREPUSD bitfinex,REP2BTC,crypto,Augur-Bitcoin,BTC,1,0.00001,0.00000001,tREPBTC
682 bitfinex,REP2USD,crypto,Augur-US Dollar,USD,1,0.00001,0.00000001,tREPUSD
683 bitfinex,REQUSD,crypto,Request Network-US Dollar,USD,1,0.00001,0.00000001,tREQUSD
684 bitfinex,RINGXUSD,crypto,RingX-US Dollar,USD,1,0.00001,0.00000001,tRINGX:USD
685 bitfinex,REQUSD,crypto,Request Network-US Dollar,USD,1,0.00001,0.00000001,tREQUSD bitfinex,RRBUSD,crypto,RenrenBit-US Dollar,USD,1,0.00001,0.00000001,tRRBUSD
686 bitfinex,RIFUSD,crypto,RIF-US Dollar,USD,1,0.00001,0.00000001,tRIFUSD bitfinex,RRBUSDT,crypto,RenrenBit-Tether USDt,USDT,1,0.00001,0.00000001,tRRBUST
bitfinex,RINGXUSD,crypto,RingX-US Dollar,USD,1,0.00001,0.00000001,tRINGX:USD
bitfinex,RLCBTC,crypto,iExec-Bitcoin,BTC,1,0.00001,0.00000001,tRLCBTC
687 bitfinex,RLCUSD,crypto,iExec-US Dollar,USD,1,0.00001,0.00000001,tRLCUSD bitfinex,RRTUSD,crypto,Recovery Right Tokens-US Dollar,USD,1,0.00001,0.00000001,tRRTUSD
688 bitfinex,SANBTC,crypto,Santiment-Bitcoin,BTC,1,0.00001,0.00000001,tSANBTC
689 bitfinex,SANETH,crypto,Santiment-Ethereum,ETH,1,0.00001,0.00000001,tSANETH
690 bitfinex,RRBUSD,crypto,RenrenBit-US Dollar,USD,1,0.00001,0.00000001,tRRBUSD bitfinex,SANUSD,crypto,Santiment-US Dollar,USD,1,0.00001,0.00000001,tSANUSD
691 bitfinex,RRBUSDT,crypto,RenrenBit-Tether USDt,USDT,1,0.00001,0.00000001,tRRBUST bitfinex,SNGLSUSD,crypto,SingularDTV-US Dollar,USD,1,0.00001,0.00000001,tSNGUSD
692 bitfinex,RRTUSD,crypto,Recovery Right Tokens-US Dollar,USD,1,0.00001,0.00000001,tRRTUSD bitfinex,SNTUSD,crypto,Status-US Dollar,USD,1,0.00001,0.00000001,tSNTUSD
693 bitfinex,RTEUSD,crypto,Rate3-US Dollar,USD,1,0.00001,0.00000001,tRTEUSD bitfinex,SNXUSD,crypto,Synthetix Network-US Dollar,USD,1,0.00001,0.00000001,tSNXUSD
bitfinex,SANBTC,crypto,Santiment-Bitcoin,BTC,1,0.00001,0.00000001,tSANBTC
bitfinex,SANETH,crypto,Santiment-Ethereum,ETH,1,0.00001,0.00000001,tSANETH
694 bitfinex,SANUSD,crypto,Santiment-US Dollar,USD,1,0.00001,0.00000001,tSANUSD bitfinex,SNXUSDT,crypto,Synthetix Network-Tether USDt,USDT,1,0.00001,0.00000001,tSNXUST
695 bitfinex,XDUSD,crypto,Data Transaction Token-US Dollar,USD,1,0.00001,0.00000001,tSCRUSD bitfinex,SOLUSD,crypto,Solana-US Dollar,USD,1,0.00001,0.00000001,tSOLUSD
696 bitfinex,SEEUSD,crypto,Seer-US Dollar,USD,1,0.00001,0.00000001,tSEEUSD bitfinex,SOLUSDT,crypto,Solana-Tether USDt,USDT,1,0.00001,0.00000001,tSOLUST
bitfinex,SNGLSUSD,crypto,SingularDTV-US Dollar,USD,1,0.00001,0.00000001,tSNGUSD
697 bitfinex,SNTUSD,crypto,Status-US Dollar,USD,1,0.00001,0.00000001,tSNTUSD bitfinex,STORJUSD,crypto,Storj-US Dollar,USD,1,0.00001,0.00000001,tSTJUSD
bitfinex,SNXUSD,crypto,Synthetix Network-US Dollar,USD,1,0.00001,0.00000001,tSNXUSD
bitfinex,SNXUSDT,crypto,Synthetix Network-Tether USDt,USDT,1,0.00001,0.00000001,tSNXUST
698 bitfinex,SPANKUSD,crypto,SpankChain-US Dollar,USD,1,0.00001,0.00000001,tSPKUSD bitfinex,SUKUUSD,crypto,SUKU-US Dollar,USD,1,0.00001,0.00000001,tSUKU:USD
699 bitfinex,STORJUSD,crypto,Storj-US Dollar,USD,1,0.00001,0.00000001,tSTJUSD bitfinex,SUKUUSDT,crypto,SUKU-Tether USDt,USDT,1,0.00001,0.00000001,tSUKU:UST
700 bitfinex,SWMUSD,crypto,Swarm-US Dollar,USD,1,0.00001,0.00000001,tSWMUSD bitfinex,SUNUSD,crypto,SUN-US Dollar,USD,1,0.00001,0.00000001,tSUNUSD
bitfinex,TKNUSD,crypto,TokenCard-US Dollar,USD,1,0.00001,0.00000001,tTKNUSD
701 bitfinex,TNBUSD,crypto,Time New Bank-US Dollar,USD,1,0.00001,0.00000001,tTNBUSD bitfinex,SUNUSDT,crypto,SUN-Tether USDt,USDT,1,0.00001,0.00000001,tSUNUST
702 bitfinex,TRIUSD,crypto,Tripio-US Dollar,USD,1,0.00001,0.00000001,tTRIUSD bitfinex,SUSHIUSD,crypto,SUSHI-US Dollar,USD,1,0.00001,0.00000001,tSUSHI:USD
703 bitfinex,TRXBTC,crypto,TRON-Bitcoin,BTC,1,0.00001,0.00000001,tTRXBTC bitfinex,SUSHIUSDT,crypto,SUSHI-Tether USDt,USDT,1,0.00001,0.00000001,tSUSHI:UST
bitfinex,TRXETH,crypto,TRON-Ethereum,ETH,1,0.00001,0.00000001,tTRXETH
bitfinex,TRXEUR,crypto,TRON-Euro,EUR,1,0.00001,0.00000001,tTRXEUR
704 bitfinex,TRXUSD,crypto,TRON-US Dollar,USD,1,0.00001,0.00000001,tTRXUSD bitfinex,TERRAUSTUSD,crypto,TerraUST-US Dollar,USD,1,0.00001,0.00000001,tTERRAUST:USD
705 bitfinex,TUSDUSD,crypto,TrueUSD-US Dollar,USD,1,0.00001,0.00000001,tTSDUSD bitfinex,TERRAUSTUSDT,crypto,TerraUST-Tether USDt,USDT,1,0.00001,0.00000001,tTERRAUST:UST
706 bitfinex,TUSDUSDT,crypto,TrueUSD-Tether USDt,USDT,1,0.00001,0.00000001,tTSDUST bitfinex,TRXBTC,crypto,TRON-Bitcoin,BTC,1,0.00001,0.00000001,tTRXBTC
707 bitfinex,USDCUSD,crypto,USDc-US Dollar,USD,1,0.00001,0.00000001,tUDCUSD bitfinex,TRXETH,crypto,TRON-Ethereum,ETH,1,0.00001,0.00000001,tTRXETH
708 bitfinex,USDCUSDT,crypto,USDc-Tether USDt,USDT,1,0.00001,0.00000001,tUDCUST bitfinex,TRXEUR,crypto,TRON-Euro,EUR,1,0.00001,0.00000001,tTRXEUR
709 bitfinex,TRXUSD,crypto,TRON-US Dollar,USD,1,0.00001,0.00000001,tTRXUSD
710 bitfinex,UFRUSD,crypto,Upfiring-US Dollar,USD,1,0.00001,0.00000001,tUFRUSD bitfinex,TUSDUSD,crypto,TrueUSD-US Dollar,USD,1,0.00001,0.00000001,tTSDUSD
711 bitfinex,UNIUSD,crypto,Uniswap-US Dollar,USD,1,0.00001,0.00000001,tUNIUSD bitfinex,TUSDUSDT,crypto,TrueUSD-Tether USDt,USDT,1,0.00001,0.00000001,tTSDUST
712 bitfinex,UNIUSDT,crypto,Uniswap-Tether USDt,USDT,1,0.00001,0.00000001,tUNIUST bitfinex,USDCUSD,crypto,USDc-US Dollar,USD,1,0.00001,0.00000001,tUDCUSD
713 bitfinex,UOSBTC,crypto,Ultra-Bitcoin,BTC,1,0.00001,0.00000001,tUOSBTC bitfinex,USDCUSDT,crypto,USDc-Tether USDt,USDT,1,0.00001,0.00000001,tUDCUST
714 bitfinex,UOSUSD,crypto,Ultra-US Dollar,USD,1,0.00001,0.00000001,tUOSUSD bitfinex,UNIUSD,crypto,Uniswap-US Dollar,USD,1,0.00001,0.00000001,tUNIUSD
715 bitfinex,UNIUSDT,crypto,Uniswap-Tether USDt,USDT,1,0.00001,0.00000001,tUNIUST
716 bitfinex,UOPUSD,crypto,Utopia-US Dollar,USD,1,0.00001,0.00000001,tUOPUSD
717 bitfinex,UOPUSDT,crypto,Utopia-Tether USDt,USDT,1,0.00001,0.00000001,tUOPUST
718 bitfinex,UOSBTC,crypto,Ultra-Bitcoin,BTC,1,0.00001,0.00000001,tUOSBTC
719 bitfinex,USDKUSD,crypto,USDk-US Dollar,USD,1,0.00001,0.00000001,tUSKUSD bitfinex,UOSUSD,crypto,Ultra-US Dollar,USD,1,0.00001,0.00000001,tUOSUSD
720 bitfinex,USDTCNHT,crypto,Tether USDt-Tether CNHt,CNHT,1,0.00001,0.00000001,tUST:CNHT
721 bitfinex,USDTUSD,crypto,Tether USDt-US Dollar,USD,1,0.00001,0.00000001,tUSTUSD
724 bitfinex,VEEUSD,crypto,BLOCKv-US Dollar,USD,1,0.00001,0.00000001,tVEEUSD bitfinex,VELOUSD,crypto,VELO-US Dollar,USD,1,0.00001,0.00000001,tVELO:USD
725 bitfinex,VETBTC,crypto,VeChain-Bitcoin,BTC,1,0.00001,0.00000001,tVETBTC bitfinex,VELOUSDT,crypto,VELO-Tether USDt,USDT,1,0.00001,0.00000001,tVELO:UST
726 bitfinex,VETUSD,crypto,VeChain-US Dollar,USD,1,0.00001,0.00000001,tVETUSD bitfinex,VETBTC,crypto,VeChain-Bitcoin,BTC,1,0.00001,0.00000001,tVETBTC
bitfinex,VLDUSD,crypto,Vetri-US Dollar,USD,1,0.00001,0.00000001,tVLDUSD
727 bitfinex,VSYSBTC,crypto,V-SYSTEMS-Bitcoin,BTC,1,0.00001,0.00000001,tVSYBTC bitfinex,VETUSD,crypto,VeChain-US Dollar,USD,1,0.00001,0.00000001,tVETUSD
728 bitfinex,VSYSUSD,crypto,V-SYSTEMS-US Dollar,USD,1,0.00001,0.00000001,tVSYUSD bitfinex,VSYSBTC,crypto,V-SYSTEMS-Bitcoin,BTC,1,0.00001,0.00000001,tVSYBTC
729 bitfinex,VSYSUSD,crypto,V-SYSTEMS-US Dollar,USD,1,0.00001,0.00000001,tVSYUSD
730 bitfinex,WAXUSD,crypto,WAX-US Dollar,USD,1,0.00001,0.00000001,tWAXUSD
731 bitfinex,WAXUSD,crypto,WAX-US Dollar,USD,1,0.00001,0.00000001,tWAXUSD bitfinex,WBTCUSD,crypto,Wrapped Bitcoin-US Dollar,USD,1,0.00001,0.00000001,tWBTUSD
732 bitfinex,WBTCETH,crypto,Wrapped Bitcoin-Ethereum,ETH,1,0.00001,0.00000001,tWBTETH bitfinex,XAUTBTC,crypto,Tether XAUt-Bitcoin,BTC,1,0.00001,0.00000001,tXAUT:BTC
bitfinex,WBTCUSD,crypto,Wrapped Bitcoin-US Dollar,USD,1,0.00001,0.00000001,tWBTUSD
733 bitfinex,WPRUSD,crypto,WePower-US Dollar,USD,1,0.00001,0.00000001,tWPRUSD bitfinex,XAUTUSD,crypto,Tether XAUt-US Dollar,USD,1,0.00001,0.00000001,tXAUT:USD
734 bitfinex,WTCUSD,crypto,Walton-US Dollar,USD,1,0.00001,0.00000001,tWTCUSD bitfinex,XAUTUSDT,crypto,Tether XAUt-Tether USDt,USDT,1,0.00001,0.00000001,tXAUT:UST
735 bitfinex,XAUTBTC,crypto,Tether XAUt-Bitcoin,BTC,1,0.00001,0.00000001,tXAUT:BTC bitfinex,XCHFUSD,crypto,CryptoFranc-US Dollar,USD,1,0.00001,0.00000001,tXCHUSD
bitfinex,XAUTUSD,crypto,Tether XAUt-US Dollar,USD,1,0.00001,0.00000001,tXAUT:USD
736 bitfinex,XAUTUSDT,crypto,Tether XAUt-Tether USDt,USDT,1,0.00001,0.00000001,tXAUT:UST bitfinex,XDCUSD,crypto,XinFin-US Dollar,USD,1,0.00001,0.00000001,tXDCUSD
737 bitfinex,XDCUSDT,crypto,XinFin-Tether USDt,USDT,1,0.00001,0.00000001,tXDCUST
738 bitfinex,XLMBTC,crypto,Stellar Lumen-Bitcoin,BTC,1,0.00001,0.00000001,tXLMBTC
739 bitfinex,XCHFETH,crypto,CryptoFranc-Ethereum,ETH,1,0.00001,0.00000001,tXCHETH bitfinex,XLMETH,crypto,Stellar Lumen-Ethereum,ETH,1,0.00001,0.00000001,tXLMETH
740 bitfinex,XCHFUSD,crypto,CryptoFranc-US Dollar,USD,1,0.00001,0.00000001,tXCHUSD bitfinex,XLMUSD,crypto,Stellar Lumen-US Dollar,USD,1,0.00001,0.00000001,tXLMUSD
bitfinex,XLMBTC,crypto,Stellar Lumen-Bitcoin,BTC,1,0.00001,0.00000001,tXLMBTC
741 bitfinex,XLMETH,crypto,Stellar Lumen-Ethereum,ETH,1,0.00001,0.00000001,tXLMETH bitfinex,XLMUSDT,crypto,Stellar Lumen-Tether USDt,USDT,1,0.00001,0.00000001,tXLMUST
742 bitfinex,XLMUSD,crypto,Stellar Lumen-US Dollar,USD,1,0.00001,0.00000001,tXLMUSD bitfinex,XMRBTC,crypto,Monero-Bitcoin,BTC,1,0.00001,0.00000001,tXMRBTC
743 bitfinex,XMRBTC,crypto,Monero-Bitcoin,BTC,1,0.00001,0.00000001,tXMRBTC bitfinex,XMRUSD,crypto,Monero-US Dollar,USD,1,0.00001,0.00000001,tXMRUSD
bitfinex,XMRUSD,crypto,Monero-US Dollar,USD,1,0.00001,0.00000001,tXMRUSD
744 bitfinex,XRAUSD,crypto,Xriba-US Dollar,USD,1,0.00001,0.00000001,tXRAUSD bitfinex,XMRUSDT,crypto,Monero-Tether USDt,USDT,1,0.00001,0.00000001,tXMRUST
bitfinex,XRPBTC,crypto,Ripple-Bitcoin,BTC,1,0.00001,0.00000001,tXRPBTC
bitfinex,XRPUSD,crypto,Ripple-US Dollar,USD,1,0.00001,0.00000001,tXRPUSD
745 bitfinex,XTZBTC,crypto,Tezos-Bitcoin,BTC,1,0.00001,0.00000001,tXTZBTC bitfinex,XRAUSD,crypto,Xriba-US Dollar,USD,1,0.00001,0.00000001,tXRAUSD
746 bitfinex,XTZUSD,crypto,Tezos-US Dollar,USD,1,0.00001,0.00000001,tXTZUSD bitfinex,XRPBTC,crypto,Ripple-Bitcoin,BTC,1,0.00001,0.00000001,tXRPBTC
747 bitfinex,XVGUSD,crypto,Verge-US Dollar,USD,1,0.00001,0.00000001,tXVGUSD bitfinex,XRPUSD,crypto,Ripple-US Dollar,USD,1,0.00001,0.00000001,tXRPUSD
bitfinex,YFIUSD,crypto,Yearn.Finance-US Dollar,USD,1,0.00001,0.00000001,tYFIUSD
748 bitfinex,YFIUSDT,crypto,Yearn.Finance-Tether USDt,USDT,1,0.00001,0.00000001,tYFIUST bitfinex,XRPUSDT,crypto,Ripple-Tether USDt,USDT,1,0.00001,0.00000001,tXRPUST
749 bitfinex,XSNUSD,crypto,Stakenet-US Dollar,USD,1,0.00001,0.00000001,tXSNUSD
750 bitfinex,XTZBTC,crypto,Tezos-Bitcoin,BTC,1,0.00001,0.00000001,tXTZBTC
751 bitfinex,YEEDUSD,crypto,Yggdrash-US Dollar,USD,1,0.00001,0.00000001,tYGGUSD bitfinex,XTZUSD,crypto,Tezos-US Dollar,USD,1,0.00001,0.00000001,tXTZUSD
752 bitfinex,YOYOWUSD,crypto,YOYOW-US Dollar,USD,1,0.00001,0.00000001,tYYWUSD bitfinex,XVGUSD,crypto,Verge-US Dollar,USD,1,0.00001,0.00000001,tXVGUSD
753 bitfinex,ZBTUSD,crypto,ZB Token-US Dollar,USD,1,0.00001,0.00000001,tZBTUSD bitfinex,YFIUSD,crypto,Yearn.Finance-US Dollar,USD,1,0.00001,0.00000001,tYFIUSD
754 bitfinex,YFIUSDT,crypto,Yearn.Finance-Tether USDt,USDT,1,0.00001,0.00000001,tYFIUST
755 bitfinex,ZCNUSD,crypto,0Chain-US Dollar,USD,1,0.00001,0.00000001,tZCNUSD bitfinex,MCSUSD,crypto,MCS-US Dollar,USD,1,0.00001,0.00000001,tYGGUSD
756 bitfinex,ZECBTC,crypto,Zcash-Bitcoin,BTC,1,0.00001,0.00000001,tZECBTC bitfinex,ZCNUSD,crypto,0Chain-US Dollar,USD,1,0.00001,0.00000001,tZCNUSD
757 bitfinex,ZECBTC,crypto,Zcash-Bitcoin,BTC,1,0.00001,0.00000001,tZECBTC
758 bitfinex,ZECUSD,crypto,Zcash-US Dollar,USD,1,0.00001,0.00000001,tZECUSD
759 bitfinex,ZILUSD,crypto,Zilliqa-US Dollar,USD,1,0.00001,0.00000001,tZILUSD bitfinex,ZILBTC,crypto,Zilliqa-Bitcoin,BTC,1,0.00001,0.00000001,tZILBTC
760 bitfinex,ZRXBTC,crypto,0x-Bitcoin,BTC,1,0.00001,0.00000001,tZRXBTC bitfinex,ZILUSD,crypto,Zilliqa-US Dollar,USD,1,0.00001,0.00000001,tZILUSD
761 bitfinex,ZRXBTC,crypto,0x-Bitcoin,BTC,1,0.00001,0.00000001,tZRXBTC
762 bitfinex,ZRXETH,crypto,0x-Ethereum,ETH,1,0.00001,0.00000001,tZRXETH
763 bitfinex,ZRXETH,crypto,0x-Ethereum,ETH,1,0.00001,0.00000001,tZRXETH bitfinex,ZRXUSD,crypto,0x-US Dollar,USD,1,0.00001,0.00000001,tZRXUSD
764 bitfinex,ZRXUSD,crypto,0x-US Dollar,USD,1,0.00001,0.00000001,tZRXUSD binance,1INCHBTC,crypto,1INCHBTC,BTC,1,0.00000001,0.10000000,1INCHBTC
765 binance,1INCHBTC,crypto,1INCHBTC,BTC,1,0.00000001,0.10000000,1INCHBTC binance,1INCHBUSD,crypto,1INCHBUSD,BUSD,1,0.00010000,0.01000000,1INCHBUSD
766 binance,1INCHBUSD,crypto,1INCHBUSD,BUSD,1,0.00010000,0.01000000,1INCHBUSD binance,1INCHUSDT,crypto,1INCHUSDT,USDT,1,0.00010000,0.01000000,1INCHUSDT
767 binance,1INCHUSDT,crypto,1INCHUSDT,USDT,1,0.00010000,0.01000000,1INCHUSDT binance,AAVEBKRW,crypto,AAVEBKRW,BKRW,1,1.00000000,0.00100000,AAVEBKRW
768 binance,AAVEBKRW,crypto,AAVEBKRW,BKRW,1,1.00000000,0.00100000,AAVEBKRW binance,AAVEBNB,crypto,AAVEBNB,BNB,1,0.00010000,0.01000000,AAVEBNB
binance,AAVEBNB,crypto,AAVEBNB,BNB,1,0.00010000,0.01000000,AAVEBNB
binance,AAVEBTC,crypto,AAVEBTC,BTC,1,0.00000100,0.01000000,AAVEBTC
769 binance,AAVEBUSD,crypto,AAVEBUSD,BUSD,1,0.01000000,0.00010000,AAVEBUSD binance,AAVEBTC,crypto,AAVEBTC,BTC,1,0.00000100,0.01000000,AAVEBTC
770 binance,AAVEETH,crypto,AAVEETH,ETH,1,0.00001000,0.00100000,AAVEETH binance,AAVEBUSD,crypto,AAVEBUSD,BUSD,1,0.01000000,0.00010000,AAVEBUSD
771 binance,AAVEUSDT,crypto,AAVEUSDT,USDT,1,0.01000000,0.00010000,AAVEUSDT binance,AAVEETH,crypto,AAVEETH,ETH,1,0.00001000,0.00100000,AAVEETH
772 binance,AAVEUSDT,crypto,AAVEUSDT,USDT,1,0.01000000,0.00010000,AAVEUSDT
773 binance,ACMBTC,crypto,ACMBTC,BTC,1,0.00000010,0.01000000,ACMBTC
774 binance,ACMBUSD,crypto,ACMBUSD,BUSD,1,0.00100000,0.00100000,ACMBUSD
775 binance,ACMUSDT,crypto,ACMUSDT,USDT,1,0.00100000,0.00100000,ACMUSDT

View File

@@ -55,7 +55,7 @@ namespace QuantConnect.Tests.Brokerages.GDAX
public static WebSocketMessage GetArgs(string json)
{
return new WebSocketMessage(json);
return new WebSocketMessage(null, json);
}
}
}