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); }
public void AddOrUpdateUser(BinanceUser user) { var key = user.Identifier; if (_usersCache.Get(key) != null) { _usersCache.Remove(key); } _usersCache.Add(key, user, GetTimeoutPolicy()); }
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); }