Exemple #1
0
        public async Task <IEnumerable <Core.Model.Symbol> > GetSymbolsAsync(CancellationToken cancellationToken)
        {
            var binanceApi = new BinanceApi();
            var result     = await binanceApi.GetSymbolsAsync(cancellationToken).ConfigureAwait(false);

            var symbols = result.Select(s => new Core.Model.Symbol
            {
                Name                 = $"{s.BaseAsset.Symbol}{s.QuoteAsset.Symbol}",
                ExchangeSymbol       = $"{s.BaseAsset.Symbol}{s.QuoteAsset.Symbol}",
                Exchange             = Exchange.Binance,
                NotionalMinimumValue = s.NotionalMinimumValue,
                BaseAsset            = new Core.Model.Asset {
                    Symbol = s.BaseAsset.Symbol, Precision = s.BaseAsset.Precision
                },
                Price = new Core.Model.InclusiveRange {
                    Increment = s.Price.Increment                                     /*, Minimum = s.Price.Minimum, Maximum = s.Price.Maximum*/
                },                                                                    // HACK : remove Price Min and Max because it realtime calcs hits performance.
                Quantity = new Core.Model.InclusiveRange {
                    Increment = s.Quantity.Increment, Minimum = s.Quantity.Minimum, Maximum = s.Quantity.Maximum
                },
                QuoteAsset = new Core.Model.Asset {
                    Symbol = s.QuoteAsset.Symbol, Precision = s.QuoteAsset.Precision
                },
                Status           = (Core.Model.SymbolStatus)s.Status,
                IsIcebergAllowed = s.IsIcebergAllowed,
                OrderTypes       = (IEnumerable <Core.Model.OrderType>)s.OrderTypes
            }).ToList();

            return(symbols);
        }
Exemple #2
0
        private async void FormSymbolList_LoadAsync(object sender, EventArgs e)
        {
            var api     = new BinanceApi();
            var symbols = await api.GetSymbolsAsync();

            symbolList = symbols /*.Where(x => x.QuoteAsset.Symbol == "BTC")*/.OrderBy(x => x.BaseAsset.Symbol).Select(x => x.ToString()).ToList();
            comboBoxSymbols.DataSource = symbols /*.Where(x => x.QuoteAsset.Symbol == "BTC")*/.OrderBy(x => x.BaseAsset.Symbol).Select(x => x.BaseAsset.Symbol + " - " + x.QuoteAsset.Symbol).ToList();
        }
