Exemple #1
0
        protected override IWebSocket OnGetTickersWebSocket(Action <IReadOnlyCollection <KeyValuePair <string, ExchangeTicker> > > callback)
        {
            Dictionary <int, string> channelIdToSymbol = new Dictionary <int, string>();

            return(ConnectWebSocket(string.Empty, (_socket, msg) =>
            {
                JToken token = JToken.Parse(msg.ToStringFromUTF8());
                if (token is JArray array)
                {
                    if (array.Count > 10)
                    {
                        List <KeyValuePair <string, ExchangeTicker> > tickerList = new List <KeyValuePair <string, ExchangeTicker> >();
                        if (channelIdToSymbol.TryGetValue(array[0].ConvertInvariant <int>(), out string symbol))
                        {
                            ExchangeTicker ticker = ParseTickerWebSocket(symbol, array);
                            if (ticker != null)
                            {
                                callback(new KeyValuePair <string, ExchangeTicker>[] { new KeyValuePair <string, ExchangeTicker>(symbol, ticker) });
                            }
                        }
                    }
                }
                else if (token["event"].ToStringInvariant() == "subscribed" && token["channel"].ToStringInvariant() == "ticker")
                {
                    // {"event":"subscribed","channel":"ticker","chanId":1,"pair":"BTCUSD"}
                    int channelId = token["chanId"].ConvertInvariant <int>();
                    channelIdToSymbol[channelId] = token["pair"].ToStringInvariant();
                }
                return Task.CompletedTask;
            }, async(_socket) =>
            {
                var symbols = await GetSymbolsAsync();
                foreach (var symbol in symbols)
                {
                    await _socket.SendMessageAsync("{\"event\":\"subscribe\",\"channel\":\"ticker\",\"pair\":\"" + symbol + "\"}");
                }
            }));
        }
 private ExchangeTicker ParseTicker(JToken token)
 {
     // [{ "TradePairId":100,"Label":"LTC/BTC","AskPrice":0.00006000,"BidPrice":0.02000000,"Low":0.00006000,"High":0.00006000,"Volume":1000.05639978,"LastPrice":0.00006000,"BuyVolume":34455.678,"SellVolume":67003436.37658233,"Change":-400.00000000,"Open": 0.00000500,"Close": 0.00000600, "BaseVolume": 3.58675866,"BaseBuyVolume": 11.25364758, "BaseSellVolume": 3456.06746543 }, ... ]
     var symbols = token["Label"].ToStringInvariant().Split('/');
     ExchangeTicker ticker = new ExchangeTicker()
     {
         Id = token["TradePairId"].ToStringInvariant(),
         Ask = token["AskPrice"].ConvertInvariant<decimal>(),
         Bid = token["BidPrice"].ConvertInvariant<decimal>(),
         Last = token["LastPrice"].ConvertInvariant<decimal>(),
         // Since we're parsing a ticker for a market, we'll use the volume/baseVolume fields here and ignore the Buy/Sell Volumes
         // This is a quess as to ambiguous intent of these fields.
         Volume = new ExchangeVolume()
         {
             PriceSymbol = symbols[0],
             QuantitySymbol = symbols[1],
             PriceAmount = token["Volume"].ConvertInvariant<decimal>(),
             QuantityAmount = token["BaseVolume"].ConvertInvariant<decimal>(),
             Timestamp = DateTime.UtcNow           // No TimeStamp is returned, but Now seems appropriate
         }
     };
     return ticker;
 }
        // Bitbank supports endpoint for getting all rates in one request, Using this endpoint is faster then ExchangeAPI's default implementation
        // (which interate `OnGetTickerAsync` for each marketSymbols)
        // Note: This doesn't give you a volume. if you want it, please specify marketSymbol.
        protected override async Task <IEnumerable <KeyValuePair <string, ExchangeTicker> > > OnGetTickersAsync()
        {
            JToken token = await MakeJsonRequestAsync <JToken>($"/prices");

            var symbols = await OnGetMarketSymbolsAsync();

            var result = new List <KeyValuePair <string, ExchangeTicker> >();

            foreach (var symbol in symbols)
            {
                var data   = token[GlobalMarketSymbolToExchangeMarketSymbolAsync(symbol)];
                var ticker = new ExchangeTicker()
                {
                    ApiResponse  = token,
                    Ask          = data["sell"].ConvertInvariant <decimal>(),
                    Bid          = data["buy"].ConvertInvariant <decimal>(),
                    Last         = data["last"].ConvertInvariant <decimal>(),
                    MarketSymbol = symbol
                };
                result.Add(new KeyValuePair <string, ExchangeTicker>(symbol, ticker));
            }
            return(result);
        }
