private async Task <ExternalTrade> ExecuteLimitOrderAsync(string assetPairId, decimal volume, decimal?price, Side side) { string instrument = await GetInstrumentAsync(assetPairId); var request = new RequestForQuoteRequest(instrument, side, volume); RequestForQuoteResponse response; Trade trade = await WrapAsync(async() => { _log.InfoWithDetails("Get quote request", request); response = await _client.RequestForQuoteAsync(request); _log.InfoWithDetails("Get quote response", response); if (price.HasValue) { if (side == Side.Sell && price.Value > response.Price) { throw new NotEnoughLiquidityException(); } if (side == Side.Buy && price.Value < response.Price) { throw new NotEnoughLiquidityException(); } } var tradeRequest = new TradeRequest(response); _log.InfoWithDetails("Execute trade request", tradeRequest); Trade tradeResponse = await _client.TradeAsync(tradeRequest); _log.InfoWithDetails("Execute trade response", tradeResponse); return(tradeResponse); }); return(new ExternalTrade { Id = trade.TradeId, LimitOrderId = trade.Order, AssetPairId = trade.Instrument, Type = trade.Side == Side.Sell ? TradeType.Sell : TradeType.Buy, Time = trade.Created, Price = trade.Price, Volume = trade.Quantity, RequestId = trade.RfqId }); }
//[Fact] public async void RequestForQuoteTest() { var rfqRequest = new RequestForQuoteRequest("BTCUSD", Side.Buy, 1); var result = await _restClient.RequestForQuoteAsync(rfqRequest); Assert.NotNull(result); Assert.Equal(rfqRequest.Instrument + ".SPOT", result.Instrument); Assert.Equal(rfqRequest.Quantity, result.Quantity); Assert.Equal(rfqRequest.ClientRfqId, result.ClientRfqId); Assert.Equal(rfqRequest.Side, result.Side); Assert.True(result.Price > 0); Assert.NotEmpty(result.Id); Assert.NotEqual(default(DateTime), result.ValidUntil); }
//[Fact] public async void TradeTest() { var rfqRequest = new RequestForQuoteRequest("BTCUSD", Side.Buy, 1); var rfqResponse = await _restClient.RequestForQuoteAsync(rfqRequest); var result = await _restClient.TradeAsync(new TradeRequest(rfqResponse)); Assert.NotNull(result); Assert.NotEmpty(result.TradeId); Assert.Equal(result.RfqId, rfqResponse.Id); Assert.Equal(result.Instrument, rfqResponse.Instrument); Assert.Equal(result.Side, rfqResponse.Side); Assert.Equal(result.Price, rfqResponse.Price); Assert.Equal(result.Quantity, rfqResponse.Quantity); Assert.Null(result.Order); Assert.NotEqual(default(DateTime), result.Created); }
public async Task <RequestForQuoteResponse> RequestForQuoteAsync(RequestForQuoteRequest requestForQuoteRequest, CancellationToken ct = default(CancellationToken)) { if (requestForQuoteRequest == null) { throw new ArgumentNullException(nameof(requestForQuoteRequest)); } var requestId = Guid.NewGuid(); _log.Info("request for quote - request", requestForQuoteRequest); var responseStr = string.Empty; try { using (var response = await _httpClient.PostAsJsonAsync("request_for_quote/", requestForQuoteRequest, ct)) { var status = response.StatusCode; responseStr = await response.Content.ReadAsStringAsync(); _log.Info("request for quote - response", new { RequestId = requestId, Response = responseStr }); CheckForError(responseStr, status, requestId); var result = JsonConvert.DeserializeObject <RequestForQuoteResponse>(responseStr); if (result.ClientRfqId != requestForQuoteRequest.ClientRfqId) { throw new B2c2RestException($"request.client_rfq_id '{requestForQuoteRequest.ClientRfqId}' != " + $"response.client_rfq_id '{result.ClientRfqId}'", requestId); } return(result); } } catch (Exception e) { _log.Error(e, "request for quote - response exception", new { RequestId = requestId, Response = responseStr }); throw; } }