/// <summary>
        /// Loop through all exchanges, get a json string for all symbols
        /// </summary>
        /// <returns></returns>
        private async Task <string> GetAllSymbolsJsonAsync()
        {
            Dictionary <string, string[]> allSymbols = new Dictionary <string, string[]>();
            List <Task> tasks = new List <Task>();

            foreach (ExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                tasks.Add(Task.Run(async() =>
                {
                    try
                    {
                        string[] symbols = (await api.GetMarketSymbolsAsync()).ToArray();
                        lock (allSymbols)
                        {
                            allSymbols[api.Name] = symbols;
                        }
                    }
                    catch (NotImplementedException)
                    {
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Failed to get symbols for {0}, error: {1}", api, ex);
                    }
                }));
            }
            await Task.WhenAll(tasks);

            return(JsonConvert.SerializeObject(allSymbols));
        }
Example #2
0
        public async Task GlobalSymbolTest()
        {
            // if tests fail, uncomment this and add replace Resources.AllSymbolsJson
            // string allSymbolsJson = GetAllSymbolsJson(); System.IO.File.WriteAllText("TestData/AllSymbols.json", allSymbolsJson);

            string globalMarketSymbol                = "BTC-ETH";
            string globalMarketSymbolAlt             = "KRW-BTC"; // WTF Bitthumb...
            Dictionary <string, string[]> allSymbols = JsonConvert.DeserializeObject <Dictionary <string, string[]> >(System.IO.File.ReadAllText("TestData/AllSymbols.json"));

            // sanity test that all exchanges return the same global symbol when converted back and forth
            foreach (IExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                try
                {
                    if (api is ExchangeUfoDexAPI || api is ExchangeOKExAPI || api is ExchangeHitBTCAPI || api is ExchangeKuCoinAPI ||
                        api is ExchangeOKCoinAPI || api is ExchangeDigifinexAPI)
                    {
                        // WIP
                        continue;
                    }

                    bool   isBithumb            = (api.Name == ExchangeName.Bithumb);
                    string exchangeMarketSymbol = await api.GlobalMarketSymbolToExchangeMarketSymbolAsync(isBithumb?globalMarketSymbolAlt : globalMarketSymbol);

                    string globalMarketSymbol2 = await api.ExchangeMarketSymbolToGlobalMarketSymbolAsync(exchangeMarketSymbol);

                    if ((!isBithumb && globalMarketSymbol2.EndsWith("-BTC")) ||
                        globalMarketSymbol2.EndsWith("-USD") ||
                        globalMarketSymbol2.EndsWith("-USDT"))
                    {
                        Assert.Fail($"Exchange {api.Name} has wrong SymbolIsReversed parameter");
                    }
                    try
                    {
                        if (!allSymbols.ContainsKey(api.Name))
                        {
                            throw new InvalidOperationException("If new exchange has no symbols, run GetAllSymbolsJson to make a new string " +
                                                                "then apply this new string to Resources.AllSymbolsJson");
                        }
                        string[] symbols = allSymbols[api.Name];
                        Assert.IsTrue(symbols.Contains(exchangeMarketSymbol), "Symbols does not contain exchange symbol");
                    }
                    catch
                    {
                        Assert.Fail("Error getting symbols");
                    }
                    Assert.IsTrue(globalMarketSymbol == globalMarketSymbol2 || globalMarketSymbolAlt == globalMarketSymbol2);
                }
                catch (NotImplementedException)
                {
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Exchange {api.Name} error converting symbol: {ex}");
                }
            }
        }
