public async Task <AssetBalanceModel> GetByAssetIdAsync(string assetId) { Balance balance = await _balanceService.GetByAssetIdAsync(assetId); var model = Mapper.Map <AssetBalanceModel>(balance); return(model); }
private async Task ProcessInstrumentAsync(Instrument instrument) { Quote quote = _quoteService.Get(instrument.QuoteSource, instrument.AssetPairId); if (quote == null) { _log.WarningWithDetails("No quote for instrument", new { instrument.AssetPairId }); return; } AssetPair assetPair = _assetPairsReadModelRepository.TryGetIfEnabled(instrument.AssetPairId); if (assetPair == null) { _log.WarningWithDetails("Asset pair not found", new { instrument.AssetPairId }); return; } Balance balance = await _balanceService.GetByAssetIdAsync(assetPair.BaseAssetId); IReadOnlyCollection <LimitOrder> limitOrders = EvenlyDistributedVolumeTrader.Calculate(quote, instrument, balance.Amount, assetPair.Accuracy, assetPair.InvertedAccuracy); await ValidateQuoteAsync(limitOrders, quote); ValidateMinVolume(limitOrders, assetPair.MinVolume); await _orderBookService.UpdateAsync(new OrderBook { AssetPairId = instrument.AssetPairId, Time = DateTime.UtcNow, LimitOrders = limitOrders }); if (instrument.Mode != InstrumentMode.Active) { SetError(limitOrders, LimitOrderError.Idle); } limitOrders = limitOrders .Where(o => o.Error == LimitOrderError.None) .ToArray(); try { await _lykkeExchangeService.ApplyAsync(instrument.AssetPairId, limitOrders); } catch (Exception exception) { _log.WarningWithDetails("An error occurred while processing limit orders", exception, limitOrders); SetError(limitOrders, LimitOrderError.Unknown, "ME error"); } }
public async Task <AssetBalanceModel> GetLykkeBalanceByAssetIdAsync(string assetId) { Balance balance = await _balanceService.GetByAssetIdAsync(ExchangeNames.Lykke, assetId); Credit credit = await _creditService.GetByAssetIdAsync(assetId); decimal balanceAmount = balance?.Amount ?? decimal.Zero; decimal creditAmount = credit?.Amount ?? decimal.Zero; return(new AssetBalanceModel { AssetId = assetId, Amount = balanceAmount, CreditAmount = creditAmount, Disbalance = balanceAmount - creditAmount }); }
private async Task <bool> ValidateBalanceAsync(InternalOrder internalOrder) { Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); Asset asset; decimal amount; if (internalOrder.Type == LimitOrderType.Sell) { asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.QuotingAssetId); amount = (internalOrder.Volume * internalOrder.Price).TruncateDecimalPlaces(asset.Accuracy, true); } else { asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.BaseAssetId); amount = internalOrder.Volume; } Balance balance = await _balanceService.GetByAssetIdAsync(ExchangeNames.Lykke, asset.Id); if (balance.Amount < amount) { internalOrder.Status = InternalOrderStatus.Rejected; internalOrder.RejectReason = Errors.NotEnoughLiquidity; await _internalOrderRepository.UpdateAsync(internalOrder); return(false); } return(true); }
private async Task <OrderBook> CalculateDirectOrderBookAsync(Instrument instrument, DateTime iterationDateTime) { Quote[] quotes = _b2C2OrderBookService.GetQuotes(instrument.AssetPairId); if (quotes == null || quotes.Length != 2) { _log.WarningWithDetails("No quotes for instrument", instrument.AssetPairId); return(null); } Balance baseAssetBalance = null; Balance quoteAssetBalance = null; TimeSpan timeSinceLastTrade = TimeSpan.Zero; if (instrument.AllowSmartMarkup) { AssetPairLink assetPairLink = await _assetPairLinkService.GetByInternalAssetPairIdAsync(instrument.AssetPairId); if (assetPairLink != null && !assetPairLink.IsEmpty()) { baseAssetBalance = await _balanceService.GetByAssetIdAsync(ExchangeNames.B2C2, assetPairLink.ExternalBaseAssetId); quoteAssetBalance = await _balanceService.GetByAssetIdAsync(ExchangeNames.B2C2, assetPairLink.ExternalQuoteAssetId); timeSinceLastTrade = DateTime.UtcNow - _tradeService.GetLastInternalTradeTime(instrument.AssetPairId); } else { _log.WarningWithDetails("The asset pair link does not configured", new { instrument.AssetPairId }); } } AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); Asset baseAsset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.BaseAssetId); MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); decimal globalMarkup = marketMakerSettings.LimitOrderPriceMarkup; decimal noQuotesMarkup = await _noFreshQuotesStopLossService.GetNoFreshQuotesMarkup(assetPair.Id); decimal pnLStopLossMarkup = await _pnLStopLossEngineService.GetTotalMarkupByAssetPairIdAsync(assetPair.Id); decimal fiatEquityStopLossMarkup = await _fiatEquityStopLossService.GetFiatEquityMarkup(assetPair.Id); _log.InfoWithDetails("Arguments for Calculator.CalculateLimitOrders(...).", new { instrument.AssetPairId, quotes, levels = instrument.Levels.ToArray(), baseAmountBalance = baseAssetBalance?.Amount ?? 0, quoteAmountBalance = quoteAssetBalance?.Amount ?? 0, timeSinceLastTradeTotalSeconds = (int)timeSinceLastTrade.TotalSeconds, instrumentHalfLifePeriod = instrument.HalfLifePeriod, instrumentAllowSmartMarkup = instrument.AllowSmartMarkup, marketMakerSettingsLimitOrderPriceMarkup = globalMarkup, pnLStopLossMarkup, fiatEquityStopLossMarkup, noQuotesMarkup, assetPairAccuracy = assetPair.Accuracy, baseAssetAccuracy = baseAsset.Accuracy, instrument }); OrderBookUpdateReport orderBookUpdateReport = null; if (_isOrderBooksUpdateReportEnabled) { orderBookUpdateReport = new OrderBookUpdateReport(iterationDateTime); orderBookUpdateReport.AssetPair = instrument.AssetPairId; orderBookUpdateReport.FirstQuoteAsk = quotes[0].Ask; orderBookUpdateReport.FirstQuoteBid = quotes[0].Bid; orderBookUpdateReport.SecondQuoteAsk = quotes[1].Ask; orderBookUpdateReport.SecondQuoteBid = quotes[1].Bid; orderBookUpdateReport.QuoteDateTime = quotes[0].Time; orderBookUpdateReport.GlobalMarkup = globalMarkup; orderBookUpdateReport.NoFreshQuoteMarkup = noQuotesMarkup; orderBookUpdateReport.PnLStopLossMarkup = pnLStopLossMarkup; orderBookUpdateReport.FiatEquityMarkup = fiatEquityStopLossMarkup; } IReadOnlyCollection <LimitOrder> limitOrders = Calculator.CalculateLimitOrders( quotes[0], quotes[1], instrument.Levels.ToArray(), baseAssetBalance?.Amount ?? 0, quoteAssetBalance?.Amount ?? 0, (int)timeSinceLastTrade.TotalSeconds, instrument.HalfLifePeriod, instrument.AllowSmartMarkup, globalMarkup, pnLStopLossMarkup, fiatEquityStopLossMarkup, noQuotesMarkup, assetPair.Accuracy, baseAsset.Accuracy, orderBookUpdateReport); await ValidateQuoteTimeoutAsync(limitOrders, quotes[0]); await ValidateQuoteTimeoutAsync(limitOrders, quotes[1]); ValidateMinVolume(limitOrders, (decimal)assetPair.MinVolume); await ValidatePriceAsync(limitOrders); await ValidateBalanceAsync(limitOrders, assetPair); WriteInfoLog(instrument.AssetPairId, quotes, timeSinceLastTrade, limitOrders, "Direct limit orders calculated"); if (orderBookUpdateReport != null) { await _orderBooksUpdatesReportPublisher.PublishAsync(orderBookUpdateReport); } return(new OrderBook { AssetPairId = instrument.AssetPairId, Time = DateTime.UtcNow, LimitOrders = limitOrders, IsDirect = true }); }
public async Task <BalanceModel> GetByAssetIdAsync(string assetId) { Balance balance = await _balanceService.GetByAssetIdAsync(assetId); return(Mapper.Map <BalanceModel>(balance)); }
private async Task <OrderBook> CalculateDirectOrderBookAsync(Instrument instrument) { Quote[] quotes = _b2C2OrderBookService.GetQuotes(instrument.AssetPairId); if (quotes == null || quotes.Length != 2) { _log.WarningWithDetails("No quotes for instrument", instrument.AssetPairId); return(null); } Balance baseAssetBalance = null; Balance quoteAssetBalance = null; TimeSpan timeSinceLastTrade = TimeSpan.Zero; if (instrument.AllowSmartMarkup) { AssetPairLink assetPairLink = await _assetPairLinkService.GetByInternalAssetPairIdAsync(instrument.AssetPairId); if (assetPairLink != null && !assetPairLink.IsEmpty()) { baseAssetBalance = await _balanceService.GetByAssetIdAsync(ExchangeNames.B2C2, assetPairLink.ExternalBaseAssetId); quoteAssetBalance = await _balanceService.GetByAssetIdAsync(ExchangeNames.B2C2, assetPairLink.ExternalQuoteAssetId); timeSinceLastTrade = DateTime.UtcNow - _tradeService.GetLastInternalTradeTime(instrument.AssetPairId); } else { _log.WarningWithDetails("The asset pair link does not configured", new { instrument.AssetPairId }); } } AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); Asset baseAsset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.BaseAssetId); MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); decimal pnLStopLossMarkup = await _pnLStopLossEngineService.GetTotalMarkupByAssetPairIdAsync(assetPair.Id); decimal fiatEquityStopLossMarkup = await _fiatEquityStopLossService.GetFiatEquityMarkup(assetPair.Id); decimal stopLossMarkup = await _noFreshQuotesStopLossService.GetNoFreshQuotesMarkup(assetPair.Id); IReadOnlyCollection <LimitOrder> limitOrders = Calculator.CalculateLimitOrders( quotes[0], quotes[1], instrument.Levels.ToArray(), baseAssetBalance?.Amount ?? 0, quoteAssetBalance?.Amount ?? 0, (int)timeSinceLastTrade.TotalSeconds, instrument.HalfLifePeriod, instrument.AllowSmartMarkup, marketMakerSettings.LimitOrderPriceMarkup, pnLStopLossMarkup, fiatEquityStopLossMarkup, stopLossMarkup, assetPair.Accuracy, baseAsset.Accuracy); await ValidateQuoteTimeoutAsync(limitOrders, quotes[0]); await ValidateQuoteTimeoutAsync(limitOrders, quotes[1]); ValidateMinVolume(limitOrders, (decimal)assetPair.MinVolume); await ValidatePriceAsync(limitOrders); await ValidateBalanceAsync(limitOrders, assetPair); WriteInfoLog(instrument.AssetPairId, quotes, timeSinceLastTrade, limitOrders, "Direct limit orders calculated"); return(new OrderBook { AssetPairId = instrument.AssetPairId, Time = DateTime.UtcNow, LimitOrders = limitOrders, IsDirect = true }); }