public async Task <decimal> GetNoFreshQuotesMarkup(string assetPairId) { MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); TimeSpan noFreshQuotesInterval = marketMakerSettings.NoFreshQuotesInterval; decimal noFreshQuotesMarkup = marketMakerSettings.NoFreshQuotesMarkup; if (noFreshQuotesInterval == default(TimeSpan) || noFreshQuotesMarkup == default(decimal)) { return(0); } Quote quote = await _quoteService.GetAsync(ExchangeNames.B2C2, assetPairId); if (quote == null) { return(noFreshQuotesMarkup); } if (DateTime.UtcNow - quote.Time > noFreshQuotesInterval) { return(noFreshQuotesMarkup); } return(0); }
public async Task InsertOrReplaceAsync(MarketMakerSettings marketMakerSettings) { var entity = new MarketMakerSettingsEntity(GetPartitionKey(), GetRowKey()); Mapper.Map(marketMakerSettings, entity); await _storage.InsertOrReplaceAsync(entity); }
public async Task <decimal> GetNoFreshQuotesMarkup(string assetPairId) { MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); TimeSpan noFreshQuotesInterval = marketMakerSettings.NoFreshQuotesInterval; decimal noFreshQuotesMarkup = marketMakerSettings.NoFreshQuotesMarkup; if (noFreshQuotesInterval == default(TimeSpan) || noFreshQuotesMarkup == default(decimal)) { _log.InfoWithDetails("No quotes check.", new { assetPairId, noFreshQuotesIntervalEqual = noFreshQuotesInterval == default(TimeSpan), noFreshQuotesMarkupEqual = noFreshQuotesMarkup == default(decimal), noFreshQuotesInterval, noFreshQuotesMarkup }); return(0); } Quote quote = await _quoteService.GetAsync(ExchangeNames.B2C2, assetPairId); if (quote == null) { _log.InfoWithDetails("Quote is null.", assetPairId); return(noFreshQuotesMarkup); } _log.InfoWithDetails("Checking time.", new { assetPairId, quote.Time, noFreshQuotesInterval }); if (DateTime.UtcNow - quote.Time > noFreshQuotesInterval) { _log.InfoWithDetails("No quotes.", new { assetPairId, quote.Time, noFreshQuotesInterval }); return(noFreshQuotesMarkup); } _log.InfoWithDetails("There is a quote so markup is 0.", new { assetPairId, quote.Time, noFreshQuotesInterval }); return(0); }
public static SettingsMarketMakerNoSql Create(MarketMakerSettings settings) { return(new SettingsMarketMakerNoSql() { PartitionKey = GeneratePartitionKey(), RowKey = GenerateRowKey(), Settings = settings }); }
private async Task ValidatePriceAsync(IReadOnlyCollection <LimitOrder> limitOrders) { MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); if (marketMakerSettings.LimitOrderPriceMaxDeviation == 0) { return; } LimitOrder[] sellLimitOrders = limitOrders .Where(o => o.Type == LimitOrderType.Sell) .OrderBy(o => o.Price) .ToArray(); LimitOrder[] buyLimitOrders = limitOrders .Where(o => o.Type == LimitOrderType.Buy) .OrderByDescending(o => o.Price) .ToArray(); if (sellLimitOrders.Any()) { decimal maxSellPrice = sellLimitOrders[0].Price * (1 + marketMakerSettings.LimitOrderPriceMaxDeviation); foreach (LimitOrder limitOrder in sellLimitOrders.Where(o => o.Error == LimitOrderError.None)) { if (limitOrder.Price > maxSellPrice) { limitOrder.Error = LimitOrderError.PriceIsOutOfTheRange; } } } if (buyLimitOrders.Any()) { decimal minBuyPrice = buyLimitOrders[0].Price * (1 - marketMakerSettings.LimitOrderPriceMaxDeviation); foreach (LimitOrder limitOrder in buyLimitOrders.Where(o => o.Error == LimitOrderError.None)) { if (limitOrder.Price < minBuyPrice) { limitOrder.Error = LimitOrderError.PriceIsOutOfTheRange; } } } }
public async Task <decimal> GetFiatEquityMarkup(string assetPairId) { AssetPair lykkeAssetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(assetPairId); Domain.AssetSettings quoteAssetSettings = await _assetSettingsService.GetByLykkeIdAsync(lykkeAssetPair.QuotingAssetId); if (quoteAssetSettings == null) { _log.WarningWithDetails("Can't find asset settings while calculating fiat equity.", lykkeAssetPair.QuotingAssetId); return(0); } if (quoteAssetSettings.IsCrypto) { return(0); } decimal fiatEquity = GetFiatEquity(); if (fiatEquity >= 0) { return(0); } MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); decimal thresholdFrom = marketMakerSettings.FiatEquityThresholdFrom; decimal thresholdTo = marketMakerSettings.FiatEquityThresholdTo; decimal markupFrom = marketMakerSettings.FiatEquityMarkupFrom; decimal markupTo = marketMakerSettings.FiatEquityMarkupTo; if (thresholdFrom >= thresholdTo) { return(0); } decimal markup = CalculateMarkup(fiatEquity, thresholdFrom, thresholdTo, markupFrom, markupTo); return(markup); }
public async Task <MarketMakerSettings> GetAsync() { MarketMakerSettings marketMakerSettings = _cache.Get(CacheKey); if (marketMakerSettings == null) { marketMakerSettings = await _marketMakerSettingsRepository.GetAsync(); if (marketMakerSettings == null) { marketMakerSettings = new MarketMakerSettings { LimitOrderPriceMaxDeviation = 0.2m }; } _cache.Set(marketMakerSettings); } return(marketMakerSettings); }
public async Task <MarketMakerSettingsModel> GetMarketMakerSettingsAsync() { MarketMakerSettings marketMakerSettings = await _marketMakerSettingsService.GetAsync(); return(Mapper.Map <MarketMakerSettingsModel>(marketMakerSettings)); }
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 }); }
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 }); }
public async Task UpdateAsync(MarketMakerSettings marketMakerSettings) { await _marketMakerSettingsRepository.InsertOrReplaceAsync(marketMakerSettings); _cache.Set(marketMakerSettings); }
public Task UpdateMarketMakerSettingsAsync(MarketMakerSettings request) { return(_manager.UpdateMarketMakerSettingsAsync(request)); }