Example #3
0
 protected override void OnShown(EventArgs e)
 {
     base.OnShown(e);
     foreach (var exchange in ExchangeAPI.GetExchangeAPIs())
     {
         cmbExchange.Items.Add(exchange.Name);
     }
     cmbExchange.SelectedIndex = 0;
 }
        /// <summary>
        /// Loop through all exchanges, get a json string for all symbols
        /// </summary>
        /// <returns></returns>
        private string GetAllSymbolsJson()
        {
            Dictionary <string, string[]> allSymbols = new Dictionary <string, string[]>();

            foreach (IExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                allSymbols[api.Name] = api.GetSymbolsAsync().Sync().ToArray();
            }
            return(JsonConvert.SerializeObject(allSymbols));
        }
        public void GlobalSymbolTest()
        {
            string globalSymbol    = "BTC-ETH";
            string globalSymbolAlt = "KRW-BTC"; // WTF Bitthumb...
            Dictionary <string, string[]> allSymbols = JsonConvert.DeserializeObject <Dictionary <string, string[]> >(Resources.AllSymbolsJson);

            // sanity test that all exchanges return the same global symbol when converted back and forth
            foreach (IExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                try
                {
                    bool   isBithumb      = (api.Name == ExchangeName.Bithumb);
                    string exchangeSymbol = api.GlobalSymbolToExchangeSymbol(isBithumb ? globalSymbolAlt : globalSymbol);
                    string globalSymbol2  = api.ExchangeSymbolToGlobalSymbol(exchangeSymbol);
                    if ((!isBithumb && globalSymbol2.EndsWith("-BTC")) ||
                        globalSymbol2.EndsWith("-USD") ||
                        globalSymbol2.EndsWith("-USDT"))
                    {
                        Assert.Fail($"Exchange {api.Name} has wrong SymbolIsReversed parameter");
                    }
                    try
                    {
                        if (!allSymbols.ContainsKey(api.Name))
                        {
                            throw new InvalidOperationException("If new exchange has no symbols, run GetAllSymbolsJson to make a new string " +
                                                                "then apply this new string to Resources.AllSymbolsJson");
                        }
                        string[] symbols = allSymbols[api.Name];
                        Assert.IsTrue(symbols.Contains(exchangeSymbol), "Symbols does not contain exchange symbol");
                    }
                    catch
                    {
                        Assert.Fail("Error getting symbols");
                    }
                    Assert.IsTrue(globalSymbol == globalSymbol2 || globalSymbolAlt == globalSymbol2);
                }
                catch (NotImplementedException)
                {
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Exchange {api.Name} error converting symbol: {ex}");
                }
            }
        }
Example #6
0
        /// <summary>
        /// Loop through all exchanges, get a json string for all symbols
        /// </summary>
        /// <returns></returns>
        private async Task <string> GetAllSymbolsJsonAsync()
        {
            Dictionary <string, string[]> allSymbols = new Dictionary <string, string[]>();
            List <Task> tasks = new List <Task>();

            foreach (ExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                tasks.Add(Task.Run(async() =>
                {
                    string[] symbols = (await api.GetMarketSymbolsAsync()).ToArray();
                    lock (allSymbols)
                    {
                        allSymbols[api.Name] = symbols;
                    }
                }));
            }
            await Task.WhenAll(tasks);

            return(JsonConvert.SerializeObject(allSymbols));
        }
Example #7
0
        /// <summary>
        /// Loop through all exchanges, get a json string for all symbols
        /// </summary>
        /// <returns></returns>
        private string GetAllSymbolsJson()
        {
            Dictionary <string, string[]> allSymbols = new Dictionary <string, string[]>();

            Parallel.ForEach(ExchangeAPI.GetExchangeAPIs(), (api) =>
            {
                try
                {
                    lock (allSymbols)
                    {
                        allSymbols[api.Name] = api.GetMarketSymbolsAsync().Sync().ToArray();
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex);
                }
            });
            return(JsonConvert.SerializeObject(allSymbols));
        }
Example #8
0
        public void GlobalSymbolTest()
        {
            string symbol    = "BTC-ETH";
            string altSymbol = "BTC-KRW"; // WTF Bitthumb...

            // sanity test that all exchanges return the same global symbol when converted back and forth
            foreach (IExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                try
                {
                    string exchangeSymbol = api.GlobalSymbolToExchangeSymbol(symbol);
                    string globalSymbol   = api.ExchangeSymbolToGlobalSymbol(exchangeSymbol);
                    Assert.IsTrue(symbol == globalSymbol || altSymbol == globalSymbol);
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Exchange {api.Name} error converting symbol: {ex}");
                }
            }
        }
Example #9
0
        public override async Task RunCommand()
        {
            var apis = ExchangeAPI.GetExchangeAPIs();

            foreach (var api in apis)
            {
                // WIP exchanges...
                if (api is ExchangeUfoDexAPI)
                {
                    continue;
                }

                if (ExchangeName != null && !Regex.IsMatch(api.Name, ExchangeName, RegexOptions.IgnoreCase))
                {
                    continue;
                }

                // test all public API for each exchange
                try
                {
                    var marketSymbol = api.NormalizeMarketSymbol(GetSymbol(api));

                    await TestMarketSymbols(api, marketSymbol);

                    await TestCurrencies(api);

                    await TestOrderBook(api, marketSymbol);

                    await TestTicker(api, marketSymbol);

                    await TestTrade(api, marketSymbol);

                    await TestCandle(api, marketSymbol);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Request failed, api: {0}, error: {1}", api.Name, ex.Message);
                }
            }
        }
Example #10
0
 public static IExchangeAPI[] GetAvailableExchanges()
 {
     return(ExchangeAPI.GetExchangeAPIs());
 }
