diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..e3f8bb79 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,25 @@ +name: Integration Testing + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + - name: Set GitHub package source + run: dotnet nuget add source --username JKorf --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/JKorf/index.json" + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal -e INTEGRATION=1 \ No newline at end of file diff --git a/Bitfinex.Net.UnitTests/BitfinexRestIntegrationTests.cs b/Bitfinex.Net.UnitTests/BitfinexRestIntegrationTests.cs new file mode 100644 index 00000000..8bc37666 --- /dev/null +++ b/Bitfinex.Net.UnitTests/BitfinexRestIntegrationTests.cs @@ -0,0 +1,125 @@ +using Bitfinex.Net; +using Bitfinex.Net.Clients; +using CryptoExchange.Net.Testing; +using Microsoft.Extensions.Logging; +using NUnit.Framework; +using System; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace Bitfinex.Net.UnitTests +{ + [NonParallelizable] + internal class BitfinexRestIntegrationTests : RestIntergrationTest + { + public override bool Run { get; set; } + + public BitfinexRestIntegrationTests() + { + } + + public override BitfinexRestClient GetClient(ILoggerFactory loggerFactory) + { + var key = Environment.GetEnvironmentVariable("APIKEY"); + var sec = Environment.GetEnvironmentVariable("APISECRET"); + + Authenticated = key != null && sec != null; + return new BitfinexRestClient(null, loggerFactory, opts => + { + opts.OutputOriginalData = true; + opts.ApiCredentials = Authenticated ? new CryptoExchange.Net.Authentication.ApiCredentials(key, sec) : null; + }); + } + + [Test] + public async Task TestErrorResponseParsing() + { + if (!ShouldRun()) + return; + + var result = await CreateClient().SpotApi.ExchangeData.GetOrderBookAsync("TST-TST", default); + + Assert.That(result.Success, Is.False); + Assert.That(result.Error.Code, Is.EqualTo(10020)); + } + + [Test] + public async Task TestSpotAccount() + { + await RunAndCheckResult(client => client.SpotApi.Account.GetBalancesAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetBaseMarginInfoAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetSymbolMarginInfoAsync("tETHUSD", default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetMovementsAsync(default, default, default, default, default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetAlertListAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetAvailableBalanceAsync("tETHUSD", Enums.OrderSide.Buy, 1000, Enums.WalletType.Exchange, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetLedgerEntriesAsync(default, default, default, default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetUserInfoAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Account.Get30DaySummaryAndFeesAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetLoginHistoryAsync(default, default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetApiKeyPermissionsAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Account.GetAccountChangeLogAsync(default), true); + } + + [Test] + public async Task TestSpotExchangeData() + { + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetPlatformStatusAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetsListAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetSymbolNamesAsync(Enums.SymbolType.Exchange, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetNamesAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetSymbolsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetFullNamesAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetUnitsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetUnderlyingsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetNetworksAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetBlockExplorerUrlsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetWithdrawalFeesAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAssetDepositWithdrawalMethodsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetSymbolsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetFuturesSymbolsAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetDepositWithdrawalStatusAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetMarginInfoAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetDerivativesFeesAsync(default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetTickerAsync("tETHUST", default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetFundingTickerAsync("fUSD", default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetTickersAsync(default, default), false); + //await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetFundingTickersAsync(default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetTickerHistoryAsync(default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetTradeHistoryAsync("tETHUST", default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetOrderBookAsync("tETHUST", Enums.Precision.PrecisionLevel2, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetFundingOrderBookAsync("fUSD", Enums.Precision.PrecisionLevel2, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetRawOrderBookAsync("fUSD", default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetRawFundingOrderBookAsync("fUSD", default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLastKlineAsync("tETHUST", Enums.KlineInterval.OneDay, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetKlinesAsync("tETHUST", Enums.KlineInterval.OneDay, default, default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetAveragePriceAsync("tETHUST", 1, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetForeignExchangeRateAsync("BTC", "USD", default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetDerivativesStatusAsync(default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetDerivativesStatusHistoryAsync("tBTCF0:USTF0", default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLiquidationsAsync(default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetFundingStatisticsAsync("fUSD", default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLastFundingSizeAsync("fUSD", default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetFundingSizeHistoryAsync("fUSD", default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLastCreditSizeAsync("fUSD", default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetCreditSizeHistoryAsync("fUSD", default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLastLongsShortsTotalsAsync("tETHUSD", Enums.StatSide.Long, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLongsShortsTotalsHistoryAsync("tETHUSD", Enums.StatSide.Long, default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLastTradingVolumeAsync(1, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetTradingVolumeHistoryAsync(1, default, default, default, default, default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetLastVolumeWeightedAveragePriceAsync("tETHUSD", default), false); + await RunAndCheckResult(client => client.SpotApi.ExchangeData.GetVolumeWeightedAveragePriceHistoryAsync("tETHUSD", default, default, default, default, default), false); + + } + + [Test] + public async Task TestSpotTrading() + { + await RunAndCheckResult(client => client.SpotApi.Trading.GetOpenOrdersAsync(default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Trading.GetClosedOrdersAsync(default, default, default, default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Trading.GetUserTradesAsync(default, default, default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Trading.GetPositionHistoryAsync(default, default, default, default), true); + await RunAndCheckResult(client => client.SpotApi.Trading.GetPositionsAsync(default), true); + await RunAndCheckResult(client => client.SpotApi.Trading.GetPositionSnapshotsAsync(default, default, default, default), true); + } + } +} diff --git a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize.txt b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize.txt index d5688c81..eee32d18 100644 --- a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize.txt +++ b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize.txt @@ -1,5 +1,5 @@ GET -/v2/stats1/credits.size:1m:UST/last +/v2/stats1/credits.size:1m:UST/hist false [ [ diff --git a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize2.txt b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize2.txt index e719e5e4..70ce2b0e 100644 --- a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize2.txt +++ b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetCreditSize2.txt @@ -1,5 +1,5 @@ GET -/v2/stats1/credits.size.sym:1m:UST:tETHUST/last +/v2/stats1/credits.size.sym:1m:UST:tETHUST/hist false [ [ diff --git a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetFundingSize.txt b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetFundingSize.txt index b1b04d14..cbfafcb7 100644 --- a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetFundingSize.txt +++ b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetFundingSize.txt @@ -1,5 +1,5 @@ GET -/v2/stats1/funding.size:1m:UST/last +/v2/stats1/funding.size:1m:UST/hist false [ [ diff --git a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetVolumeWeightedAveragePrice.txt b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetVolumeWeightedAveragePrice.txt index b79548fd..cd77115f 100644 --- a/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetVolumeWeightedAveragePrice.txt +++ b/Bitfinex.Net.UnitTests/Endpoints/Spot/ExchangeData/GetVolumeWeightedAveragePrice.txt @@ -1,5 +1,5 @@ GET -/v2/stats1/vwap:1d:tETHUST/last +/v2/stats1/vwap:1d:tETHUST/hist false [ [ diff --git a/Bitfinex.Net.UnitTests/RestRequestTests.cs b/Bitfinex.Net.UnitTests/RestRequestTests.cs index daaed6e5..2a24588b 100644 --- a/Bitfinex.Net.UnitTests/RestRequestTests.cs +++ b/Bitfinex.Net.UnitTests/RestRequestTests.cs @@ -87,12 +87,12 @@ public async Task ValidateSpotExchangeDataCalls() await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetDerivativesStatusHistoryAsync("tETHUST"), "GetDerivativesStatusHistory"); await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetLiquidationsAsync(), "GetLiquidations", useSingleArrayItem: true); await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetFundingStatisticsAsync("tETHUST"), "GetFundingStatistics"); - await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetFundingSizeAsync("UST", Enums.StatSection.Last), "GetFundingSize"); - await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetCreditSizeAsync("UST", Enums.StatSection.Last), "GetCreditSize"); - await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetCreditSizeAsync("UST", "tETHUST", Enums.StatSection.Last), "GetCreditSize2"); - await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetLongsShortsTotalsAsync("tETHUST", Enums.StatSide.Long, Enums.StatSection.History), "GetLongsShortsTotals"); - await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetTradingVolumeAsync(1, Enums.StatSection.History), "GetTradingVolume"); - await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetVolumeWeightedAveragePriceAsync("tETHUST", Enums.StatSection.Last), "GetVolumeWeightedAveragePrice"); + await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetFundingSizeHistoryAsync("UST"), "GetFundingSize"); + await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetCreditSizeHistoryAsync("UST"), "GetCreditSize"); + await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetCreditSizeHistoryAsync("UST", "tETHUST"), "GetCreditSize2"); + await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetLongsShortsTotalsHistoryAsync("tETHUST", Enums.StatSide.Long), "GetLongsShortsTotals"); + await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetTradingVolumeHistoryAsync(1), "GetTradingVolume"); + await tester.ValidateAsync(client => client.SpotApi.ExchangeData.GetVolumeWeightedAveragePriceHistoryAsync("tETHUST"), "GetVolumeWeightedAveragePrice"); } [Test] diff --git a/Bitfinex.Net/Bitfinex.Net.csproj b/Bitfinex.Net/Bitfinex.Net.csproj index c2315324..e8ac2fe6 100644 --- a/Bitfinex.Net/Bitfinex.Net.csproj +++ b/Bitfinex.Net/Bitfinex.Net.csproj @@ -51,10 +51,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive + \ No newline at end of file diff --git a/Bitfinex.Net/Bitfinex.Net.xml b/Bitfinex.Net/Bitfinex.Net.xml index b6f5888c..90d0e634 100644 --- a/Bitfinex.Net/Bitfinex.Net.xml +++ b/Bitfinex.Net/Bitfinex.Net.xml @@ -410,22 +410,40 @@ - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + @@ -2037,13 +2055,21 @@ - + + + Get total active funding in specified asset + + + The asset + Cancellation token + + + Get total active funding in specified asset The asset - Section of data Max number of results Filter by start time Filter by end time @@ -2051,13 +2077,21 @@ Cancellation token - + + + Get total funding used in positions in specified asset + + + The asset + Cancellation token + + + Get total funding used in positions in specified asset The asset - Section of data Max number of results Filter by start time Filter by end time @@ -2065,14 +2099,23 @@ Cancellation token - + + + Get total funding used in positions on a specific symbol in specified asset + + + The asset + The symbol + Cancellation token + + + Get total funding used in positions on a specific symbol in specified asset The asset The symbol - Section of data Max number of results Filter by start time Filter by end time @@ -2080,14 +2123,23 @@ Cancellation token - + + + Get total longs/shorts in base currency (i.e. BTC for tBTCUSD) + + + The symbol + Position side + Cancellation token + + + Get total longs/shorts in base currency (i.e. BTC for tBTCUSD) The symbol Position side - Section of data Max number of results Filter by start time Filter by end time @@ -2095,13 +2147,21 @@ Cancellation token - + + + Get trading volume on the platform + + + The period in days to get the data for. 1, 7 or 30 + Cancellation token + + + Get trading volume on the platform The period in days to get the data for. 1, 7 or 30 - Section of data Max number of results Filter by start time Filter by end time @@ -2109,13 +2169,21 @@ Cancellation token - + + + Get volume weighted average price for the day + + + The symbol + Cancellation token + + + Get volume weighted average price for the day The symbol - Section of data Max number of results Filter by start time Filter by end time diff --git a/Bitfinex.Net/Clients/SpotApi/BitfinexRestClientSpotApiExchangeData.cs b/Bitfinex.Net/Clients/SpotApi/BitfinexRestClientSpotApiExchangeData.cs index cd8eb4a3..216491b5 100644 --- a/Bitfinex.Net/Clients/SpotApi/BitfinexRestClientSpotApiExchangeData.cs +++ b/Bitfinex.Net/Clients/SpotApi/BitfinexRestClientSpotApiExchangeData.cs @@ -570,67 +570,137 @@ public async Task>> GetFundingSt } #endregion - #region Get Funding Size + #region Get Funding Size History /// - public async Task>> GetFundingSizeAsync(string symbol, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + public async Task>> GetFundingSizeHistoryAsync(string symbol, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) { var parameters = new Dictionary(); + parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); + parameters.AddOptionalParameter("start", DateTimeConverter.ConvertToMilliseconds(startTime)); + parameters.AddOptionalParameter("end", DateTimeConverter.ConvertToMilliseconds(endTime)); parameters.AddOptionalParameter("sort", sorting != null ? JsonConvert.SerializeObject(sorting, new SortingConverter(false)) : null); - var endpoint = _baseClient.GetUrl($"stats1/funding.size:1m:{symbol}/{EnumConverter.GetString(section)}", "2"); + var endpoint = _baseClient.GetUrl($"stats1/funding.size:1m:{symbol}/{EnumConverter.GetString(StatSection.History)}", "2"); return await _baseClient.SendRequestAsync>(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); } #endregion - #region Get Credit Size + #region Get Last Funding Size /// - public async Task>> GetCreditSizeAsync(string symbol, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + public async Task> GetLastFundingSizeAsync(string symbol, CancellationToken ct = default) { var parameters = new Dictionary(); + var endpoint = _baseClient.GetUrl($"stats1/funding.size:1m:{symbol}/{EnumConverter.GetString(StatSection.Last)}", "2"); + return await _baseClient.SendRequestAsync(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); + } + #endregion + + #region Get Last Credit Size + /// + public async Task> GetLastCreditSizeAsync(string symbol, CancellationToken ct = default) + { + var parameters = new Dictionary(); + var endpoint = _baseClient.GetUrl($"stats1/credits.size:1m:{symbol}/{EnumConverter.GetString(StatSection.Last)}", "2"); + return await _baseClient.SendRequestAsync(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); + } + #endregion + + #region Get Credit Size History + /// + public async Task>> GetCreditSizeHistoryAsync(string symbol, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + { + var parameters = new Dictionary(); + parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); + parameters.AddOptionalParameter("start", DateTimeConverter.ConvertToMilliseconds(startTime)); + parameters.AddOptionalParameter("end", DateTimeConverter.ConvertToMilliseconds(endTime)); parameters.AddOptionalParameter("sort", sorting != null ? JsonConvert.SerializeObject(sorting, new SortingConverter(false)) : null); - var endpoint = _baseClient.GetUrl($"stats1/credits.size:1m:{symbol}/{EnumConverter.GetString(section)}", "2"); + var endpoint = _baseClient.GetUrl($"stats1/credits.size:1m:{symbol}/{EnumConverter.GetString(StatSection.History)}", "2"); return await _baseClient.SendRequestAsync>(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); } #endregion /// - public async Task>> GetCreditSizeAsync(string asset, string symbol, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + public async Task> GetLastCreditSizeAsync(string asset, string symbol, CancellationToken ct = default) + { + var parameters = new Dictionary(); + var endpoint = _baseClient.GetUrl($"stats1/credits.size.sym:1m:{asset}:{symbol}/{EnumConverter.GetString(StatSection.Last)}", "2"); + return await _baseClient.SendRequestAsync(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); + } + + /// + public async Task>> GetCreditSizeHistoryAsync(string asset, string symbol, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) { var parameters = new Dictionary(); + parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); + parameters.AddOptionalParameter("start", DateTimeConverter.ConvertToMilliseconds(startTime)); + parameters.AddOptionalParameter("end", DateTimeConverter.ConvertToMilliseconds(endTime)); parameters.AddOptionalParameter("sort", sorting != null ? JsonConvert.SerializeObject(sorting, new SortingConverter(false)) : null); - var endpoint = _baseClient.GetUrl($"stats1/credits.size.sym:1m:{asset}:{symbol}/{EnumConverter.GetString(section)}", "2"); + var endpoint = _baseClient.GetUrl($"stats1/credits.size.sym:1m:{asset}:{symbol}/{EnumConverter.GetString(StatSection.History)}", "2"); return await _baseClient.SendRequestAsync>(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); } /// - public async Task>> GetLongsShortsTotalsAsync(string symbol, StatSide side, StatSection section,int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + public async Task> GetLastLongsShortsTotalsAsync(string symbol, StatSide side, CancellationToken ct = default) { var parameters = new Dictionary(); + var endpoint = _baseClient.GetUrl($"stats1/pos.size:1m:{symbol}:{EnumConverter.GetString(side)}/{EnumConverter.GetString(StatSection.Last)}", "2"); + return await _baseClient.SendRequestAsync(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); + } + + /// + public async Task>> GetLongsShortsTotalsHistoryAsync(string symbol, StatSide side, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + { + var parameters = new Dictionary(); + parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); + parameters.AddOptionalParameter("start", DateTimeConverter.ConvertToMilliseconds(startTime)); + parameters.AddOptionalParameter("end", DateTimeConverter.ConvertToMilliseconds(endTime)); parameters.AddOptionalParameter("sort", sorting != null ? JsonConvert.SerializeObject(sorting, new SortingConverter(false)) : null); - var endpoint = _baseClient.GetUrl($"stats1/pos.size:1m:{symbol}:{EnumConverter.GetString(side)}/{EnumConverter.GetString(section)}", "2"); + var endpoint = _baseClient.GetUrl($"stats1/pos.size:1m:{symbol}:{EnumConverter.GetString(side)}/{EnumConverter.GetString(StatSection.History)}", "2"); return await _baseClient.SendRequestAsync>(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); } /// - public async Task>> GetTradingVolumeAsync(int period, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + public async Task> GetLastTradingVolumeAsync(int period, CancellationToken ct = default) { var parameters = new Dictionary(); + var endpoint = _baseClient.GetUrl($"stats1/vol.{period}d:30m:BFX/{EnumConverter.GetString(StatSection.Last)}", "2"); + return await _baseClient.SendRequestAsync(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); + } + + /// + public async Task>> GetTradingVolumeHistoryAsync(int period, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + { + var parameters = new Dictionary(); + parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); + parameters.AddOptionalParameter("start", DateTimeConverter.ConvertToMilliseconds(startTime)); + parameters.AddOptionalParameter("end", DateTimeConverter.ConvertToMilliseconds(endTime)); parameters.AddOptionalParameter("sort", sorting != null ? JsonConvert.SerializeObject(sorting, new SortingConverter(false)) : null); - var endpoint = _baseClient.GetUrl($"stats1/vol.{period}d:30m:BFX/{EnumConverter.GetString(section)}", "2"); + var endpoint = _baseClient.GetUrl($"stats1/vol.{period}d:30m:BFX/{EnumConverter.GetString(StatSection.History)}", "2"); return await _baseClient.SendRequestAsync>(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); } /// - public async Task>> GetVolumeWeightedAveragePriceAsync(string symbol, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) + public async Task> GetLastVolumeWeightedAveragePriceAsync(string symbol, CancellationToken ct = default) + { + var parameters = new Dictionary(); + var endpoint = _baseClient.GetUrl($"stats1/vwap:1d:{symbol}/{EnumConverter.GetString(StatSection.Last)}", "2"); + return await _baseClient.SendRequestAsync(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); + } + + /// + public async Task>> GetVolumeWeightedAveragePriceHistoryAsync(string symbol, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default) { var parameters = new Dictionary(); + parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); + parameters.AddOptionalParameter("start", DateTimeConverter.ConvertToMilliseconds(startTime)); + parameters.AddOptionalParameter("end", DateTimeConverter.ConvertToMilliseconds(endTime)); parameters.AddOptionalParameter("sort", sorting != null ? JsonConvert.SerializeObject(sorting, new SortingConverter(false)) : null); - var endpoint = _baseClient.GetUrl($"stats1/vwap:1d:{symbol}/{EnumConverter.GetString(section)}", "2"); + var endpoint = _baseClient.GetUrl($"stats1/vwap:1d:{symbol}/{EnumConverter.GetString(StatSection.History)}", "2"); return await _baseClient.SendRequestAsync>(endpoint, HttpMethod.Get, ct, parameters).ConfigureAwait(false); } } diff --git a/Bitfinex.Net/Interfaces/Clients/SpotApi/IBitfinexRestClientSpotApiExchangeData.cs b/Bitfinex.Net/Interfaces/Clients/SpotApi/IBitfinexRestClientSpotApiExchangeData.cs index e030e3af..c682a3cb 100644 --- a/Bitfinex.Net/Interfaces/Clients/SpotApi/IBitfinexRestClientSpotApiExchangeData.cs +++ b/Bitfinex.Net/Interfaces/Clients/SpotApi/IBitfinexRestClientSpotApiExchangeData.cs @@ -230,28 +230,54 @@ public interface IBitfinexRestClientSpotApiExchangeData /// /// /// The asset - /// Section of data + /// Cancellation token + /// + Task> GetLastFundingSizeAsync(string asset, CancellationToken ct = default); + + /// + /// Get total active funding in specified asset + /// + /// + /// The asset /// Max number of results /// Filter by start time /// Filter by end time /// Sorting /// Cancellation token /// - Task>> GetFundingSizeAsync(string asset, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + Task>> GetFundingSizeHistoryAsync(string asset, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + + /// + /// Get total funding used in positions in specified asset + /// + /// + /// The asset + /// Cancellation token + /// + Task> GetLastCreditSizeAsync(string asset, CancellationToken ct = default); /// /// Get total funding used in positions in specified asset /// /// /// The asset - /// Section of data /// Max number of results /// Filter by start time /// Filter by end time /// Sorting /// Cancellation token /// - Task>> GetCreditSizeAsync(string asset, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + Task>> GetCreditSizeHistoryAsync(string asset, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + + /// + /// Get total funding used in positions on a specific symbol in specified asset + /// + /// + /// The asset + /// The symbol + /// Cancellation token + /// + Task> GetLastCreditSizeAsync(string asset, string symbol, CancellationToken ct = default); /// /// Get total funding used in positions on a specific symbol in specified asset @@ -259,14 +285,23 @@ public interface IBitfinexRestClientSpotApiExchangeData /// /// The asset /// The symbol - /// Section of data /// Max number of results /// Filter by start time /// Filter by end time /// Sorting /// Cancellation token /// - Task>> GetCreditSizeAsync(string asset, string symbol, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + Task>> GetCreditSizeHistoryAsync(string asset, string symbol, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + + /// + /// Get total longs/shorts in base currency (i.e. BTC for tBTCUSD) + /// + /// + /// The symbol + /// Position side + /// Cancellation token + /// + Task> GetLastLongsShortsTotalsAsync(string symbol, StatSide side, CancellationToken ct = default); /// /// Get total longs/shorts in base currency (i.e. BTC for tBTCUSD) @@ -274,42 +309,57 @@ public interface IBitfinexRestClientSpotApiExchangeData /// /// The symbol /// Position side - /// Section of data /// Max number of results /// Filter by start time /// Filter by end time /// Sorting /// Cancellation token /// - Task>> GetLongsShortsTotalsAsync(string symbol, StatSide side, StatSection section,int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + Task>> GetLongsShortsTotalsHistoryAsync(string symbol, StatSide side, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + + /// + /// Get trading volume on the platform + /// + /// + /// The period in days to get the data for. 1, 7 or 30 + /// Cancellation token + /// + Task> GetLastTradingVolumeAsync(int period, CancellationToken ct = default); /// /// Get trading volume on the platform /// /// /// The period in days to get the data for. 1, 7 or 30 - /// Section of data /// Max number of results /// Filter by start time /// Filter by end time /// Sorting /// Cancellation token /// - Task>> GetTradingVolumeAsync(int period, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + Task>> GetTradingVolumeHistoryAsync(int period, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); /// /// Get volume weighted average price for the day /// /// /// The symbol - /// Section of data + /// Cancellation token + /// + Task> GetLastVolumeWeightedAveragePriceAsync(string symbol, CancellationToken ct = default); + + /// + /// Get volume weighted average price for the day + /// + /// + /// The symbol /// Max number of results /// Filter by start time /// Filter by end time /// Sorting /// Cancellation token /// - Task>> GetVolumeWeightedAveragePriceAsync(string symbol, StatSection section, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); + Task>> GetVolumeWeightedAveragePriceHistoryAsync(string symbol, int? limit = null, DateTime? startTime = null, DateTime? endTime = null, Sorting? sorting = null, CancellationToken ct = default); /// /// Get symbol names