예제 #1
0
        public async Task <decimal?> GetBalance(string symbol)
        {
            var accountInfo = await _binanceClient.GetAccountInfoAsync(_user);

            var balance = accountInfo.Balances.FirstOrDefault(b =>
                                                              b.Asset.Equals(symbol, StringComparison.InvariantCultureIgnoreCase));

            return(balance?.Free);
        }
        public async void OnTick()
        {
            Log.Info("Grabbing account info...");
            var info = await _api.GetAccountInfoAsync(_user);

            Log.Info(" - User: {0}", info.User.ApiKey);
            Log.Info(" - Able to trade: {0}", info.Status.CanTrade);
            Log.Info(" - Able to withdraw: {0}", info.Status.CanWithdraw);
            Log.Info(" - Able to deposit: {0}", info.Status.CanDeposit);
            Log.Info(" - Free {0}: {1}", _baseCurrency, info.GetBalance(_baseCurrency).Free);
            Log.Info(" - Locked {0}: {1}", _baseCurrency, info.GetBalance(_baseCurrency).Locked);
            Log.Info(" - Free {0}: {1}", _tradeCurrency, info.GetBalance(_tradeCurrency).Free);
            Log.Info(" - Locked {0}: {1}", _tradeCurrency, info.GetBalance(_tradeCurrency).Locked);
        }
예제 #3
0
        public async Task <Core.Model.AccountInfo> GetAccountInfoAsync(Core.Model.User user, CancellationToken cancellationToken)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var binanceApi = new BinanceApi();

            using var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret);
            var result = await binanceApi.GetAccountInfoAsync(apiUser, 0, cancellationToken).ConfigureAwait(false);

            var accountInfo = GetAccountInfo(result);

            user.RateLimiter = new Core.Model.RateLimiter {
                IsEnabled = result.User.RateLimiter.IsEnabled
            };
            accountInfo.User = user;
            return(accountInfo);
        }
예제 #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);
            }
        }