Exemple #3
0
        private static async Task Main()
        {
            var assets = new List <Asset>();

            var api = new BinanceApi();

            // Get the current timestamp.
            var timestamp = await api.GetTimestampAsync();

            // Get latest currency pairs (symbols).
            var symbols = (await api.GetSymbolsAsync()).ToList();

            // Get assets.
            foreach (var symbol in symbols)
            {
                if (!assets.Contains(symbol.BaseAsset))
                {
                    assets.Add(symbol.BaseAsset);
                }

                if (!assets.Contains(symbol.QuoteAsset))
                {
                    assets.Add(symbol.QuoteAsset);
                }
            }

            // Read the symbol template file.
            var lines = (await File.ReadAllLinesAsync("Symbol.template.cs")).ToList();

            // Replace remarks.
            var index = lines.FindIndex(l => l.Contains("<remarks></remarks>"));

            lines[index] = $"    /// <remarks>File generated by {nameof(BinanceCodeGenerator)} tool.</remarks>";

            // Replace timestamp.
            index        = lines.FindIndex(l => l.Contains("<<insert timestamp>>"));
            lines[index] = $"        public static readonly long LastUpdateAt = {timestamp};";

            index = lines.FindIndex(l => l.Contains("<<insert symbols>>"));
            lines.RemoveAt(index);

            // Sort symbols.
            symbols.Sort();

            var groups = symbols.GroupBy(s => s.QuoteAsset);

            // Insert definition for each currency pair (symbol).
            foreach (var group in groups)
            {
                lines.Insert(index++, $"        // {group.First().QuoteAsset}");

                foreach (var symbol in group)
                {
                    lines.Insert(index++, $"        public static Symbol {symbol.BaseAsset}_{symbol.QuoteAsset} => Cache.Get(\"{symbol.BaseAsset}{symbol.QuoteAsset}\");");
                }

                lines.Insert(index++, string.Empty);
            }
            lines.RemoveAt(index);

            index = lines.FindIndex(l => l.Contains("<<insert symbol definitions>>"));
            lines.RemoveAt(index);

            foreach (var symbol in symbols)
            {
                var orderTypes = string.Join(",", symbol.OrderTypes.Select(_ => "OrderType." + _));
                lines.Insert(index++, $"                        new Symbol(SymbolStatus.{symbol.Status}, Asset.{symbol.BaseAsset}, Asset.{symbol.QuoteAsset}, ({Convert.ToString(symbol.Quantity.Minimum, CultureInfo.InvariantCulture)}m, {Convert.ToString(symbol.Quantity.Maximum, CultureInfo.InvariantCulture)}m, {Convert.ToString(symbol.Quantity.Increment, CultureInfo.InvariantCulture)}m), ({Convert.ToString(0, CultureInfo.InvariantCulture)}m, {Convert.ToString(0, CultureInfo.InvariantCulture)}m, {Convert.ToString(symbol.Price.Increment, CultureInfo.InvariantCulture)}m), {Convert.ToString(symbol.NotionalMinimumValue, CultureInfo.InvariantCulture)}m, {symbol.IsIcebergAllowed.ToString().ToLowerInvariant()}, new List<OrderType> {{{orderTypes}}}),");
            }

            // Save the generated source code (replacing original).
            await File.WriteAllLinesAsync("../../../../../src/Binance/Symbol.cs", lines);

            // Read the asset template file.
            lines = (await File.ReadAllLinesAsync("Asset.template.cs")).ToList();

            // Replace remarks.
            index        = lines.FindIndex(l => l.Contains("<remarks></remarks>"));
            lines[index] = $"    /// <remarks>File generated by {nameof(BinanceCodeGenerator)} tool.</remarks>";

            // Replace timestamp.
            index        = lines.FindIndex(l => l.Contains("<<insert timestamp>>"));
            lines[index] = $"        public static readonly long LastUpdateAt = {timestamp};";

            index = lines.FindIndex(l => l.Contains("<<insert assets>>"));
            lines.RemoveAt(index);

            // Sort assets.
            assets.Sort();

            // Insert definition for each asset.
            foreach (var asset in assets)
            {
                lines.Insert(index++, $"        public static Asset {asset} => Cache.Get(\"{asset}\");");
            }

            index = lines.FindIndex(l => l.Contains("<<insert asset definitions>>"));
            lines.RemoveAt(index);

            foreach (var asset in assets)
            {
                lines.Insert(index++, $"                        new Asset(\"{asset}\", {Convert.ToString(asset.Precision, CultureInfo.InvariantCulture)}),");
            }

            // Save the generated source code (replacing original).
            await File.WriteAllLinesAsync("../../../../../src/Binance/Asset.cs", lines);

            Console.WriteLine("Successfully generated new Symbol.cs and Asset.cs files.");
            Console.WriteLine();
            Console.WriteLine("  ...press any key to close window.");
            Console.ReadKey(true);
        }
