mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-08 16:36:15 +00:00
commit
99d514c647
@ -106,19 +106,16 @@ namespace CryptoExchange.Net
|
|||||||
catch (JsonReaderException jre)
|
catch (JsonReaderException jre)
|
||||||
{
|
{
|
||||||
var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Data: {data}";
|
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));
|
return new CallResult<JToken>(null, new DeserializeError(info));
|
||||||
}
|
}
|
||||||
catch (JsonSerializationException jse)
|
catch (JsonSerializationException jse)
|
||||||
{
|
{
|
||||||
var info = $"Deserialize JsonSerializationException: {jse.Message}. Data: {data}";
|
var info = $"Deserialize JsonSerializationException: {jse.Message}. Data: {data}";
|
||||||
log.Write(LogVerbosity.Error, info);
|
|
||||||
return new CallResult<JToken>(null, new DeserializeError(info));
|
return new CallResult<JToken>(null, new DeserializeError(info));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var info = $"Deserialize Unknown Exception: {ex.Message}. Data: {data}";
|
var info = $"Deserialize Unknown Exception: {ex.Message}. Data: {data}";
|
||||||
log.Write(LogVerbosity.Error, info);
|
|
||||||
return new CallResult<JToken>(null, new DeserializeError(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)
|
protected CallResult<T> Deserialize<T>(string data, bool checkObject = true, JsonSerializer? serializer = null)
|
||||||
{
|
{
|
||||||
var tokenResult = ValidateJson(data);
|
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>
|
/// <summary>
|
||||||
|
@ -5,12 +5,13 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>CryptoExchange.Net</PackageId>
|
<PackageId>CryptoExchange.Net</PackageId>
|
||||||
<Authors>JKorf</Authors>
|
<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>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
|
||||||
<NeutralLanguage>en</NeutralLanguage>
|
<NeutralLanguage>en</NeutralLanguage>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<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>
|
<Nullable>enable</Nullable>
|
||||||
<LangVersion>8.0</LangVersion>
|
<LangVersion>8.0</LangVersion>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
|
@ -797,6 +797,11 @@
|
|||||||
Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
|
Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</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">
|
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.LastOrderBookUpdate">
|
||||||
<summary>
|
<summary>
|
||||||
Timestamp of the last update
|
Timestamp of the last update
|
||||||
@ -1769,6 +1774,11 @@
|
|||||||
Event when the state changes
|
Event when the state changes
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</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">
|
<member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnOrderBookUpdate">
|
||||||
<summary>
|
<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
|
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
|
||||||
|
@ -33,6 +33,10 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
event Action<IEnumerable<ISymbolOrderBookEntry>, IEnumerable<ISymbolOrderBookEntry>> OnOrderBookUpdate;
|
event Action<IEnumerable<ISymbolOrderBookEntry>, IEnumerable<ISymbolOrderBookEntry>> OnOrderBookUpdate;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Event when the BestBid or BestAsk changes ie a Pricing Tick
|
||||||
|
/// </summary>
|
||||||
|
event Action<ISymbolOrderBookEntry, ISymbolOrderBookEntry> OnBestOffersChanged;
|
||||||
|
/// <summary>
|
||||||
/// Timestamp of the last update
|
/// Timestamp of the last update
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTime LastOrderBookUpdate { get; }
|
DateTime LastOrderBookUpdate { get; }
|
||||||
|
@ -79,6 +79,12 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
/// Event when the state changes
|
/// Event when the state changes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<OrderBookStatus, OrderBookStatus>? OnStatusChange;
|
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>
|
/// <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
|
/// 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>
|
/// </summary>
|
||||||
@ -286,9 +292,17 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks. #{orderBookSequenceNumber}");
|
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks. #{orderBookSequenceNumber}");
|
||||||
CheckProcessBuffer();
|
CheckProcessBuffer();
|
||||||
OnOrderBookUpdate?.Invoke(bidList, askList);
|
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>
|
/// <summary>
|
||||||
/// Update the order book using a single id for an update
|
/// Update the order book using a single id for an update
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -315,8 +329,11 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheckProcessBuffer();
|
CheckProcessBuffer();
|
||||||
|
var prevBestBid = BestBid;
|
||||||
|
var prevBestAsk = BestAsk;
|
||||||
ProcessSingleSequenceUpdates(rangeUpdateId, bids, asks);
|
ProcessSingleSequenceUpdates(rangeUpdateId, bids, asks);
|
||||||
OnOrderBookUpdate?.Invoke(bids, asks);
|
OnOrderBookUpdate?.Invoke(bids, asks);
|
||||||
|
CheckBestOffersChanged(prevBestBid, prevBestAsk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,8 +366,11 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheckProcessBuffer();
|
CheckProcessBuffer();
|
||||||
|
var prevBestBid = BestBid;
|
||||||
|
var prevBestAsk = BestAsk;
|
||||||
ProcessRangeUpdates(firstUpdateId, lastUpdateId, bids, asks);
|
ProcessRangeUpdates(firstUpdateId, lastUpdateId, bids, asks);
|
||||||
OnOrderBookUpdate?.Invoke(bids, asks);
|
OnOrderBookUpdate?.Invoke(bids, asks);
|
||||||
|
CheckBestOffersChanged(prevBestBid, prevBestAsk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,8 +396,11 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheckProcessBuffer();
|
CheckProcessBuffer();
|
||||||
|
var prevBestBid = BestBid;
|
||||||
|
var prevBestAsk = BestAsk;
|
||||||
ProcessUpdates(bids, asks);
|
ProcessUpdates(bids, asks);
|
||||||
OnOrderBookUpdate?.Invoke(bids, asks);
|
OnOrderBookUpdate?.Invoke(bids, asks);
|
||||||
|
CheckBestOffersChanged(prevBestBid, prevBestAsk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ namespace CryptoExchange.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
string? paramString = null;
|
string? paramString = null;
|
||||||
if (parameters != null && method == HttpMethod.Post)
|
if (method == HttpMethod.Post)
|
||||||
paramString = " with request body " + request.Content;
|
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}")}");
|
log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null? "": $" via proxy {apiProxy.Host}")}");
|
||||||
|
@ -552,7 +552,7 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
log.Write(LogVerbosity.Debug, $"Closing all {sockets.Sum(s => s.Value.HandlerCount)} subscriptions");
|
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>();
|
var tasks = new List<Task>();
|
||||||
{
|
{
|
||||||
@ -561,7 +561,7 @@ namespace CryptoExchange.Net
|
|||||||
tasks.Add(sub.Close());
|
tasks.Add(sub.Close());
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.WaitAll(tasks.ToArray());
|
await Task.WhenAll(tasks.ToArray()).ConfigureAwait(false);
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,10 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
/// <param name="nullValueHandling">How null values should be serialized</param>
|
/// <param name="nullValueHandling">How null values should be serialized</param>
|
||||||
public virtual void Send<T>(T obj, NullValueHandling nullValueHandling = NullValueHandling.Ignore)
|
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>
|
/// <summary>
|
||||||
|
@ -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.
|
To stop synchronizing an order book use the `Stop` method.
|
||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
* Version 3.0.3 - 23 Jan 2020
|
||||||
|
* Added OnBestOffersChanged event to order book implementations
|
||||||
|
|
||||||
* Version 3.0.2 - 10 Dec 2019
|
* Version 3.0.2 - 10 Dec 2019
|
||||||
* Removed invalid check for unauthenticated proxy
|
* Removed invalid check for unauthenticated proxy
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user