private TradeRegistrationContext RegisterNewUser(TradeRegistrationContext context, bool isBuyer)
        {
            var user = new BinanceUser()
            {
                WalletsHistory = new List <Wallet>(),
                Identifier     = IdentificationUtilities.GetRandomIdentifier(),
            };

            var pair        = isBuyer ? context.SellingPair : context.BuyingPair;
            var firstWallet = new Wallet()
            {
                Symbol  = pair.Symbol,
                OwnerId = user.Identifier,
                Balance = pair.Amount,
                WalletCreatedFromTradeId = context.Trade.TradeId,
            };

            user.WalletsHistory.Add(firstWallet);
            var secondWallet = firstWallet.Clone();

            pair = isBuyer ? context.BuyingPair : context.SellingPair;
            secondWallet.Symbol  = pair.Symbol;
            secondWallet.Balance = pair.Amount;
            user.WalletsHistory.Add(secondWallet);

            _repository.AddOrUpdateUser(user);
            _logger.Debug($"Registered a new user with Id: {user.Identifier}");
            return(context);
        }
Example #2
0
        public void AddOrUpdateUser(BinanceUser user)
        {
            var key = user.Identifier;

            if (_usersCache.Get(key) != null)
            {
                _usersCache.Remove(key);
            }

            _usersCache.Add(key, user, GetTimeoutPolicy());
        }
Example #3
0
        public UserProfitReport GetUserProfit(BinanceUser user)
        {
            _logger.Verbose($"Starting profit calculation for user with Id: {user.Identifier}");
            var trades = new List <Trade>();
            var profit = new UserProfitReport();

            Debug.Assert(user.WalletsHistory[1].WalletCreatedFromTradeId == user.WalletsHistory[0].WalletCreatedFromTradeId);
            foreach (var tradeId in user.WalletsHistory.Select(w => w.WalletCreatedFromTradeId).Skip(1)) // First two wallets are created from the same trade.
            {
                var trade = _repository.GetTradeById(tradeId);
                trades.Add(trade);
            }

            var selectedWallets = user.WalletsHistory.Where(w => w.Symbol == _config.TargetCurrencySymbol).ToList();

            profit.AverageProfitPerHour = CalculateProfitPerHour(selectedWallets);
            profit.CurrencySymbol       = _config.TargetCurrencySymbol;

            var lastTrade = _repository.GetTradeById(user.CurrentWallet.WalletCreatedFromTradeId);

            if (DateTime.UtcNow - lastTrade.TradeTime > TimeSpan.FromSeconds(_config.Limiters.MaximalAllowedTradeSyncSeconds))
            {
                _logger.Information($"User with Id {user.Identifier} had last trade with Id {lastTrade.TradeId} out of sync.");
                profit.IsFullReport = false;
                return(profit);
            }

            if (selectedWallets.Count < 3 || profit.AverageProfitPerHour == default)
            {
                _logger.Verbose($"User with Id {user.Identifier} had small amount of information. Aborting report calculation.");
                profit.IsFullReport = false;
                return(profit);
            }

            var dateDiffList = new List <TimeSpan>(capacity: trades.Count - 1);

            for (int i = 1; i < trades.Count; i++)
            {
                dateDiffList.Add(trades[i].TradeTime - trades[i - 1].TradeTime);
            }

            profit.IsFullReport          = true;
            profit.EndBalance            = selectedWallets.Last().Balance;
            profit.StartBalance          = selectedWallets.First().Balance;
            profit.TotalTradesCount      = user.WalletsHistory.Count - 1;
            profit.SuccessFailureRatio   = GetSuccessFailureRate(selectedWallets);
            profit.MinimalTradeThreshold = TimeSpan.FromSeconds(dateDiffList.Min(diff => diff.TotalSeconds));
            profit.AverageTradeThreshold = TimeSpan.FromSeconds(dateDiffList.Average(diff => diff.TotalSeconds));
            profit.AverageTradesPerHour  = GetTradesPerHour(profit.TotalTradesCount, profit.AverageTradeThreshold);

            return(profit);
        }