1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-08 08:26:20 +00:00

Merge pull request #1 from JKorf/master

rebase from fork master
This commit is contained in:
BenDavison 2020-01-29 17:46:51 +00:00 committed by GitHub
commit 99d514c647
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 60 additions and 13 deletions

View File

@ -106,19 +106,16 @@ namespace CryptoExchange.Net
catch (JsonReaderException jre)
{
var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Data: {data}";
log.Write(LogVerbosity.Error, info);
return new CallResult<JToken>(null, new DeserializeError(info));
}
catch (JsonSerializationException jse)
{
var info = $"Deserialize JsonSerializationException: {jse.Message}. Data: {data}";
log.Write(LogVerbosity.Error, info);
return new CallResult<JToken>(null, new DeserializeError(info));
}
catch (Exception ex)
{
var info = $"Deserialize Unknown Exception: {ex.Message}. Data: {data}";
log.Write(LogVerbosity.Error, info);
return new CallResult<JToken>(null, new DeserializeError(info));
}
}
@ -134,7 +131,13 @@ namespace CryptoExchange.Net
protected CallResult<T> Deserialize<T>(string data, bool checkObject = true, JsonSerializer? serializer = null)
{
var tokenResult = ValidateJson(data);
return !tokenResult ? new CallResult<T>(default, tokenResult.Error) : Deserialize<T>(tokenResult.Data, checkObject, serializer);
if (!tokenResult)
{
log.Write(LogVerbosity.Error, tokenResult.Error!.Message);
return new CallResult<T>(default, tokenResult.Error);
}
return Deserialize<T>(tokenResult.Data, checkObject, serializer);
}
/// <summary>

View File

@ -5,12 +5,13 @@
<PropertyGroup>
<PackageId>CryptoExchange.Net</PackageId>
<Authors>JKorf</Authors>
<PackageVersion>3.0.2</PackageVersion>
<Description>A base package for implementing cryptocurrency exchange API's</Description>
<PackageVersion>3.0.4</PackageVersion>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
<NeutralLanguage>en</NeutralLanguage>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageReleaseNotes>3.0.2 - Removed invalid check for unauthenticated proxy</PackageReleaseNotes>
<PackageReleaseNotes>3.0.4 - Removed unnecessary json serialization when sending string data</PackageReleaseNotes>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

View File

@ -797,6 +797,11 @@
Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
</summary>
</member>
<member name="E:CryptoExchange.Net.Interfaces.ISymbolOrderBook.OnBestOffersChanged">
<summary>
Event when the BestBid or BestAsk changes ie a Pricing Tick
</summary>
</member>
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.LastOrderBookUpdate">
<summary>
Timestamp of the last update
@ -1769,6 +1774,11 @@
Event when the state changes
</summary>
</member>
<member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnBestOffersChanged">
<summary>
Event when the BestBid or BestAsk changes ie a Pricing Tick
</summary>
</member>
<member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnOrderBookUpdate">
<summary>
Event when order book was updated, containing the changed bids and asks. Be careful! It can generate a lot of events at high-liquidity markets

View File

@ -33,6 +33,10 @@ namespace CryptoExchange.Net.Interfaces
/// </summary>
event Action<IEnumerable<ISymbolOrderBookEntry>, IEnumerable<ISymbolOrderBookEntry>> OnOrderBookUpdate;
/// <summary>
/// Event when the BestBid or BestAsk changes ie a Pricing Tick
/// </summary>
event Action<ISymbolOrderBookEntry, ISymbolOrderBookEntry> OnBestOffersChanged;
/// <summary>
/// Timestamp of the last update
/// </summary>
DateTime LastOrderBookUpdate { get; }

View File

