Пример #1
0
        public void CalculatePrice_CheckCorrectCalculation()
        {
            var assetPairRate = new AssetPairModel
            {
                AssetPair = "BTCCHF",
                BidPrice  = 6838.57154,
                AskPrice  = 6838.57154
            };

            IMarkup merchantMarkup = new Markup
            {
                Percent     = 0,
                Pips        = 0,
                DeltaSpread = 1.4m,
                FixedFee    = 0
            };

            IRequestMarkup requestMarkup = new RequestMarkup
            {
                Pips     = 9,
                Percent  = 9,
                FixedFee = 13
            };

            var assetPair = new AssetPair
            {
                Id               = "BTCCHF",
                Name             = "BTC/CHF",
                Accuracy         = 3,
                BaseAssetId      = "BTC",
                QuotingAssetId   = "CHF",
                InvertedAccuracy = 8,
                IsDisabled       = false,
                Source           = "BTCUSD",
                Source2          = "USDCHF"
            };

            decimal chfAmount = 10;

            _logMock.Setup(o => o.WriteInfoAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <DateTime>())).Verifiable();

            var rate = _service.CalculatePrice(assetPairRate.AskPrice, assetPairRate.BidPrice, assetPair.Accuracy,
                                               BtcAccuracy, requestMarkup.Percent, requestMarkup.Pips, PriceCalculationMethod.ByBid, merchantMarkup);

            var btcAmount = (chfAmount + (decimal)requestMarkup.FixedFee + merchantMarkup.FixedFee) / rate;

            Assert.IsTrue(Math.Abs(btcAmount - (decimal)0.00374839) < BtcAccuracy.GetMinValue());
        }
Пример #2
0
        public async Task <IOrder> GetLatestOrCreateAsync(IPaymentRequest paymentRequest, bool force = false)
        {
            IReadOnlyList <IOrder> orders = await _orderRepository.GetAsync(paymentRequest.Id);

            IOrder latestOrder = orders.OrderByDescending(x => x.ExtendedDueDate).FirstOrDefault();

            var now = DateTime.UtcNow;

            if (latestOrder != null)
            {
                if (now < latestOrder.DueDate)
                {
                    return(latestOrder);
                }

                if (now < latestOrder.ExtendedDueDate && !force)
                {
                    return(latestOrder);
                }
            }

            RequestMarkup requestMarkup = Mapper.Map <RequestMarkup>(paymentRequest);

            var paymentInfo = await GetPaymentInfoAsync(paymentRequest.SettlementAssetId, paymentRequest.PaymentAssetId, paymentRequest.Amount, paymentRequest.MerchantId, requestMarkup);

            var order = new Order
            {
                MerchantId       = paymentRequest.MerchantId,
                PaymentRequestId = paymentRequest.Id,
                AssetPairId      = paymentInfo.AssetPairId,
                SettlementAmount = paymentRequest.Amount,
                PaymentAmount    = paymentInfo.PaymentAmount,
                DueDate          = now.Add(_orderExpirationPeriods.Primary),
                ExtendedDueDate  = now.Add(_orderExpirationPeriods.Extended),
                CreatedDate      = now,
                ExchangeRate     = paymentInfo.Rate
            };

            IOrder createdOrder = await _orderRepository.InsertAsync(order);

            _log.Info("Order created", order.ToJson());

            return(createdOrder);
        }
Пример #3
0
        private async Task <(string AssetPairId, decimal PaymentAmount, decimal Rate)> GetPaymentInfoAsync(string settlementAssetId, string paymentAssetId, decimal amount, string merchantId, RequestMarkup requestMarkup)
        {
            string lykkePaymentAssetId = await _lykkeAssetsResolver.GetLykkeId(paymentAssetId);

            string lykkeSettlementAssetId = await _lykkeAssetsResolver.GetLykkeId(settlementAssetId);

            string assetPairId = $"{paymentAssetId}{settlementAssetId}";

            IMarkup merchantMarkup;

            try
            {
                merchantMarkup = await _markupService.ResolveAsync(merchantId, assetPairId);
            }
            catch (MarkupNotFoundException e)
            {
                _log.ErrorWithDetails(e, new
                {
                    e.MerchantId,
                    e.AssetPairId
                });

                throw;
            }

            decimal paymentAmount, rate;

            try
            {
                paymentAmount = await _calculationService.GetAmountAsync(lykkePaymentAssetId,
                                                                         lykkeSettlementAssetId, amount, requestMarkup, merchantMarkup);

                rate = await _calculationService.GetRateAsync(lykkePaymentAssetId, lykkeSettlementAssetId,
                                                              requestMarkup.Percent, requestMarkup.Pips, merchantMarkup);
            }
            catch (MarketPriceZeroException e)
            {
                _log.ErrorWithDetails(e, new { e.PriceType });

                throw;
            }
            catch (UnexpectedAssetPairPriceMethodException e)
            {
                _log.ErrorWithDetails(e, new { e.PriceMethod });

                throw;
            }
            catch (ZeroRateException e)
            {
                _log.ErrorWithDetails(e, new
                {
                    lykkePaymentAssetId,
                    lykkeSettlementAssetId,
                    requestMarkup.Percent,
                    requestMarkup.Pips,
                    merchantMarkup
                });

                throw;
            }

            return(assetPairId, paymentAmount, rate);
        }