Exemple #4
0
        public override Boolean Initialize()
        {
            m_MessagePump.Signal(Resources.ExchangeInitialization);

            try
            {
                BinanceStatus status = m_Api.GetSystemStatusAsync().Result;

                if (status == BinanceStatus.Maintenance)
                {
                    throw new Exception(Resources.ServerMaintenance);
                }

                TimeSpan delta = TimeSpan.Zero;

                for (Int32 i = 0; i < 5; ++i)
                {
                    DateTime now    = DateTime.Now;
                    Boolean  result = m_Api.PingAsync().Result;

                    if (!result)
                    {
                        throw new Exception(Resources.ServerPing);
                    }

                    delta += DateTime.Now - now;
                }

                m_MessagePump.Signal(Utilities.FormatMessage(Resources.MessageConnectivityOK, delta.Milliseconds / 5));
            }
            catch (Exception e)
            {
                m_MessagePump.Signal(Utilities.FormatMessage(Resources.ConnectivityKO, Utilities.GetExceptionMessage(e)));
                return(false);
            }

            try
            {
                m_User = new BinanceApiUser(Config.KeyApi, Config.KeySecret);
                m_MessagePump.Signal(Resources.LoginOK);
            }
            catch (Exception e)
            {
                m_MessagePump.Signal(Utilities.FormatMessage(Resources.LoginKO, Utilities.GetExceptionMessage(e)));
                return(false);
            }

            try
            {
                UpdateBalances(m_Api.GetAccountInfoAsync(m_User).Result);

                m_UserDataWebSocket = new UserDataWebSocketManager();
                m_UserDataWebSocket.SubscribeAsync <AccountUpdateEventArgs>(m_User, x => UpdateBalances(x.AccountInfo)).Wait();
                m_UserDataWebSocket.WaitUntilWebSocketOpenAsync().Wait();

                if (m_Balances.Count == 0)
                {
                    m_MessagePump.Signal(Resources.BalancesOK0);
                }
                else
                {
                    m_MessagePump.Signal(Utilities.FormatMessage(Resources.BalancesKO, m_Balances.Count, (m_Balances.Count == 1 ? String.Empty : "s")));

                    foreach (KeyValuePair <String, Decimal> balance in m_Balances.OrderBy(x => x.Key))
                    {
                        m_MessagePump.Signal($" - {balance.Value:F8} {balance.Key}");
                    }
                }
            }
            catch (Exception e)
            {
                m_MessagePump.Signal(Utilities.FormatMessage(Resources.BalancesKO, Utilities.GetExceptionMessage(e)));
                return(false);
            }

            try
            {
                Dictionary <String, Int32> symbolsData = new Dictionary <String, Int32>();
                HashSet <String>           assets      = new HashSet <String>();

                foreach (Symbol symbol in m_Api.GetSymbolsAsync().Result)
                {
                    if (symbol.Status != SymbolStatus.Trading)
                    {
                        continue;
                    }

                    String baseAsset  = symbol.BaseAsset;
                    String quoteAsset = symbol.BaseAsset;
                    String name       = symbol.ToString();

                    if ((Config.TradingWhitelist.Count > 0) && (!Config.TradingWhitelist.Contains(baseAsset) || !Config.TradingWhitelist.Contains(quoteAsset)))
                    {
                        continue;
                    }

                    String mininumQuantity = symbol.Quantity.Minimum.ToString(CultureInfo.InvariantCulture);
                    Int32  dustDecimals    = Math.Max(0, mininumQuantity.IndexOf("1", StringComparison.OrdinalIgnoreCase) - 1);

                    assets.Add(baseAsset);
                    assets.Add(quoteAsset);
                    symbolsData[name] = dustDecimals;
                }

                ConcurrentBag <Trade> trades = new ConcurrentBag <Trade>();

                Parallel.ForEach(assets.SelectMany(x => assets, (a1, a2) => new { Asset1 = a1, Asset2 = a2 }), pair =>
                {
                    if (pair.Asset1 == pair.Asset2)
                    {
                        return;
                    }

                    TradeLeg leg1 = BuildTradeLeg(symbolsData, Config.InvestmentBaseAsset, pair.Asset1);

                    if ((leg1 == null) || (leg1.Position != Config.TradingPositions[0]))
                    {
                        return;
                    }

                    TradeLeg leg2 = BuildTradeLeg(symbolsData, pair.Asset1, pair.Asset2);

                    if ((leg2 == null) || (leg2.Position != Config.TradingPositions[1]))
                    {
                        return;
                    }

                    TradeLeg leg3 = BuildTradeLeg(symbolsData, pair.Asset2, Config.InvestmentBaseAsset);

                    if ((leg3 == null) || (leg3.Position != Config.TradingPositions[2]))
                    {
                        return;
                    }

                    trades.Add(new Trade(leg1, leg2, leg3));
                });

                if (trades.Count == 0)
                {
                    throw new Exception(Resources.NoTriangularRelationships);
                }

                m_Trades.AddRange(trades);

                m_MessagePump.Signal(Utilities.FormatMessage(Resources.TradesOK, m_Trades.Count, (m_Trades.Count == 1 ? String.Empty : "s")));
            }
            catch (Exception e)
            {
                m_MessagePump.Signal(Utilities.FormatMessage(Resources.TradesKO, Utilities.GetExceptionMessage(e)));
                return(false);
            }

            try
            {
                List <String> symbols = m_Trades.Select(x => x.Leg1.Symbol)
                                        .Union(m_Trades.Select(x => x.Leg2.Symbol))
                                        .Union(m_Trades.Select(x => x.Leg3.Symbol))
                                        .Distinct().OrderBy(x => x).ToList();

                foreach (String symbol in symbols)
                {
                    m_OrderBooks[symbol] = new SortedOrderBook(m_Api.GetOrderBookAsync(symbol, Config.DataSize).Result);

                    m_OrderBooksCache[symbol]            = new DepthWebSocketCache();
                    m_OrderBooksCache[symbol].Error     += (sender, e) => m_OrderBooks[symbol].Invalid = true;
                    m_OrderBooksCache[symbol].OutOfSync += (sender, e) => m_OrderBooks[symbol].Invalid = true;
                    m_OrderBooksCache[symbol].Subscribe(symbol, e => m_OrderBooks[symbol] = new SortedOrderBook(e.OrderBook));

                    Thread.Sleep(Config.DataStagger);
                }

                m_MessagePump.Signal(Utilities.FormatMessage(Resources.OrderBooksOK, symbols.Count, (symbols.Count == 1 ? String.Empty : "s")));
                m_MessagePump.Signal(String.Empty);

                m_Initialized = true;

                return(true);
            }
            catch (Exception e)
            {
                m_MessagePump.Signal(Utilities.FormatMessage(Resources.OrderBooksKO, Utilities.GetExceptionMessage(e)));
                return(false);
            }
        }