Exemple #4
0
        protected override async Task <IWebSocket> OnGetTickersWebSocketAsync(Action <IReadOnlyCollection <KeyValuePair <string, ExchangeTicker> > > callback, params string[] marketSymbols)
        {
            Dictionary <int, string> channelIdToSymbol = new Dictionary <int, string>();

            return(await ConnectWebSocketAsync(string.Empty, async (_socket, msg) =>
            {
                JToken token = JToken.Parse(msg.ToStringFromUTF8());
                if (token is JArray array)
                {
                    if (array.Count > 10)
                    {
                        List <KeyValuePair <string, ExchangeTicker> > tickerList = new List <KeyValuePair <string, ExchangeTicker> >();
                        if (channelIdToSymbol.TryGetValue(array[0].ConvertInvariant <int>(), out string symbol))
                        {
                            ExchangeTicker ticker = await ParseTickerWebSocketAsync(symbol, array);
                            if (ticker != null)
                            {
                                callback(new KeyValuePair <string, ExchangeTicker>[] { new KeyValuePair <string, ExchangeTicker>(symbol, ticker) });
                            }
                        }
                    }
                }
                else if (token["event"].ToStringInvariant() == "subscribed" && token["channel"].ToStringInvariant() == "ticker")
                {
                    // {"event":"subscribed","channel":"ticker","chanId":1,"pair":"BTCUSD"}
                    int channelId = token["chanId"].ConvertInvariant <int>();
                    channelIdToSymbol[channelId] = token["pair"].ToStringInvariant();
                }
            }, async (_socket) =>
            {
                marketSymbols = marketSymbols == null || marketSymbols.Length == 0 ? (await GetMarketSymbolsAsync()).ToArray() : marketSymbols;
                foreach (var marketSymbol in marketSymbols)
                {
                    await _socket.SendMessageAsync(new { @event = "subscribe", channel = "ticker", pair = marketSymbol });
                }
            }));
        }
        protected override IWebSocket OnGetTickersWebSocket(Action <IReadOnlyCollection <KeyValuePair <string, ExchangeTicker> > > callback, params string[] symbols)
        {
            void innerCallback(string json)
            {
                #region sample json

                /*
                 * {
                 *  Nonce : int,
                 *  Deltas :
                 *  [
                 *      {
                 *          MarketName     : string,
                 *          High           : decimal,
                 *          Low            : decimal,
                 *          Volume         : decimal,
                 *          Last           : decimal,
                 *          BaseVolume     : decimal,
                 *          TimeStamp      : date,
                 *          Bid            : decimal,
                 *          Ask            : decimal,
                 *          OpenBuyOrders  : int,
                 *          OpenSellOrders : int,
                 *          PrevDay        : decimal,
                 *          Created        : date
                 *      }
                 *  ]
                 * }
                 */
                #endregion

                var    freshTickers = new Dictionary <string, ExchangeTicker>(StringComparer.OrdinalIgnoreCase);
                JToken token        = JToken.Parse(json);
                token = token["D"];
                foreach (JToken ticker in token)
                {
                    string marketName = ticker["M"].ToStringInvariant();
                    var(baseCurrency, quoteCurrency) = ExchangeMarketSymbolToCurrencies(marketName);
                    decimal  last = ticker["l"].ConvertInvariant <decimal>();
                    decimal  ask  = ticker["A"].ConvertInvariant <decimal>();
                    decimal  bid  = ticker["B"].ConvertInvariant <decimal>();
                    decimal  baseCurrencyVolume  = ticker["V"].ConvertInvariant <decimal>();
                    decimal  quoteCurrencyVolume = ticker["m"].ConvertInvariant <decimal>();//NOTE: Bittrex uses the term BaseVolume when referring to QuoteCurrencyVolume
                    DateTime timestamp           = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(ticker["T"].ConvertInvariant <long>());
                    var      t = new ExchangeTicker
                    {
                        MarketSymbol = marketName,
                        Ask          = ask,
                        Bid          = bid,
                        Last         = last,
                        Volume       = new ExchangeVolume
                        {
                            BaseCurrencyVolume  = baseCurrencyVolume,
                            BaseCurrency        = baseCurrency,
                            QuoteCurrencyVolume = quoteCurrencyVolume,
                            QuoteCurrency       = quoteCurrency,
                            Timestamp           = timestamp
                        }
                    };
                    freshTickers[marketName] = t;
                }
                callback(freshTickers);
            }

            return(new BittrexWebSocketManager().SubscribeToSummaryDeltas(innerCallback));
        }
        /// <summary>
        /// Parse a JToken into a ticker
        /// </summary>
        /// <param name="api">ExchangeAPI</param>
        /// <param name="token">Token</param>
        /// <param name="marketSymbol">Symbol</param>
        /// <param name="askKey">Ask key</param>
        /// <param name="bidKey">Bid key</param>
        /// <param name="lastKey">Last key</param>
        /// <param name="baseVolumeKey">Base currency volume key</param>
        /// <param name="quoteVolumeKey">Quote currency volume key</param>
        /// <param name="timestampKey">Timestamp key</param>
        /// <param name="timestampType">Timestamp type</param>
        /// <param name="baseCurrencyKey">Base currency key</param>
        /// <param name="quoteCurrencyKey">Quote currency key</param>
        /// <param name="idKey">Id key</param>
        /// <returns>ExchangeTicker</returns>
        internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, string marketSymbol,
                                                   object askKey, object bidKey, object lastKey, object baseVolumeKey,
                                                   object quoteVolumeKey  = null, object timestampKey     = null, TimestampType timestampType = TimestampType.None,
                                                   object baseCurrencyKey = null, object quoteCurrencyKey = null, object idKey                = null)
        {
            if (token == null || !token.HasValues)
            {
                return(null);
            }
            decimal last = token[lastKey].ConvertInvariant <decimal>();

            // parse out volumes, handle cases where one or both do not exist
            token.ParseVolumes(baseVolumeKey, quoteVolumeKey, last, out decimal baseCurrencyVolume, out decimal quoteCurrencyVolume);

            // pull out timestamp
            DateTime timestamp = (timestampKey == null ? CryptoUtility.UtcNow : CryptoUtility.ParseTimestamp(token[timestampKey], timestampType));

            // split apart the symbol if we have a separator, otherwise just put the symbol for base and convert symbol
            string baseCurrency;
            string quoteCurrency;

            if (baseCurrencyKey != null && quoteCurrencyKey != null)
            {
                baseCurrency  = token[baseCurrencyKey].ToStringInvariant();
                quoteCurrency = token[quoteCurrencyKey].ToStringInvariant();
            }
            else if (string.IsNullOrWhiteSpace(marketSymbol))
            {
                throw new ArgumentNullException(nameof(marketSymbol));
            }
            else
            {
                (baseCurrency, quoteCurrency) = api.ExchangeMarketSymbolToCurrencies(marketSymbol);
            }

            // create the ticker and return it
            JToken askValue = token[askKey];
            JToken bidValue = token[bidKey];

            if (askValue is JArray)
            {
                askValue = askValue[0];
            }
            if (bidValue is JArray)
            {
                bidValue = bidValue[0];
            }
            ExchangeTicker ticker = new ExchangeTicker
            {
                MarketSymbol = marketSymbol,
                Ask          = askValue.ConvertInvariant <decimal>(),
                Bid          = bidValue.ConvertInvariant <decimal>(),
                Id           = (idKey == null ? null : token[idKey].ToStringInvariant()),
                Last         = last,
                Volume       = new ExchangeVolume
                {
                    BaseCurrencyVolume  = baseCurrencyVolume,
                    BaseCurrency        = baseCurrency,
                    QuoteCurrencyVolume = quoteCurrencyVolume,
                    QuoteCurrency       = quoteCurrency,
                    Timestamp           = timestamp
                }
            };

            return(ticker);
        }
