public static double CalculateAveragePrice( OrderBookNoSql orderBook, ISpotInstrument instrument, IAsset fromAsset, IAsset toAsset, IAsset volumeAsset, double volume) { if (instrument.BaseAsset == fromAsset.Symbol && volumeAsset.Symbol == fromAsset.Symbol) { return((double)CalculateAveragePriceStraight(orderBook.BuyLevels.OrderByDescending(e => e.Price), (decimal)volume, instrument.Accuracy)); } if (instrument.BaseAsset == fromAsset.Symbol && volumeAsset.Symbol == toAsset.Symbol) { return((double)CalculateAveragePriceNotStraight(orderBook.BuyLevels.OrderByDescending(e => e.Price), (decimal)volume, instrument.Accuracy)); } if (instrument.BaseAsset == toAsset.Symbol && volumeAsset.Symbol == toAsset.Symbol) { return((double)CalculateAveragePriceStraight(orderBook.SellLevels.OrderBy(e => e.Price), (decimal)volume, instrument.Accuracy)); } if (instrument.BaseAsset == toAsset.Symbol && volumeAsset.Symbol == fromAsset.Symbol) { return((double)CalculateAveragePriceNotStraight(orderBook.SellLevels.OrderBy(e => e.Price), (decimal)volume, instrument.Accuracy)); } throw new Exception("CalculateAveragePrice cant calculate price and volume"); }
private ProcessQuoteResult ProcessOneInstrument(GetQuoteRequest requestQuote, ISpotInstrument instrument, double markUp) { _logger.LogInformation("Receive ProcessOneInstrument requestQuote: {JsonTextRequestQuote}; instrument: {JsonTextInstrument}; markUp : {JsonTextMarkUp}", JsonConvert.SerializeObject(requestQuote), JsonConvert.SerializeObject(instrument), JsonConvert.SerializeObject(markUp)); var fromAsset = _assetsClient.GetAssetById(new AssetIdentity() { BrokerId = requestQuote.BrokerId, Symbol = requestQuote.FromAsset }); if (fromAsset == null) { return(new ProcessQuoteResult("Unknown asset")); } var toAsset = _assetsClient.GetAssetById(new AssetIdentity() { BrokerId = requestQuote.BrokerId, Symbol = instrument.BaseAsset == fromAsset.Symbol ? instrument.QuoteAsset : instrument.BaseAsset }); if (toAsset == null) { return(new ProcessQuoteResult("Unknown opposite asset")); } double volume; IAsset fixedAsset; if (requestQuote.IsFromFixed) { volume = requestQuote.FromAssetVolume; fixedAsset = fromAsset; } else { volume = requestQuote.ToAssetVolume; fixedAsset = toAsset; } var fees = _spotInstrumentFeesClient.GetSpotInstrumentFees(requestQuote.BrokerId, instrument.Symbol); var fee = fees?.TakerFeeSize ?? 0; var orderBook = _orderBookService.GetOrderBook(requestQuote.BrokerId, instrument.Symbol); if (orderBook == null) { return(new ProcessQuoteResult("No liquidity")); } var price = AveragePriceCalculator.CalculateAveragePrice(orderBook, instrument, fromAsset, toAsset, fixedAsset, volume); if (price <= 0) { return(new ProcessQuoteResult("No liquidity")); } price = (1 + markUp + fee) * price; price = Math.Round(price, Mathematics.AccuracyToNormalizeDouble); price = Math.Round(price, instrument.Accuracy, MidpointRounding.ToZero); var toAssetVolume = 0.0; var fromAssetVolume = 0.0; var oppositeVolume = 0.0; var oppositeAssetSymbol = string.Empty; if (requestQuote.IsFromFixed) { fromAssetVolume = volume; if (instrument.BaseAsset == fromAsset.Symbol) { toAssetVolume = oppositeVolume = volume * price; oppositeAssetSymbol = toAsset.Symbol; } else { toAssetVolume = oppositeVolume = volume / price; oppositeAssetSymbol = toAsset.Symbol; } } else { toAssetVolume = volume; if (instrument.BaseAsset == toAsset.Symbol) { fromAssetVolume = oppositeVolume = volume * price; oppositeAssetSymbol = fromAsset.Symbol; } else { fromAssetVolume = oppositeVolume = volume / price; oppositeAssetSymbol = fromAsset.Symbol; } } fromAssetVolume = Math.Round(fromAssetVolume, Mathematics.AccuracyToNormalizeDouble); fromAssetVolume = Math.Round(fromAssetVolume, fromAsset.Accuracy, MidpointRounding.ToPositiveInfinity); toAssetVolume = Math.Round(toAssetVolume, Mathematics.AccuracyToNormalizeDouble); toAssetVolume = Math.Round(toAssetVolume, toAsset.Accuracy, MidpointRounding.ToZero); return(new ProcessQuoteResult( fromAssetVolume, toAssetVolume, price, oppositeVolume, oppositeAssetSymbol, new List <InstrumentInTrade>() { new InstrumentInTrade() { Symbol = instrument.Symbol, Price = price } })); }