Exemple #5
0
        private static async Task Main()
        {
            var assets = new List <Asset>();

            long timestamp;

            List <Symbol> symbols;

            var api = new BinanceApi();

            // Get the current timestamp.
            timestamp = await api.GetTimestampAsync();

            // Get latest currency pairs (symbols).
            symbols = (await api.GetSymbolsAsync()).ToList();

            // Get assets.
            foreach (var symbol in symbols)
            {
                if (!assets.Contains(symbol.BaseAsset))
                {
                    assets.Add(symbol.BaseAsset);
                }

                if (!assets.Contains(symbol.QuoteAsset))
                {
                    assets.Add(symbol.QuoteAsset);
                }
            }

            // Read the symbol template file.
            var lines = (await File.ReadAllLinesAsync("Symbol.template.cs")).ToList();

            // Replace timestamp.
            var index = lines.FindIndex(l => l.Contains("<<insert timestamp>>"));

            lines[index] = $"        public static readonly long LastUpdateAt = {timestamp};";

            index = lines.FindIndex(l => l.Contains("<<insert symbols>>"));
            lines.RemoveAt(index);

            // Sort symbols.
            symbols.Sort();

            var groups = symbols.GroupBy(s => s.QuoteAsset);

            // Insert definition for each currency pair (symbol).
            foreach (var group in groups)
            {
                lines.Insert(index++, $"        // {group.First().QuoteAsset}");

                foreach (var symbol in group)
                {
                    lines.Insert(index++, $"        public static readonly Symbol {symbol.BaseAsset}_{symbol.QuoteAsset} = new Symbol(Asset.{symbol.BaseAsset}, Asset.{symbol.QuoteAsset}, {symbol.BaseMinQuantity}m, {symbol.BaseMaxQuantity}m, {symbol.QuoteIncrement}m);");
                }

                lines.Insert(index++, string.Empty);
            }
            lines.RemoveAt(index);

            index = lines.FindIndex(l => l.Contains("<<insert symbol definitions>>"));
            lines.RemoveAt(index);

            foreach (var symbol in symbols)
            {
                lines.Insert(index++, $"            {{ \"{symbol}\", {symbol.BaseAsset}_{symbol.QuoteAsset} }},");
            }

            // Save the generated source code (replacing original).
            await File.WriteAllLinesAsync("../../src/Binance/Symbol.cs", lines);

            // Read the asset template file.
            lines = (await File.ReadAllLinesAsync("Asset.template.cs")).ToList();

            // Replace timestamp.
            index        = lines.FindIndex(l => l.Contains("<<insert timestamp>>"));
            lines[index] = $"        public static readonly long LastUpdateAt = {timestamp};";

            index = lines.FindIndex(l => l.Contains("<<insert assets>>"));
            lines.RemoveAt(index);

            // Sort assets.
            assets.Sort();

            // Insert definition for each asset.
            foreach (var asset in assets)
            {
                lines.Insert(index++, $"        public static readonly Asset {asset} = new Asset(\"{asset}\", {asset.Precision});");
            }

            index = lines.FindIndex(l => l.Contains("<<insert asset definitions>>"));
            lines.RemoveAt(index);

            foreach (var asset in assets)
            {
                lines.Insert(index++, $"            {{ \"{asset}\", {asset} }},");
            }

            // Save the generated source code (replacing original).
            await File.WriteAllLinesAsync("../../src/Binance/Asset.cs", lines);

            Console.WriteLine();
            Console.WriteLine("  ...press any key to close window.");
            Console.ReadKey(true);
        }