Ejemplo n.º 1
0
        private void HandleEvent(object sender, ProfitableUserTradedEventArgs e)
        {
            if (e.Report.CurrencySymbol != _config.TargetCurrencySymbol)
            {
                _logger.Information("Report was not targeting our currency symbol.");
                return;
            }

            var eventOwnerUser = _repo.GetUserById(e.UserId);

            if (eventOwnerUser.CurrentWallet.Symbol == CurrentWallet.Symbol)
            {
                _logger.Information($"Skipping report due to trader and our wallets currency equality.");
            }

            if (AttachedUser == null || AttachedUser.Identifier == e.UserId)
            {
                if (!_attempCalculator.IsSucceededAttemp())
                {
                    _logger.Information("Skipping trade due to low attemps count.");
                    return;
                }

                if (AttachedUser == null)
                {
                    _logger.Information($"Attaching to user with Id: {e.UserId}");
                    AttachedUsersHistory.Add(e.UserId);
                    AttachedUserProfit = e.Report;
                    AttachedUser       = eventOwnerUser;
                }

                _logger.Information("Attached user traded. Repeating actions.");
                var trade = _repo.GetTradeById(e.TradeId);
                _lastTradeDate = trade.TradeTime;
                if (AttachedUser.CurrentWallet.Symbol == CurrentWallet.Symbol)
                {
                    _logger.Information("Currently the trader holds the currency that we already have.");
                    return;
                }

                _logger.Warning($"Wallet balance was {CurrentWallet.Amount}{CurrentWallet.Symbol}");
                _logger.Warning($"Selling {CurrentWallet.Amount}{CurrentWallet.Symbol} and buying {AttachedUser.CurrentWallet.Symbol}");
                var newWallet = CalculateWalletBalanceAfterTrade(CurrentWallet, trade.Price);
                Wallets.Add(newWallet);
                _logger.Warning($"After selling balance is {CurrentWallet.Amount}{CurrentWallet.Symbol}");
            }
            else
            {
                var maxTimeToWaitForAttachedUser = TimeSpan.FromTicks(AttachedUserProfit.AverageTradeThreshold.Ticks * 2);

                if (DateTime.UtcNow - _lastTradeDate > maxTimeToWaitForAttachedUser ||
                    e.Report.AverageProfitPerHour > AttachedUserProfit.AverageProfitPerHour)
                {
                    DetachAttachedUser();
                    HandleEvent(this, e);
                }
            }
        }
Ejemplo n.º 2
0
 private void EventHandlerPredicate(object sender, ProfitableUserTradedEventArgs args)
 {
     lock (_lockObject)
     {
         try
         {
             HandleEvent(sender, args);
         }
         catch (Exception e)
         {
             _logger.Error(e, $"An exception was thrown while handling the ProfitableUserTraded event. Trade Id and user Id were: {args?.TradeId} {args?.UserId}");
             throw;
         }
     }
 }
        private void OnUserTraded(object sender, UserTradedEventArgs e)
        {
            _logger.Verbose($"The user with Id {e.UserId} seems to be trading.");
            var userProfit = _ups.GetUserProfit(e.UserId);

            if (IsProfitableUser(userProfit))
            {
                _logger.Information($"The user with Id {e.UserId} seems to be profitable.");
                var eventArgs = new ProfitableUserTradedEventArgs()
                {
                    UserId  = e.UserId,
                    TradeId = e.TradeId,
                    Report  = userProfit,
                };

                ProfitableUserTraded?.Invoke(this, eventArgs);
            }
        }
Ejemplo n.º 4
0
        private void HandleEvent(object sender, ProfitableUserTradedEventArgs e)
        {
            if (_isTradingLocked)
            {
                UpdateLockedState();

                if (_isTradingLocked)
                {
                    _logger.Information($"Trading is locked. Skipping profitable user with Id: {e.UserId}");
                    return;
                }
                else
                {
                    UpdateCurrentWallet();
                }
            }

            if (e.Report.CurrencySymbol != _config.TargetCurrencySymbol)
            {
                _logger.Information("Report was not targeting our currency symbol.");
                return;
            }

            var traderUser = _repo.GetUserById(e.UserId);

            if (traderUser.CurrentWallet.Symbol == CurrentWallet.Symbol)
            {
                _logger.Information("Currently the trader holds the currency that we already have.");
                return;
            }

            if (e.Report.AverageProfitPerHour < _config.Limiters.MinimalTraderProfitPerHourPercentage ||
                e.Report.AverageTradesPerHour > _config.Limiters.MaximalTraderTradesPerHour)
            {
                _logger.Information($"Skipping profitable user's trade due to limiters. Trader user Id was {e.UserId}");
                if (AttachedUser?.Identifier == e.UserId)
                {
                    DetachAttachedUser();
                }

                return;
            }

            if (AttachedUser == null || AttachedUser?.Identifier == e.UserId)
            {
                if (!_attempCalculator.IsSucceededAttemp())
                {
                    _logger.Information("Skipping trade due to low attemps count.");
                    return;
                }

                if (AttachedUser == null)
                {
                    _logger.Information($"Attaching to user with Id: {e.UserId}");
                    AttachedUsersHistory.Add(e.UserId);
                    AttachedUserProfit = e.Report;
                    AttachedUser       = traderUser;
                }

                _logger.Information("Attached user traded. Repeating actions.");
                using (var client = CreateBinanceClient())
                {
                    var trade       = _repo.GetTradeById(e.TradeId);
                    var orderSide   = CurrentWallet.Symbol == _symbolPair.Symbol1 ? OrderSide.Sell : OrderSide.Buy;
                    var priceResult = client.GetPrice(_symbolPair.ToString());
                    var price       = priceResult.Data.Price;
                    var quantity    = CurrentWallet.Symbol == _symbolPair.Symbol1 ? CurrentWallet.Amount : CurrentWallet.Amount / price;
                    quantity = RecorrectQuantity(quantity);

                    _logger.Warning($"Wallet balance is {CurrentWallet.Amount}{CurrentWallet.Symbol}");
                    _logger.Warning($"Selling {CurrentWallet.Amount}{CurrentWallet.Symbol} and buying {AttachedUser.CurrentWallet.Symbol} with price of {price}.");

                    var placeOrderResult = client.PlaceOrder(
                        timeInForce: TimeInForce.GoodTillCancel,
                        symbol: _symbolPair.ToString(),
                        quantity: quantity,
                        type: OrderType.Limit,
                        side: orderSide,
                        price: price);

                    _repo.BlacklistOrder(placeOrderResult.Data.OrderId);

                    _isTradingLocked    = true;
                    _lastTradeDate      = trade.TradeTime;
                    _lastLockTime       = DateTime.UtcNow;
                    _lockedDueToOrderId = placeOrderResult.Data.OrderId;
                }
                _logger.Warning($"Locked the trading until the order with Id {_lockedDueToOrderId} become filled/expired/rejected.");
            }
            else
            {
                var maxSecondsToWait = AttachedUserProfit.AverageTradeThreshold.TotalSeconds * Math.E;
                maxSecondsToWait = Math.Min(maxSecondsToWait, _config.Limiters.MaximalSecondsToWaitForTheTrader);

                if (DateTime.UtcNow - _lastTradeDate > TimeSpan.FromSeconds(maxSecondsToWait) ||
                    e.Report.AverageProfitPerHour > AttachedUserProfit.AverageProfitPerHour * Math.E &&
                    e.Report.AverageTradesPerHour < AttachedUserProfit.AverageTradesPerHour)
                {
                    DetachAttachedUser();
                    HandleEvent(this, e);
                }
            }
        }