diff --git a/GDAXClient.Specs/Services/Products/ProductsServiceSpecs.cs b/GDAXClient.Specs/Services/Products/ProductsServiceSpecs.cs index cdaa7dc7..0d845a96 100644 --- a/GDAXClient.Specs/Services/Products/ProductsServiceSpecs.cs +++ b/GDAXClient.Specs/Services/Products/ProductsServiceSpecs.cs @@ -166,7 +166,7 @@ class when_getting_product_history }; Because of = () => - product_history_response = Subject.GetProductHistoryAsync(ProductType.BtcUsd, DateTime.Now.AddDays(-1), DateTime.Now, 57600).Result; + product_history_response = Subject.GetHistoricRatesAsync(ProductType.BtcUsd, DateTime.Now.AddDays(-1), DateTime.Now, 57600).Result; It should_have_correct_product_stats = () => { diff --git a/GDAXClient/GDAXClient.cs b/GDAXClient/GDAXClient.cs index 61bd9bf9..ad3e871f 100644 --- a/GDAXClient/GDAXClient.cs +++ b/GDAXClient/GDAXClient.cs @@ -28,11 +28,11 @@ public GDAXClient(Authenticator authenticator, bool sandBox = false) AccountsService = new AccountsService(httpClient, httpRequestMessageService, authenticator); CoinbaseAccountsService = new CoinbaseAccountsService(httpClient, httpRequestMessageService, authenticator); - OrdersService = new OrdersService(httpClient, httpRequestMessageService, authenticator); + OrdersService = new OrdersService(httpClient, httpRequestMessageService, authenticator, queryBuilder); PaymentsService = new PaymentsService(httpClient, httpRequestMessageService, authenticator); WithdrawalsService = new WithdrawalsService(httpClient, httpRequestMessageService, authenticator); DepositsService = new DepositsService(httpClient, httpRequestMessageService, authenticator); - ProductsService = new ProductsService(httpClient, httpRequestMessageService, authenticator); + ProductsService = new ProductsService(httpClient, httpRequestMessageService, authenticator, queryBuilder); CurrenciesService = new CurrenciesService(httpClient, httpRequestMessageService, authenticator); FillsService = new FillsService(httpClient, httpRequestMessageService, authenticator); FundingsService = new FundingsService(httpClient, httpRequestMessageService, authenticator, queryBuilder); diff --git a/GDAXClient/Services/Orders/OrdersService.cs b/GDAXClient/Services/Orders/OrdersService.cs index 5d69b934..23249f8c 100644 --- a/GDAXClient/Services/Orders/OrdersService.cs +++ b/GDAXClient/Services/Orders/OrdersService.cs @@ -1,13 +1,13 @@ using GDAXClient.HttpClient; using GDAXClient.Services.Accounts; using GDAXClient.Services.HttpRequest; +using GDAXClient.Utilities; using GDAXClient.Utilities.Extensions; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Text; using System.Threading.Tasks; namespace GDAXClient.Services.Orders @@ -20,24 +20,31 @@ public class OrdersService : AbstractService private readonly IAuthenticator authenticator; + private readonly IQueryBuilder queryBuilder; + public OrdersService( IHttpClient httpClient, IHttpRequestMessageService httpRequestMessageService, - IAuthenticator authenticator) + IAuthenticator authenticator, + IQueryBuilder queryBuilder) : base(httpClient, httpRequestMessageService, authenticator) { this.httpRequestMessageService = httpRequestMessageService; this.httpClient = httpClient; this.authenticator = authenticator; + this.queryBuilder = queryBuilder; } - public async Task PlaceMarketOrderAsync(OrderSide side, ProductType productId, decimal size) + public async Task PlaceMarketOrderAsync( + OrderSide side, + ProductType productPair, + decimal size) { var newOrder = JsonConvert.SerializeObject(new Order { side = side.ToString().ToLower(), - product_id = productId.ToDasherizedUpper(), + product_id = productPair.ToDasherizedUpper(), type = OrderType.Market.ToString().ToLower(), size = size }); @@ -49,24 +56,26 @@ public async Task PlaceMarketOrderAsync(OrderSide side, ProductTy return orderResponse; } - public async Task PlaceLimitOrderAsync(OrderSide side, ProductType productId, decimal size, decimal price, TimeInForce timeInForce = TimeInForce.Gtc, bool postOnly = true) + public async Task PlaceLimitOrderAsync( + OrderSide side, + ProductType productPair, + decimal size, + decimal price, + TimeInForce timeInForce = TimeInForce.Gtc, + bool postOnly = true) { var newOrder = JsonConvert.SerializeObject(new Order { side = side.ToString().ToLower(), - product_id = productId.ToDasherizedUpper(), + product_id = productPair.ToDasherizedUpper(), type = OrderType.Limit.ToString().ToLower(), price = price, size = size }); - var queryString = new StringBuilder("?"); - - queryString.Append("time_in_force="); - queryString.Append(timeInForce.ToString().ToUpperInvariant()); - - queryString.Append("&post_only="); - queryString.Append(postOnly.ToString().ToLower()); + var queryString = queryBuilder.BuildQuery( + new KeyValuePair("time_in_force", timeInForce.ToString().ToUpperInvariant()), + new KeyValuePair("post_only", postOnly.ToString().ToLower())); var httpResponseMessage = await SendHttpRequestMessageAsync(HttpMethod.Post, authenticator, "/orders" + queryString, newOrder).ConfigureAwait(false); var contentBody = await httpClient.ReadAsStringAsync(httpResponseMessage).ConfigureAwait(false); @@ -75,24 +84,27 @@ public async Task PlaceLimitOrderAsync(OrderSide side, ProductTyp return orderResponse; } - public async Task PlaceLimitOrderAsync(OrderSide side, ProductType productId, decimal size, decimal price, DateTime cancelAfter, bool postOnly = true) + public async Task PlaceLimitOrderAsync( + OrderSide side, + ProductType productPair, + decimal size, + decimal price, + DateTime cancelAfter, + bool postOnly = true) { var newOrder = JsonConvert.SerializeObject(new Order { side = side.ToString().ToLower(), - product_id = productId.ToDasherizedUpper(), + product_id = productPair.ToDasherizedUpper(), type = OrderType.Limit.ToString().ToLower(), price = price, size = size }); - var queryString = new StringBuilder("?"); - - queryString.Append("time_in_force=GTT"); - queryString.Append("&cancel_after="); - queryString.Append(cancelAfter.Minute + "," + cancelAfter.Hour + "," + cancelAfter.Day); - queryString.Append("&post_only="); - queryString.Append(postOnly.ToString().ToLower()); + var queryString = queryBuilder.BuildQuery( + new KeyValuePair("time_in_force", "GTT"), + new KeyValuePair("cancel_after", cancelAfter.Minute + "," + cancelAfter.Hour + "," + cancelAfter.Day), + new KeyValuePair("post_only", postOnly.ToString().ToLower())); var httpResponseMessage = await SendHttpRequestMessageAsync(HttpMethod.Post, authenticator, "/orders" + queryString, newOrder); var contentBody = await httpClient.ReadAsStringAsync(httpResponseMessage).ConfigureAwait(false); diff --git a/GDAXClient/Services/Products/ProductsService.cs b/GDAXClient/Services/Products/ProductsService.cs index 6393e079..ac9d93f4 100644 --- a/GDAXClient/Services/Products/ProductsService.cs +++ b/GDAXClient/Services/Products/ProductsService.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; +using GDAXClient.Utilities; namespace GDAXClient.Products { @@ -23,15 +24,19 @@ public class ProductsService : AbstractService private readonly IAuthenticator authenticator; + private readonly IQueryBuilder queryBuilder; + public ProductsService( IHttpClient httpClient, IHttpRequestMessageService httpRequestMessageService, - IAuthenticator authenticator) + IAuthenticator authenticator, + IQueryBuilder queryBuilder) : base(httpClient, httpRequestMessageService, authenticator) { this.httpRequestMessageService = httpRequestMessageService; this.httpClient = httpClient; this.authenticator = authenticator; + this.queryBuilder = queryBuilder; } public async Task> GetAllProductsAsync() @@ -70,13 +75,17 @@ public async Task GetProductStatsAsync(ProductType productPair) return productStatsResponse; } - - public async Task> GetProductHistoryAsync(ProductType productPair, DateTime start, DateTime end, int granularity) + public async Task> GetHistoricRatesAsync(ProductType productPair, DateTime start, DateTime end, int granularity) { var isoStart = start.ToString("s"); var isoEnd = end.ToString("s"); - - var httpResponseMessage = await SendHttpRequestMessageAsync(HttpMethod.Get, authenticator, $"/products/{productPair.ToDasherizedUpper()}/candles?start={isoStart}&end={isoEnd}&granularity={granularity}"); + + var queryString = queryBuilder.BuildQuery( + new KeyValuePair("start", isoStart), + new KeyValuePair("end", isoEnd), + new KeyValuePair("granularity", granularity.ToString())); + + var httpResponseMessage = await SendHttpRequestMessageAsync(HttpMethod.Get, authenticator, $"/products/{productPair.ToDasherizedUpper()}/candles" + queryString); var contentBody = await httpClient.ReadAsStringAsync(httpResponseMessage).ConfigureAwait(false); var productHistoryResponse = JsonConvert.DeserializeObject>(contentBody); diff --git a/README.md b/README.md index 397fb6a2..f202c9b3 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,9 @@ var allAccounts = await gdaxClient.AccountsService.GetAllAccountsAsync(); - GetAllAccountsAsync() - get all coinbase accounts ###### Orders ###### -- PlaceMarketOrderAsync(orderSide, productType, size) - place market order -- PlaceLimitOrderAsync(orderSide, productType, size, price) - place limit order +- PlaceMarketOrderAsync(orderSide, productPair, size) - place market order +- PlaceLimitOrderAsync(orderSide, productPair, size, price, timeInForce, postOnly) - place limit order with time in force +- PlaceLimitOrderAsync(orderSide, productPair, size, price, cancelAfter, postOnly) - place limit order with cancel after date - CancelAllOrdersAsync() - cancel all orders - CancelOrderByIdAsync(id) - cancel order by id - GetAllOrdersAsync(limit) - get all open or un-settled orders (paged response) @@ -58,6 +59,7 @@ var allAccounts = await gdaxClient.AccountsService.GetAllAccountsAsync(); - GetProductOrderBookAsync(productType) - get a list of open orders for a product - GetProductTickerAsync(productType) - get information about the last trade (tick), best bid/ask and 24h volume - GetProductStatsAsync(productType) - get 24 hour stats for a product +- GetHistoricRatesAsync(productPair, start, end, granularity) - get historic rates for a product ###### Currencies ###### - GetAllCurrenciesAsync() - gets a list of known currencies @@ -120,6 +122,8 @@ var secondAccountHistoryOnFirstPage = firstPage.ToList()[1]; Thanks for contributing! - @dgelineau +- @quin810 +- @DontFretBrett

Bugs or questions?