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()); }
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); }
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); }
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); }