Exemple #7
0
        /// <summary>
        /// Parse a JToken into a ticker
        /// </summary>
        /// <param name="api">ExchangeAPI</param>
        /// <param name="token">Token</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="askKey">Ask key</param>
        /// <param name="bidKey">Bid key</param>
        /// <param name="lastKey">Last key</param>
        /// <param name="baseVolumeKey">Base volume key</param>
        /// <param name="convertVolumeKey">Convert volume key</param>
        /// <param name="timestampKey">Timestamp key</param>
        /// <param name="timestampType">Timestamp type</param>
        /// <param name="baseCurrencyKey">Base currency key</param>
        /// <param name="convertCurrencyKey">Convert currency key</param>
        /// <param name="idKey">Id key</param>
        /// <returns>ExchangeTicker</returns>
        internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, string symbol,
                                                   object askKey, object bidKey, object lastKey, object baseVolumeKey,
                                                   object convertVolumeKey = null, object timestampKey       = null, TimestampType timestampType = TimestampType.None,
                                                   object baseCurrencyKey  = null, object convertCurrencyKey = null, object idKey                = null)
        {
            if (token == null || !token.HasValues)
            {
                return(null);
            }
            decimal last = token[lastKey].ConvertInvariant <decimal>();

            // parse out volumes, handle cases where one or both do not exist
            token.ParseVolumes(baseVolumeKey, convertVolumeKey, last, out decimal baseVolume, out decimal convertVolume);

            // pull out timestamp
            DateTime timestamp = (timestampKey == null ? DateTime.UtcNow : CryptoUtility.ParseTimestamp(token[timestampKey], timestampType));

            // split apart the symbol if we have a separator, otherwise just put the symbol for base and convert symbol
            string baseSymbol;
            string convertSymbol;

            if (baseCurrencyKey != null && convertCurrencyKey != null)
            {
                baseSymbol    = token[baseCurrencyKey].ToStringInvariant();
                convertSymbol = token[convertCurrencyKey].ToStringInvariant();
            }
            else if (string.IsNullOrWhiteSpace(symbol))
            {
                throw new ArgumentNullException(nameof(symbol));
            }
            else if (api.SymbolSeparator.Length != 0)
            {
                string[] pieces = symbol.Split(api.SymbolSeparator[0]);
                if (pieces.Length != 2)
                {
                    throw new ArgumentException($"Symbol does not have the correct symbol separator of '{api.SymbolSeparator}'");
                }
                baseSymbol    = pieces[0];
                convertSymbol = pieces[1];
            }
            else
            {
                baseSymbol = convertSymbol = symbol;
            }

            // create the ticker and return it
            ExchangeTicker ticker = new ExchangeTicker
            {
                Ask    = token[askKey].ConvertInvariant <decimal>(),
                Bid    = token[bidKey].ConvertInvariant <decimal>(),
                Id     = (idKey == null ? null : token[idKey].ToStringInvariant()),
                Last   = last,
                Volume = new ExchangeVolume
                {
                    BaseVolume      = baseVolume,
                    BaseSymbol      = baseSymbol,
                    ConvertedVolume = convertVolume,
                    ConvertedSymbol = convertSymbol,
                    Timestamp       = timestamp
                }
            };

            return(ticker);
        }