@ -79,6 +79,12 @@ namespace CryptoExchange.Net.OrderBook
/// Event when the state changes
/// </summary>
public event Action<OrderBookStatus, OrderBookStatus>? OnStatusChange;
/// <summary>
/// Event when the BestBid or BestAsk changes ie a Pricing Tick
/// </summary>
public event Action<ISymbolOrderBookEntry, ISymbolOrderBookEntry>? OnBestOffersChanged;
/// <summary>
/// Event when order book was updated, containing the changed bids and asks. Be careful! It can generate a lot of events at high-liquidity markets
/// </summary>
@ -286,9 +292,17 @@ namespace CryptoExchange.Net.OrderBook
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks. #{orderBookSequenceNumber}");
CheckProcessBuffer();
OnOrderBookUpdate?.Invoke(bidList, askList);
OnBestOffersChanged?.Invoke(BestBid, BestAsk);
}
}
private void CheckBestOffersChanged(ISymbolOrderBookEntry prevBestBid, ISymbolOrderBookEntry prevBestAsk)
{
if (BestBid.Price != prevBestBid.Price || BestBid.Quantity != prevBestBid.Quantity ||
BestAsk.Price != prevBestAsk.Price || BestAsk.Quantity != prevBestAsk.Quantity)
OnBestOffersChanged?.Invoke(BestBid, BestAsk);
}
/// <summary>
/// Update the order book using a single id for an update
/// </summary>
@ -315,8 +329,11 @@ namespace CryptoExchange.Net.OrderBook
else
{
CheckProcessBuffer();
var prevBestBid = BestBid;
var prevBestAsk = BestAsk;
ProcessSingleSequenceUpdates(rangeUpdateId, bids, asks);
OnOrderBookUpdate?.Invoke(bids, asks);
CheckBestOffersChanged(prevBestBid, prevBestAsk);
}
}
}
@ -349,8 +366,11 @@ namespace CryptoExchange.Net.OrderBook
else
{
CheckProcessBuffer();
var prevBestBid = BestBid;
var prevBestAsk = BestAsk;
ProcessRangeUpdates(firstUpdateId, lastUpdateId, bids, asks);
OnOrderBookUpdate?.Invoke(bids, asks);
CheckBestOffersChanged(prevBestBid, prevBestAsk);
}
}
}
@ -376,8 +396,11 @@ namespace CryptoExchange.Net.OrderBook
else
{
CheckProcessBuffer();
var prevBestBid = BestBid;
var prevBestAsk = BestAsk;
ProcessUpdates(bids, asks);
OnOrderBookUpdate?.Invoke(bids, asks);
CheckBestOffersChanged(prevBestBid, prevBestAsk);
}
}
}

View File

@ -181,7 +181,7 @@ namespace CryptoExchange.Net
}
string? paramString = null;
if (parameters != null && method == HttpMethod.Post)
if (method == HttpMethod.Post)
paramString = " with request body " + request.Content;
log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null? "": $" via proxy {apiProxy.Host}")}");

View File

@ -552,7 +552,7 @@ namespace CryptoExchange.Net
{
log.Write(LogVerbosity.Debug, $"Closing all {sockets.Sum(s => s.Value.HandlerCount)} subscriptions");
await Task.Run(() =>
await Task.Run(async () =>
{
var tasks = new List<Task>();
{
@ -561,7 +561,7 @@ namespace CryptoExchange.Net
tasks.Add(sub.Close());
}
Task.WaitAll(tasks.ToArray());
await Task.WhenAll(tasks.ToArray()).ConfigureAwait(false);
}).ConfigureAwait(false);
}

View File

@ -216,7 +216,10 @@ namespace CryptoExchange.Net.Sockets
/// <param name="nullValueHandling">How null values should be serialized</param>
public virtual void Send<T>(T obj, NullValueHandling nullValueHandling = NullValueHandling.Ignore)
{
Send(JsonConvert.SerializeObject(obj, Formatting.None, new JsonSerializerSettings { NullValueHandling = nullValueHandling }));
if(obj is string str)
Send(str);
else
Send(JsonConvert.SerializeObject(obj, Formatting.None, new JsonSerializerSettings { NullValueHandling = nullValueHandling }));
}
/// <summary>

View File

@ -194,6 +194,9 @@ The order book will automatically reconnect when the connection is lost and resy
To stop synchronizing an order book use the `Stop` method.
## Release notes
* Version 3.0.3 - 23 Jan 2020
* Added OnBestOffersChanged event to order book implementations
* Version 3.0.2 - 10 Dec 2019
* Removed invalid check for unauthenticated proxy