예제 #1
0
 public async Task ProcessMessage(LimitQueueItem tradeItem)
 {
     foreach (var limitOrder in tradeItem.Orders)
     {
         await _delayWampUpSubject.OnNewOperation(limitOrder.Order.ClientId);
     }
 }
예제 #2
0
        private async Task ProcessMessage(LimitQueueItem tradeItem)
        {
            foreach (var order in tradeItem.Orders)
            {
                foreach (var trade in order.Trades)
                {
                    if (trade.Fees == null)
                    {
                        continue;
                    }

                    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, order.Order.Id, trade.ClientId, trade.OppositeClientId, (decimal)trade.OppositeVolume);
                            }
                            catch (Exception e)
                            {
                                await _log.WriteErrorAsync(nameof(TradeSubscriber), nameof(ProcessMessage), item.Transfer.ToJson(), e);
                            }
                        }
                    }
                }
            }
        }
        public async Task <bool> ProcessMessage(LimitQueueItem tradeItem)
        {
            var trusted = new Dictionary <string, bool>();

            foreach (var limitOrderWithTrades in tradeItem.Orders)
            {
                try
                {
                    var meOrder = limitOrderWithTrades.Order;

                    if (!trusted.ContainsKey(meOrder.ClientId))
                    {
                        trusted[meOrder.ClientId] = await _clientAccountsRepository.IsTrusted(meOrder.ClientId);
                    }

                    var isTrusted = trusted[meOrder.ClientId];

                    var aggregated = AggregateSwaps(limitOrderWithTrades.Trades);

                    ILimitOrder prevOrderState = null;

                    // need previous order state for not trusted clients
                    if (!isTrusted)
                    {
                        prevOrderState = await _limitOrdersRepository.GetOrderAsync(meOrder.Id);
                    }

                    await _limitOrdersRepository.CreateOrUpdateAsync(meOrder);

                    var status = (OrderStatus)Enum.Parse(typeof(OrderStatus), meOrder.Status);

                    IClientTrade[] trades = null;
                    if (status == OrderStatus.Processing || status == OrderStatus.Matched)
                    {
                        trades = await SaveTrades(limitOrderWithTrades);
                    }

                    // all code below is for untrusted users
                    if (isTrusted)
                    {
                        continue;
                    }

                    await SaveTransactionAndContext(trades, aggregated, limitOrderWithTrades);

                    switch (status)
                    {
                    case OrderStatus.InOrderBook:
                    case OrderStatus.Cancelled:
                        await CreateEvent(limitOrderWithTrades, status);

                        break;

                    case OrderStatus.Processing:
                    case OrderStatus.Matched:
                        if (prevOrderState == null)
                        {
                            await CreateEvent(limitOrderWithTrades, OrderStatus.InOrderBook);
                        }
                        await SendMoney(trades, aggregated, meOrder, status);

                        break;

                    case OrderStatus.Dust:
                    case OrderStatus.NoLiquidity:
                    case OrderStatus.NotEnoughFunds:
                    case OrderStatus.ReservedVolumeGreaterThanBalance:
                    case OrderStatus.UnknownAsset:
                    case OrderStatus.LeadToNegativeSpread:
                        await _log.WriteInfoAsync(nameof(LimitTradeQueue), nameof(ProcessMessage), limitOrderWithTrades.ToJson(), "order rejected");

                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(OrderStatus));
                    }

                    if (status == OrderStatus.Cancelled || status == OrderStatus.Matched)
                    {
                        await ReturnRemainingVolume(limitOrderWithTrades);
                    }

                    await UpdateCache(meOrder);

                    await SendPush(aggregated, meOrder, prevOrderState, status);
                }
                catch (Exception e)
                {
                    await _log.WriteErrorAsync(nameof(LimitTradeQueue), nameof(ProcessMessage), limitOrderWithTrades.Order.ToJson(), e);
                }
            }

            return(true);
        }