private async Task ProcessMessage(TradeQueueItem queueMessage)
 {
     foreach (var trade in queueMessage.Trades)
     {
         if (trade.Fees != null)
         {
             foreach (var item in trade.Fees)
             {
                 if (item.Transfer != null)
                 {
                     try
                     {
                         await _paidFeeQueueWriter.AddPaidFee(Guid.NewGuid(), item.Transfer.Asset,
                                                              item.Transfer.FromClientId, item.Transfer.ToClientId, (decimal)item.Transfer.Volume,
                                                              item.Transfer.Date, queueMessage.Order.Id, trade.MarketClientId, trade.LimitClientId, (decimal)trade.LimitVolume);
                     }
                     catch (Exception e)
                     {
                         await _log.WriteErrorAsync(nameof(TradeSubscriber), nameof(ProcessMessage), item.Transfer.ToJson(), e);
                     }
                 }
             }
         }
     }
 }
Exemple #2
0
        private async Task ProcessTrade(TradeQueueItem message)
        {
            if (!message.Order.Status.Equals("matched", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            var pair = await _assetsService.AssetPairGetAsync(message.Order.AssetPairId);

            if (pair == null)
            {
                throw new ArgumentNullException(nameof(pair));
            }

            bool isLimitAssetBase = message.Trades.First().LimitAsset == pair.BaseAssetId;

            var limitAsset = await _assetsService.AssetGetAsync(message.Trades.First().LimitAsset);

            if (limitAsset == null)
            {
                throw new ArgumentNullException(nameof(limitAsset));
            }

            var marketAsset = await _assetsService.AssetGetAsync(message.Trades.First().MarketAsset);

            if (marketAsset == null)
            {
                throw new ArgumentNullException(nameof(marketAsset));
            }

            foreach (var trade in message.Trades)
            {
                await _tradesCommonRepository.InsertCommonTrade(new TradeCommon
                {
                    Amount        = isLimitAssetBase ? trade.LimitVolume : trade.MarketVolume,
                    AssetPair     = message.Order.AssetPairId,
                    BaseAsset     = isLimitAssetBase ? limitAsset.DisplayId : marketAsset.DisplayId,
                    BaseAssetId   = isLimitAssetBase ? trade.LimitAsset : trade.MarketAsset,
                    QuotAssetId   = isLimitAssetBase ? trade.MarketAsset : trade.LimitAsset,
                    Dt            = trade.Timestamp,
                    Id            = Guid.NewGuid().ToString(),
                    LimitOrderId  = trade.LimitOrderId,
                    MarketOrderId = message.Order.Id,
                    Price         = trade.Price.GetValueOrDefault(),
                    QuotAsset     = isLimitAssetBase ? marketAsset.DisplayId : limitAsset.DisplayId,
                });
            }
        }
Exemple #3
0
        public async Task <bool> ProcessMessage(TradeQueueItem queueMessage)
        {
            await _marketOrdersRepository.CreateAsync(queueMessage.Order);

            if (!queueMessage.Order.Status.Equals("matched", StringComparison.OrdinalIgnoreCase))
            {
                await _log.WriteInfoAsync(nameof(TradeQueue), nameof(ProcessMessage), queueMessage.Order.ToJson(), "Message processing being aborted, due to order status is not matched. Order was saved");

                return(true);
            }

            var walletCredsMarket = await _walletCredentialsRepository.GetAsync(queueMessage.Trades[0].MarketClientId);

            var walletCredsLimit = await _walletCredentialsRepository.GetAsync(queueMessage.Trades[0].LimitClientId);

            var clientTrades = queueMessage.ToDomainOffchain(walletCredsMarket, walletCredsLimit, await _assetsService.GetAllAssetsAsync());

            var notify = new HashSet <string>();

            try
            {
                // for trusted clients only write history (finally block)
                if (await _clientAccountsRepository.IsTrusted(queueMessage.Order.ClientId))
                {
                    return(true);
                }

                // get operations only by market order user (limit user will be processed in limit trade queue)
                var operations = AggregateSwaps(queueMessage.Trades).Where(x => x.ClientId == queueMessage.Order.ClientId).ToList();

                await CreateTransaction(queueMessage.Order.ExternalId, operations, clientTrades);

                var ethereumTxRequest = await _ethereumTransactionRequestRepository.GetByOrderAsync(queueMessage.Order.ExternalId);

                if (ethereumTxRequest != null)
                {
                    var wasTransferOk = await ProcessEthGuaranteeTransfer(ethereumTxRequest, operations, clientTrades);

                    if (!wasTransferOk)
                    {
                        return(true);
                    }
                }

                var sellOperations = operations.Where(x => x.Amount < 0);
                var buyOperations  = operations.Where(x => x.Amount > 0);

                foreach (var operation in sellOperations)
                {
                    var asset = await _assetsService.TryGetAssetAsync(operation.AssetId);

                    if (asset.Blockchain == Blockchain.Ethereum)
                    {
                        continue;   //guarantee transfer already sent for eth
                    }
                    // return change in offchain
                    var offchainOrder = await _offchainOrdersRepository.GetOrder(queueMessage.Order.ExternalId);

                    var change = offchainOrder.ReservedVolume - Math.Abs(operation.Amount);

                    if (change < 0)
                    {
                        await _log.WriteWarningAsync(nameof(TradeQueue), nameof(ProcessMessage),
                                                     $"Order: [{offchainOrder.OrderId}], data: [{operation.ToJson()}]",
                                                     "Diff is less than ZERO !");
                    }

                    if (change > 0)
                    {
                        await _offchainRequestService.CreateOffchainRequestAndNotify(operation.TransferId, operation.ClientId,
                                                                                     operation.AssetId, change, offchainOrder.OrderId, OffchainTransferType.FromHub);

                        notify.Add(operation.ClientId);
                    }
                }

                foreach (var operation in buyOperations)
                {
                    var asset = await _assetsService.TryGetAssetAsync(operation.AssetId);

                    if (asset.Blockchain == Blockchain.Ethereum)
                    {
                        await ProcessEthBuy(operation, asset, clientTrades, queueMessage.Order.ExternalId);

                        continue;
                    }

                    await _offchainRequestService.CreateOffchainRequestAndNotify(operation.TransferId, operation.ClientId,
                                                                                 operation.AssetId, operation.Amount, queueMessage.Order.ExternalId, OffchainTransferType.FromHub);

                    notify.Add(operation.ClientId);
                }
            }
            finally
            {
                await _clientTradesRepository.SaveAsync(clientTrades);

                foreach (var item in notify)
                {
                    await _offchainRequestService.NotifyUser(item);
                }
            }

            return(true);
        }
Exemple #4
0
 private async Task ProcessMessage(TradeQueueItem queueMessage)
 {
     await _delayWampUpSubject.OnNewOperation(queueMessage.Order.ClientId);
 }