public async Task <PriceModel> GetPriceAsync([FromQuery] string priceId) { try { var price = await _pricesService.GetAsync(priceId); return(Mapper.Map <PriceModel>(price)); } catch (EntityNotFoundException) { throw new ValidationApiException(HttpStatusCode.NotFound, "Price snapshot does not exist."); } }
public async Task <Order> CreateAsync(string walletId, string priceId, decimal quotingVolume) { var price = await _pricesService.GetAsync(priceId); if (price == null) { throw new EntityNotFoundException(); } var instrument = await _instrumentsAccessService.GetByAssetPairIdAsync(price.AssetPair); if (instrument.State != InstrumentState.Active) { throw new FailedOperationException($"Instrument {instrument.AssetPair} isn't active."); } var defaultSettings = await _settingsService.GetDefaultSettingsAsync(); if (DateTime.UtcNow > price.ValidTo + (instrument.OverlapTime ?? defaultSettings.OverlapTime)) { throw new FailedOperationException("Given price too old."); } if (quotingVolume > price.QuotingVolume) { throw new FailedOperationException("Requested volume higher than initial."); } var pair = await _assetsService.TryGetAssetPairAsync(price.AssetPair); var baseAsset = await _assetsService.TryGetAssetAsync(pair.BaseAssetId); var baseVolume = quotingVolume == price.QuotingVolume ? price.BaseVolume : (quotingVolume / price.Value).TruncateDecimalPlaces(baseAsset.Accuracy, price.Type == OrderType.Sell); var order = new Order { Id = Guid.NewGuid().ToString(), WalletId = walletId, Type = price.Type, AssetPair = price.AssetPair, QuotingVolume = quotingVolume, BaseVolume = baseVolume, PriceId = priceId, CreatedTime = DateTime.UtcNow, Status = OrderStatus.New, ReserveTransferId = Guid.NewGuid().ToString(), SettlementTransferId = Guid.NewGuid().ToString() }; await _ordersRepository.InsertAsync(order); _log.Info("Order was created.", order); try { await _internalTransfersService.TransferAsync( order.ReserveTransferId, walletId, await _settingsService.GetWalletIdAsync(), order.Type == OrderType.Buy ?pair.QuotingAssetId : pair.BaseAssetId, order.Type == OrderType.Buy ?quotingVolume : baseVolume); } catch (MeNotEnoughFundsException) { var rejectReason = "Client doesn't have enough funds."; await PersistWithStatusAsync(order, OrderStatus.Cancelled, rejectReason); throw new FailedOperationException(rejectReason); } catch (MeOperationException e) { var rejectReason = "ME call failed."; await PersistWithStatusAsync(order, OrderStatus.Cancelled, rejectReason); _log.Warning(rejectReason, priceId, e); throw new FailedOperationException(rejectReason); } catch (FailedOperationException e) { var rejectReason = "ME call failed."; await PersistWithStatusAsync(order, OrderStatus.Cancelled, rejectReason); _log.Warning(rejectReason, priceId, e); throw; } await PersistWithStatusAsync(order, OrderStatus.Reserved); return(order); }