Пример #1
0
        public async Task <IAssetPairRate> GetCurrentRateAsync(string baseAssetId, string quotingAssetId)
        {
            if (await _assetPairSettingsService.GetAsync(baseAssetId, quotingAssetId) != null)
            {
                IReadOnlyList <IAssetPairRate> allRates =
                    await _assetPairRateRepository.GetAsync(baseAssetId, quotingAssetId);

                return(allRates
                       .Where(x => x.CreatedOn <= DateTime.UtcNow)
                       .OrderByDescending(x => x.CreatedOn)
                       .FirstOrDefault());
            }

            AssetPair assetPair = await _assetsLocalCache.GetAssetPairAsync(baseAssetId, quotingAssetId);

            if (assetPair == null)
            {
                throw new AssetPairUnknownException(baseAssetId, quotingAssetId);
            }

            AssetPairModel assetPairRate = await InvokeMarketProfileServiceAsync(assetPair.Id);

            return(Mapper.Map <AssetPairRate>(assetPairRate, opt =>
            {
                opt.Items["BaseAssetId"] = baseAssetId;
                opt.Items["QuotingAssetId"] = quotingAssetId;
            }));
        }
        public async Task <decimal> GetRateAsync(
            string baseAssetId,
            string quotingAssetId,
            decimal markupPercent,
            int markupPips,
            IMarkup merchantMarkup)
        {
            decimal askPrice, bidPrice;

            AssetPair priceAssetPair = null, assetPair = null;

            if (!string.IsNullOrEmpty(merchantMarkup.PriceAssetPairId))
            {
                _log.Info($"Price asset pair will be used: {merchantMarkup.PriceAssetPairId}");

                priceAssetPair = await _assetsLocalCache.GetAssetPairByIdAsync(merchantMarkup.PriceAssetPairId);

                IAssetPairRate assetPairRate =
                    await _assetRatesService.GetCurrentRateAsync(priceAssetPair.BaseAssetId, priceAssetPair.QuotingAssetId);

                _log.Info($"Price method: {merchantMarkup.PriceMethod.ToString()}");

                switch (merchantMarkup.PriceMethod)
                {
                case PriceMethod.None:
                case PriceMethod.Direct:
                    askPrice = assetPairRate.AskPrice;
                    bidPrice = assetPairRate.BidPrice;
                    break;

                case PriceMethod.Reverse:
                    askPrice = Math.Abs(assetPairRate.AskPrice) > 0
                            ? 1 / assetPairRate.AskPrice
                            : throw new MarketPriceZeroException("ask");
                    bidPrice = Math.Abs(assetPairRate.BidPrice) > 0
                            ? 1 / assetPairRate.BidPrice
                            : throw new MarketPriceZeroException("bid");
                    break;

                default:
                    throw new UnexpectedAssetPairPriceMethodException(merchantMarkup.PriceMethod);
                }
            }
            else
            {
                assetPair = await _assetsLocalCache.GetAssetPairAsync(baseAssetId, quotingAssetId);

                try
                {
                    IAssetPairRate assetPairRate = await _assetRatesService.GetCurrentRateAsync(baseAssetId, quotingAssetId);

                    askPrice = assetPairRate.AskPrice;

                    bidPrice = assetPairRate.BidPrice;
                }
                catch (Exception)
                {
                    askPrice = bidPrice = 1;
                }
            }

            _log.Info($"Market rate that will be used for calculation, askPrice = {askPrice}, bidPrice = {bidPrice}");

            Asset baseAsset = await _assetsLocalCache.GetAssetByIdAsync(baseAssetId);

            int pairAccuracy = priceAssetPair?.Accuracy ?? assetPair?.Accuracy ?? baseAsset.Accuracy;

            return(CalculatePrice(askPrice, bidPrice, pairAccuracy, baseAsset.Accuracy, markupPercent,
                                  markupPips, PriceCalculationMethod.ByBid, merchantMarkup));
        }
Пример #3
0
        public async Task <decimal> GetRateAsync(
            string baseAssetId,
            string quotingAssetId,
            double markupPercent,
            int markupPips,
            IMarkup merchantMarkup)
        {
            double askPrice, bidPrice;

            AssetPair priceAssetPair = null, assetPair = null;

            if (!string.IsNullOrEmpty(merchantMarkup.PriceAssetPairId))
            {
                await _log.WriteInfoAsync(nameof(CalculationService), nameof(GetRateAsync),
                                          new { merchantMarkup.PriceAssetPairId }.ToJson(), "Price asset pair will be used");

                priceAssetPair = await _assetsLocalCache.GetAssetPairByIdAsync(merchantMarkup.PriceAssetPairId);

                AssetPairModel assetPairRate = await InvokeMarketProfileServiceAsync(priceAssetPair.Id);

                await _log.WriteInfoAsync(nameof(CalculationService), nameof(GetRateAsync),
                                          new { PriceMethod = merchantMarkup.PriceMethod.ToString() }.ToJson(), "Price method");

                switch (merchantMarkup.PriceMethod)
                {
                case PriceMethod.None:
                case PriceMethod.Direct:
                    askPrice = assetPairRate.AskPrice;
                    bidPrice = assetPairRate.BidPrice;
                    break;

                case PriceMethod.Reverse:
                    askPrice = Math.Abs(assetPairRate.AskPrice) > 0
                            ? 1 / assetPairRate.AskPrice
                            : throw new MarketPriceZeroException("ask");
                    bidPrice = Math.Abs(assetPairRate.BidPrice) > 0
                            ? 1 / assetPairRate.BidPrice
                            : throw new MarketPriceZeroException("bid");
                    break;

                default:
                    throw new UnexpectedAssetPairPriceMethodException(merchantMarkup.PriceMethod);
                }
            }
            else
            {
                assetPair = await _assetsLocalCache.GetAssetPairAsync(baseAssetId, quotingAssetId);

                if (assetPair != null)
                {
                    await _log.WriteInfoAsync(nameof(CalculationService), nameof(GetRateAsync),
                                              new { AssetPairId = assetPair.Id }.ToJson(), "Asset pair will be used");

                    AssetPairModel assetPairRate = await InvokeMarketProfileServiceAsync(assetPair.Id);

                    askPrice = assetPairRate.AskPrice;

                    bidPrice = assetPairRate.BidPrice;
                }
                else
                {
                    askPrice = bidPrice = 1D;
                }
            }

            await _log.WriteInfoAsync(nameof(CalculationService), nameof(GetRateAsync),
                                      new { askPrice, bidPrice }.ToJson(), "Market rate that will be used for calculation");

            Asset baseAsset = await _assetsLocalCache.GetAssetByIdAsync(baseAssetId);

            int pairAccuracy = priceAssetPair?.Accuracy ?? assetPair?.Accuracy ?? baseAsset.Accuracy;

            return(CalculatePrice(askPrice, bidPrice, pairAccuracy, baseAsset.Accuracy, markupPercent, markupPips,
                                  PriceCalculationMethod.ByBid, merchantMarkup));
        }