Пример #4
0
        public async Task <IOrder> GetLatestOrCreateAsync(IPaymentRequest paymentRequest, bool force = false)
        {
            IReadOnlyList <IOrder> orders = await _orderRepository.GetAsync(paymentRequest.Id);

            IOrder latestOrder = orders.OrderByDescending(x => x.ExtendedDueDate).FirstOrDefault();

            var now = DateTime.UtcNow;

            if (latestOrder != null)
            {
                if (now < latestOrder.DueDate)
                {
                    return(latestOrder);
                }

                if (now < latestOrder.ExtendedDueDate && !force)
                {
                    return(latestOrder);
                }
            }

            IMerchant merchant = await _merchantRepository.GetAsync(paymentRequest.MerchantId);

            if (merchant == null)
            {
                throw new MerchantNotFoundException(paymentRequest.MerchantId);
            }

            string lykkePaymentAssetId = await _lykkeAssetsResolver.GetLykkeId(paymentRequest.PaymentAssetId);

            string lykkeSettlementAssetId = await _lykkeAssetsResolver.GetLykkeId(paymentRequest.SettlementAssetId);

            string assetPairId = $"{paymentRequest.PaymentAssetId}{paymentRequest.SettlementAssetId}";

            RequestMarkup requestMarkup = Mapper.Map <RequestMarkup>(paymentRequest);

            IMarkup merchantMarkup;

            try
            {
                merchantMarkup = await _markupService.ResolveAsync(merchant.Id, assetPairId);
            }
            catch (MarkupNotFoundException ex)
            {
                await _log.WriteErrorAsync(nameof(OrderService), nameof(GetLatestOrCreateAsync), new
                {
                    ex.MerchantId,
                    ex.AssetPairId
                }.ToJson(), ex);

                throw;
            }

            decimal paymentAmount, rate;

            try
            {
                paymentAmount = await _calculationService.GetAmountAsync(lykkePaymentAssetId,
                                                                         lykkeSettlementAssetId, paymentRequest.Amount, requestMarkup, merchantMarkup);

                rate = await _calculationService.GetRateAsync(lykkePaymentAssetId, lykkeSettlementAssetId,
                                                              requestMarkup.Percent, requestMarkup.Pips, merchantMarkup);
            }
            catch (MarketPriceZeroException priceZeroEx)
            {
                _log.WriteError(nameof(GetLatestOrCreateAsync), new { priceZeroEx.PriceType }, priceZeroEx);

                throw;
            }
            catch (UnexpectedAssetPairPriceMethodException assetPairEx)
            {
                _log.WriteError(nameof(GetLatestOrCreateAsync), new { assetPairEx.PriceMethod }, assetPairEx);

                throw;
            }

            var order = new Order
            {
                MerchantId       = paymentRequest.MerchantId,
                PaymentRequestId = paymentRequest.Id,
                AssetPairId      = assetPairId,
                SettlementAmount = paymentRequest.Amount,
                PaymentAmount    = paymentAmount,
                DueDate          = now.Add(_orderExpirationPeriods.Primary),
                ExtendedDueDate  = now.Add(_orderExpirationPeriods.Extended),
                CreatedDate      = now,
                ExchangeRate     = rate
            };

            IOrder createdOrder = await _orderRepository.InsertAsync(order);

            await _log.WriteInfoAsync(nameof(OrderService), nameof(GetLatestOrCreateAsync), order.ToJson(),
                                      "Order created.");

            return(createdOrder);
        }