Example #11
0
        private static void TestExchanges(string nameRegex = null, string functionRegex = null)
        {
            string GetSymbol(IExchangeAPI api)
            {
                if (api is ExchangeCryptopiaAPI || api is ExchangeLivecoinAPI || api is ExchangeZBcomAPI)
                {
                    return("LTC-BTC");
                }
                else if (api is ExchangeKrakenAPI)
                {
                    return("XXBTZ-USD");
                }
                else if (api is ExchangeBittrexAPI || api is ExchangePoloniexAPI)
                {
                    return("BTC-LTC");
                }
                else if (api is ExchangeBinanceAPI || api is ExchangeOkexAPI || api is ExchangeBleutradeAPI ||
                         api is ExchangeKucoinAPI || api is ExchangeHuobiAPI || api is ExchangeAbucoinsAPI)
                {
                    return("ETH-BTC");
                }
                else if (api is ExchangeYobitAPI)
                {
                    return("LTC-BTC");
                }
                else if (api is ExchangeTuxExchangeAPI)
                {
                    return("BTC-ETH");
                }
                else if (api is ExchangeBitMEXAPI)
                {
                    return("XBT-USD");
                }
                return("BTC-USD");
            }

            ExchangeTrade[] trades = null;
            bool histTradeCallback(IEnumerable <ExchangeTrade> tradeEnum)
            {
                trades = tradeEnum.ToArray();
                return(true);
            }

            IExchangeAPI[] apis = ExchangeAPI.GetExchangeAPIs();
            foreach (IExchangeAPI api in apis)
            {
                if (nameRegex != null && !Regex.IsMatch(api.Name, nameRegex, RegexOptions.IgnoreCase))
                {
                    continue;
                }

                // test all public API for each exchange
                try
                {
                    string symbol = api.NormalizeSymbol(GetSymbol(api));

                    if (functionRegex == null || Regex.IsMatch("symbol", functionRegex, RegexOptions.IgnoreCase))
                    {
                        Console.Write("Test {0} GetSymbolsAsync... ", api.Name);
                        IReadOnlyCollection <string> symbols = api.GetSymbolsAsync().Sync().ToArray();
                        Assert(symbols != null && symbols.Count != 0 && symbols.Contains(symbol, StringComparer.OrdinalIgnoreCase));
                        Console.WriteLine($"OK (default: {symbol}; {symbols.Count} symbols)");
                    }

                    if (functionRegex == null || Regex.IsMatch("orderbook", functionRegex, RegexOptions.IgnoreCase))
                    {
                        try
                        {
                            Console.Write("Test {0} GetOrderBookAsync... ", api.Name);
                            var book = api.GetOrderBookAsync(symbol).Sync();
                            Assert(book.Asks.Count != 0 && book.Bids.Count != 0 && book.Asks.First().Value.Amount > 0m &&
                                   book.Asks.First().Value.Price > 0m && book.Bids.First().Value.Amount > 0m && book.Bids.First().Value.Price > 0m);
                            Console.WriteLine($"OK ({book.Asks.Count} asks, {book.Bids.Count} bids)");
                        }
                        catch (NotImplementedException)
                        {
                            Console.WriteLine($"Not implemented");
                        }
                    }

                    if (functionRegex == null || Regex.IsMatch("ticker", functionRegex, RegexOptions.IgnoreCase))
                    {
                        try
                        {
                            Console.Write("Test {0} GetTickerAsync... ", api.Name);
                            var ticker = api.GetTickerAsync(symbol).Sync();
                            Assert(ticker != null && ticker.Ask > 0m && ticker.Bid > 0m && ticker.Last > 0m &&
                                   ticker.Volume != null && ticker.Volume.BaseVolume > 0m && ticker.Volume.ConvertedVolume > 0m);
                            Console.WriteLine($"OK (ask: {ticker.Ask}, bid: {ticker.Bid}, last: {ticker.Last})");
                        }
                        catch
                        {
                            Console.WriteLine($"Data invalid or empty");
                        }
                    }

                    if (functionRegex == null || Regex.IsMatch("trade", functionRegex, RegexOptions.IgnoreCase))
                    {
                        try
                        {
                            Console.Write("Test {0} GetHistoricalTradesAsync... ", api.Name);
                            api.GetHistoricalTradesAsync(histTradeCallback, symbol).Sync();
                            Assert(trades.Length != 0 && trades[0].Price > 0m && trades[0].Amount > 0m);
                            Console.WriteLine($"OK ({trades.Length})");

                            Console.Write("Test {0} GetRecentTradesAsync... ", api.Name);
                            trades = api.GetRecentTradesAsync(symbol).Sync().ToArray();
                            Assert(trades.Length != 0 && trades[0].Price > 0m && trades[0].Amount > 0m);
                            Console.WriteLine($"OK ({trades.Length} trades)");
                        }
                        catch (NotImplementedException)
                        {
                            Console.WriteLine($"Not implemented");
                        }
                    }

                    if (functionRegex == null || Regex.IsMatch("candle", functionRegex, RegexOptions.IgnoreCase))
                    {
                        try
                        {
                            Console.Write("Test {0} GetCandlesAsync... ", api.Name);
                            var candles = api.GetCandlesAsync(symbol, 86400, CryptoUtility.UtcNow.Subtract(TimeSpan.FromDays(7.0)), null).Sync().ToArray();
                            Assert(candles.Length != 0 && candles[0].ClosePrice > 0m && candles[0].HighPrice > 0m && candles[0].LowPrice > 0m && candles[0].OpenPrice > 0m &&
                                   candles[0].HighPrice >= candles[0].LowPrice && candles[0].HighPrice >= candles[0].ClosePrice && candles[0].HighPrice >= candles[0].OpenPrice &&
                                   !string.IsNullOrWhiteSpace(candles[0].Name) && candles[0].ExchangeName == api.Name && candles[0].PeriodSeconds == 86400 && candles[0].BaseVolume > 0.0 &&
                                   candles[0].ConvertedVolume > 0.0 && candles[0].WeightedAverage >= 0m);

                            Console.WriteLine($"OK ({candles.Length})");
                        }
                        catch (NotImplementedException)
                        {
                            Console.WriteLine($"Not implemented");
                        }
                        catch
                        {
                            // These API require private access to get candles end points
                            if (!(api is ExchangeKucoinAPI))
                            {
                                throw;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Request failed, api: {0}, error: {1}", api, ex.Message);
                }
            }
        }
        public async Task GlobalSymbolTest()
        {
            // if tests fail, uncomment this and it will save a new test file
            // string allSymbolsJson = GetAllSymbolsJsonAsync().Sync(); System.IO.File.WriteAllText("TestData/AllSymbols.json", allSymbolsJson);

            string globalMarketSymbol                = "ETH-BTC"; //1 ETH is worth 0.0192 BTC...
            string globalMarketSymbolAlt             = "BTC-KRW"; // WTF Bitthumb... //1 BTC worth 9,783,000 won
            Dictionary <string, string[]> allSymbols = JsonConvert.DeserializeObject <Dictionary <string, string[]> >(System.IO.File.ReadAllText("TestData/AllSymbols.json"));

            // sanity test that all exchanges return the same global symbol when converted back and forth
            foreach (IExchangeAPI api in ExchangeAPI.GetExchangeAPIs())
            {
                try
                {
                    if (api is ExchangeUfoDexAPI || api is ExchangeOKExAPI || api is ExchangeHitBTCAPI || api is ExchangeKuCoinAPI ||
                        api is ExchangeOKCoinAPI || api is ExchangeDigifinexAPI || api is ExchangeNDAXAPI || api is ExchangeBL3PAPI ||
                        api is ExchangeBinanceUSAPI || api is ExchangeBinanceJerseyAPI || api is ExchangeBinanceDEXAPI ||
                        api is ExchangeBitMEXAPI || api is ExchangeBTSEAPI || api is ExchangeBybitAPI)
                    {
                        // WIP
                        continue;
                    }

                    bool   isBithumb            = (api.Name == ExchangeName.Bithumb);
                    string exchangeMarketSymbol = await api.GlobalMarketSymbolToExchangeMarketSymbolAsync(isBithumb?globalMarketSymbolAlt : globalMarketSymbol);

                    string globalMarketSymbol2 = await api.ExchangeMarketSymbolToGlobalMarketSymbolAsync(exchangeMarketSymbol);

                    if ((!isBithumb && globalMarketSymbol2.StartsWith("BTC-")) ||
                        globalMarketSymbol2.StartsWith("USD-") ||
                        globalMarketSymbol2.StartsWith("USDT-"))
                    {
                        Assert.Fail($"Exchange {api.Name} has wrong SymbolIsReversed parameter");
                    }
                    try
                    {
                        if (!allSymbols.ContainsKey(api.Name))
                        {
                            throw new InvalidOperationException("If new exchange has no symbols, run GetAllSymbolsJson to make a new string " +
                                                                "then apply this new string to Resources.AllSymbolsJson");
                        }
                        string[] symbols = allSymbols[api.Name];

                        // BL3P does not have usd
                        if (api.Name != ExchangeName.BL3P)
                        {
                            Assert.IsTrue(symbols.Contains(exchangeMarketSymbol), "Symbols does not contain exchange symbol");
                        }
                    }
                    catch
                    {
                        Assert.Fail("Error getting symbols");
                    }
                    Assert.IsTrue(globalMarketSymbol == globalMarketSymbol2 || globalMarketSymbolAlt == globalMarketSymbol2);
                }
                catch (NotImplementedException)
                {
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Exchange {api.Name} error converting symbol: {ex}");
                }
            }
        }