Exemple #8
0
        protected override IDisposable OnGetTickersWebSocket(Action <IReadOnlyCollection <KeyValuePair <string, ExchangeTicker> > > callback)
        {
            if (callback == null)
            {
                return(null);
            }

            void innerCallback(string json)
            {
                #region sample json

                /*
                 * {
                 *  Nonce : int,
                 *  Deltas :
                 *  [
                 *      {
                 *          MarketName     : string,
                 *          High           : decimal,
                 *          Low            : decimal,
                 *          Volume         : decimal,
                 *          Last           : decimal,
                 *          BaseVolume     : decimal,
                 *          TimeStamp      : date,
                 *          Bid            : decimal,
                 *          Ask            : decimal,
                 *          OpenBuyOrders  : int,
                 *          OpenSellOrders : int,
                 *          PrevDay        : decimal,
                 *          Created        : date
                 *      }
                 *  ]
                 * }
                 */
                #endregion

                var    freshTickers = new Dictionary <string, ExchangeTicker>(StringComparer.OrdinalIgnoreCase);
                JToken token        = JToken.Parse(json);
                token = token["D"];
                foreach (JToken ticker in token)
                {
                    string   marketName = ticker["M"].ToStringInvariant();
                    decimal  last       = ticker["l"].ConvertInvariant <decimal>();
                    decimal  ask        = ticker["A"].ConvertInvariant <decimal>();
                    decimal  bid        = ticker["B"].ConvertInvariant <decimal>();
                    decimal  volume     = ticker["V"].ConvertInvariant <decimal>();
                    decimal  baseVolume = ticker["m"].ConvertInvariant <decimal>();
                    DateTime timestamp  = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(ticker["T"].ConvertInvariant <long>());
                    var      t          = new ExchangeTicker
                    {
                        Ask    = ask,
                        Bid    = bid,
                        Last   = last,
                        Volume = new ExchangeVolume
                        {
                            ConvertedVolume = volume,
                            ConvertedSymbol = marketName,
                            BaseVolume      = baseVolume,
                            BaseSymbol      = marketName,
                            Timestamp       = timestamp
                        }
                    };
                    freshTickers[marketName] = t;
                }
                callback(freshTickers);
            }

            var client = SocketManager;
            return(client.SubscribeToSummaryDeltas(innerCallback));
        }