1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-12 17:03:10 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
JKorf a02b3f88d7 Updated version 2023-04-01 19:00:22 +02:00
JKorf af44ca4c9f Logging 2023-04-01 18:58:52 +02:00
JKorf cf2b57bb96 Revert "Test some changes for robustness"
This reverts commit 1c33e297e7.
2023-04-01 18:55:48 +02:00
JKorf d0a2288910 Updated version 2023-03-18 14:58:09 +01:00
JKorf 89c11afc21 Fix Api key rate limit 2023-03-18 14:22:09 +01:00
JKorf da6ed580f1 Added CalculateTradableAmount to SymbolOrderBook 2023-03-18 10:01:38 +01:00
JKorf 1c33e297e7 Test some changes for robustness 2023-02-18 10:41:26 +01:00
7 changed files with 83 additions and 9 deletions
@@ -108,5 +108,33 @@ namespace CryptoExchange.Net.UnitTests
Assert.AreEqual(1.06666667m, resultBids2.Data);
Assert.AreEqual(1.23333333m, resultAsks2.Data);
}
[TestCase]
public void CalculateTradableAmount()
{
var orderbook = new TestableSymbolOrderBook();
orderbook.SetData(new List<ISymbolOrderBookEntry>
{
new BookEntry{ Price = 1, Quantity = 1 },
new BookEntry{ Price = 1.1m, Quantity = 1 },
},
new List<ISymbolOrderBookEntry>()
{
new BookEntry{ Price = 1.2m, Quantity = 1 },
new BookEntry{ Price = 1.3m, Quantity = 1 },
});
var resultBids = orderbook.CalculateTradableAmount(2, OrderBookEntryType.Bid);
var resultAsks = orderbook.CalculateTradableAmount(2, OrderBookEntryType.Ask);
var resultBids2 = orderbook.CalculateTradableAmount(1.5m, OrderBookEntryType.Bid);
var resultAsks2 = orderbook.CalculateTradableAmount(1.5m, OrderBookEntryType.Ask);
Assert.True(resultBids.Success);
Assert.True(resultAsks.Success);
Assert.AreEqual(1.9m, resultBids.Data);
Assert.AreEqual(1.61538462m, resultAsks.Data);
Assert.AreEqual(1.4m, resultBids2.Data);
Assert.AreEqual(1.23076923m, resultAsks2.Data);
}
}
}
+1 -1
View File
@@ -213,7 +213,7 @@ namespace CryptoExchange.Net
{
foreach (var limiter in RateLimiters)
{
var limitResult = await limiter.LimitRequestAsync(_log, uri.AbsolutePath, method, signed, Options.ApiCredentials?.Key, Options.RateLimitingBehaviour, requestWeight, cancellationToken).ConfigureAwait(false);
var limitResult = await limiter.LimitRequestAsync(_log, uri.AbsolutePath, method, signed, Options.ApiCredentials?.Key ?? ClientOptions.ApiCredentials?.Key, Options.RateLimitingBehaviour, requestWeight, cancellationToken).ConfigureAwait(false);
if (!limitResult.Success)
return new CallResult<IRequest>(limitResult.Error!);
}
+4 -4
View File
@@ -6,16 +6,16 @@
<PackageId>CryptoExchange.Net</PackageId>
<Authors>JKorf</Authors>
<Description>A base package for implementing cryptocurrency API's</Description>
<PackageVersion>5.4.0</PackageVersion>
<AssemblyVersion>5.4.0</AssemblyVersion>
<FileVersion>5.4.0</FileVersion>
<PackageVersion>5.4.2</PackageVersion>
<AssemblyVersion>5.4.2</AssemblyVersion>
<FileVersion>5.4.2</FileVersion>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/JKorf/CryptoExchange.Net.git</RepositoryUrl>
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
<NeutralLanguage>en</NeutralLanguage>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageReleaseNotes>5.4.0 - Added unsubscribing when receiving subscribe answer after the request timeout has passed, Fixed socket options copying, Made TimeSync implementation optional, Cleaned up ApiCredentials and added better support for extending ApiCredentials</PackageReleaseNotes>
<PackageReleaseNotes>5.4.2 - Reverted socket changes as it seems to cause reconnect to hang</PackageReleaseNotes>
<Nullable>enable</Nullable>
<LangVersion>9.0</LangVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
@@ -101,13 +101,22 @@ namespace CryptoExchange.Net.Interfaces
/// <summary>
/// Get the average price that a market order would fill at at the current order book state. This is no guarentee that an order of that quantity would actually be filled
/// at that price since between this calculation and the order placement the book can have changed.
/// at that price since between this calculation and the order placement the book might have changed.
/// </summary>
/// <param name="quantity">The quantity in base asset to fill</param>
/// <param name="type">The type</param>
/// <returns>Average fill price</returns>
CallResult<decimal> CalculateAverageFillPrice(decimal quantity, OrderBookEntryType type);
/// <summary>
/// Get the amount of base asset which can be traded with the quote quantity when placing a market order at at the current order book state.
/// This is no guarentee that an order of that quantity would actually be fill the quantity returned by this since between this calculation and the order placement the book might have changed.
/// </summary>
/// <param name="quoteQuantity">The quantity in quote asset looking to trade</param>
/// <param name="type">The type</param>
/// <returns>Amount of base asset tradable with the specified amount of quote asset</returns>
CallResult<decimal> CalculateTradableAmount(decimal quoteQuantity, OrderBookEntryType type);
/// <summary>
/// String representation of the top x entries
/// </summary>
@@ -304,14 +304,14 @@ namespace CryptoExchange.Net.OrderBook
}
/// <inheritdoc/>
public CallResult<decimal> CalculateAverageFillPrice(decimal quantity, OrderBookEntryType type)
public CallResult<decimal> CalculateAverageFillPrice(decimal baseQuantity, OrderBookEntryType type)
{
if (Status != OrderBookStatus.Synced)
return new CallResult<decimal>(new InvalidOperationError($"{nameof(CalculateAverageFillPrice)} is not available when book is not in Synced state"));
var totalCost = 0m;
var totalAmount = 0m;
var amountLeft = quantity;
var amountLeft = baseQuantity;
lock (_bookLock)
{
var list = type == OrderBookEntryType.Ask ? asks : bids;
@@ -334,6 +334,35 @@ namespace CryptoExchange.Net.OrderBook
return new CallResult<decimal>(Math.Round(totalCost / totalAmount, 8));
}
/// <inheritdoc/>
public CallResult<decimal> CalculateTradableAmount(decimal quoteQuantity, OrderBookEntryType type)
{
if (Status != OrderBookStatus.Synced)
return new CallResult<decimal>(new InvalidOperationError($"{nameof(CalculateTradableAmount)} is not available when book is not in Synced state"));
var quoteQuantityLeft = quoteQuantity;
var totalBaseQuantity = 0m;
lock (_bookLock)
{
var list = type == OrderBookEntryType.Ask ? asks : bids;
var step = 0;
while (quoteQuantityLeft > 0)
{
if (step == list.Count)
return new CallResult<decimal>(new InvalidOperationError("Quantity is larger than order in the order book"));
var element = list.ElementAt(step);
var stepAmount = Math.Min(element.Value.Quantity * element.Value.Price, quoteQuantityLeft);
quoteQuantityLeft -= stepAmount;
totalBaseQuantity += stepAmount / element.Value.Price;
step++;
}
}
return new CallResult<decimal>(Math.Round(totalBaseQuantity, 8));
}
/// <summary>
/// Implementation for starting the order book. Should typically have logic for subscribing to the update stream and retrieving
/// and setting the initial order book
@@ -253,7 +253,7 @@ namespace CryptoExchange.Net.Sockets
var reconnectSuccessful = await ProcessReconnectAsync().ConfigureAwait(false);
if (!reconnectSuccessful)
{
_log.Write(LogLevel.Warning, "Failed reconnect processing, reconnecting again");
_log.Write(LogLevel.Warning, $"Failed reconnect processing: {reconnectSuccessful.Error}, reconnecting again");
await _socket.ReconnectAsync().ConfigureAwait(false);
}
else
+8
View File
@@ -33,6 +33,14 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d
Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf).
## Release notes
* Version 5.4.2 - 01 Apr 2023
* Reverted socket changes as it seems to cause reconnect to hang
* Version 5.4.1 - 18 Mar 2023
* Added CalculateTradableAmount to SymbolOrderBook
* Improved socket reconnect robustness
* Fixed api rate limiter not working correctly
* Version 5.4.0 - 14 Feb 2023
* Added unsubscribing when receiving subscribe answer after the request timeout has passed
* Fixed socket options copying