mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-10 01:16:24 +00:00
Cleanup/Fixed Resharper comments
This commit is contained in:
parent
de0916920f
commit
8cb3420520
@ -14,12 +14,12 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// <summary>
|
||||
/// The api key to authenticate requests
|
||||
/// </summary>
|
||||
public SecureString Key { get; private set; }
|
||||
public SecureString Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The api secret to authenticate requests
|
||||
/// </summary>
|
||||
public SecureString Secret { get; private set; }
|
||||
public SecureString Secret { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The private key to authenticate requests
|
||||
|
@ -140,7 +140,7 @@ namespace CryptoExchange.Net
|
||||
protected CallResult<T> Deserialize<T>(string data, bool checkObject = true, JsonSerializer serializer = null)
|
||||
{
|
||||
var tokenResult = ValidateJson(data);
|
||||
return !tokenResult.Success ? new CallResult<T>(default(T), tokenResult.Error) : Deserialize<T>(tokenResult.Data, checkObject, serializer);
|
||||
return !tokenResult.Success ? new CallResult<T>(default, tokenResult.Error) : Deserialize<T>(tokenResult.Data, checkObject, serializer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -184,19 +184,19 @@ namespace CryptoExchange.Net
|
||||
{
|
||||
var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Received data: {obj}";
|
||||
log.Write(LogVerbosity.Error, info);
|
||||
return new CallResult<T>(default(T), new DeserializeError(info));
|
||||
return new CallResult<T>(default, new DeserializeError(info));
|
||||
}
|
||||
catch (JsonSerializationException jse)
|
||||
{
|
||||
var info = $"Deserialize JsonSerializationException: {jse.Message}. Received data: {obj}";
|
||||
log.Write(LogVerbosity.Error, info);
|
||||
return new CallResult<T>(default(T), new DeserializeError(info));
|
||||
return new CallResult<T>(default, new DeserializeError(info));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var info = $"Deserialize Unknown Exception: {ex.Message}. Received data: {obj}";
|
||||
log.Write(LogVerbosity.Error, info);
|
||||
return new CallResult<T>(default(T), new DeserializeError(info));
|
||||
return new CallResult<T>(default, new DeserializeError(info));
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,7 +277,7 @@ namespace CryptoExchange.Net
|
||||
var attr = prop.GetCustomAttributes(typeof(JsonPropertyAttribute), false).FirstOrDefault();
|
||||
if (attr == null)
|
||||
{
|
||||
if (String.Equals(prop.Name, name, StringComparison.CurrentCultureIgnoreCase))
|
||||
if (string.Equals(prop.Name, name, StringComparison.CurrentCultureIgnoreCase))
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
|
@ -76,7 +76,7 @@ namespace CryptoExchange.Net.Converters
|
||||
|
||||
var converterAttribute = (JsonConverterAttribute)property.GetCustomAttribute(typeof(JsonConverterAttribute)) ?? (JsonConverterAttribute)property.PropertyType.GetCustomAttribute(typeof(JsonConverterAttribute));
|
||||
var conversionAttribute = (JsonConversionAttribute)property.GetCustomAttribute(typeof(JsonConversionAttribute)) ?? (JsonConversionAttribute)property.PropertyType.GetCustomAttribute(typeof(JsonConversionAttribute));
|
||||
object value = null;
|
||||
object value;
|
||||
if (converterAttribute != null)
|
||||
{
|
||||
value = arr[attribute.Index].ToObject(property.PropertyType, new JsonSerializer {Converters = {(JsonConverter) Activator.CreateInstance(converterAttribute.ConverterType)}});
|
||||
|
@ -78,7 +78,7 @@ namespace CryptoExchange.Net.Converters
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default(T);
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ namespace CryptoExchange.Net.Converters
|
||||
/// </summary>
|
||||
public class TimestampNanoSecondsConverter : JsonConverter
|
||||
{
|
||||
private const decimal ticksPerNanosecond = TimeSpan.TicksPerMillisecond / 1000m / 1000;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
@ -20,7 +22,6 @@ namespace CryptoExchange.Net.Converters
|
||||
if (reader.Value == null)
|
||||
return null;
|
||||
|
||||
var ticksPerNanosecond = (TimeSpan.TicksPerMillisecond / 1000m / 1000);
|
||||
var nanoSeconds = long.Parse(reader.Value.ToString());
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks((long)Math.Round(nanoSeconds * ticksPerNanosecond));
|
||||
}
|
||||
@ -28,7 +29,6 @@ namespace CryptoExchange.Net.Converters
|
||||
/// <inheritdoc />
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var ticksPerNanosecond = (TimeSpan.TicksPerMillisecond / 1000m / 1000);
|
||||
writer.WriteValue((long)Math.Round(((DateTime)value - new DateTime(1970, 1, 1)).Ticks / ticksPerNanosecond));
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +469,7 @@
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.ExtensionMethods.ToIEnumerable(System.Net.WebHeaderCollection)">
|
||||
<summary>
|
||||
Header collection to inenumerable
|
||||
Header collection to IEnumerable
|
||||
</summary>
|
||||
<param name="headers"></param>
|
||||
<returns></returns>
|
||||
@ -709,6 +709,110 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:CryptoExchange.Net.Interfaces.ISymbolOrderBook">
|
||||
<summary>
|
||||
Interface for order book
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.Status">
|
||||
<summary>
|
||||
The status of the order book. Order book is up to date when the status is `Synced`
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.LastSequenceNumber">
|
||||
<summary>
|
||||
Last update identifier
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.Symbol">
|
||||
<summary>
|
||||
The symbol of the order book
|
||||
</summary>
|
||||
</member>
|
||||
<member name="E:CryptoExchange.Net.Interfaces.ISymbolOrderBook.OnStatusChange">
|
||||
<summary>
|
||||
Event when the state changes
|
||||
</summary>
|
||||
</member>
|
||||
<member name="E:CryptoExchange.Net.Interfaces.ISymbolOrderBook.OnOrderBookUpdate">
|
||||
<summary>
|
||||
Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.LastOrderBookUpdate">
|
||||
<summary>
|
||||
Timestamp of the last update
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.AskCount">
|
||||
<summary>
|
||||
The number of asks in the book
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.BidCount">
|
||||
<summary>
|
||||
The number of bids in the book
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.Asks">
|
||||
<summary>
|
||||
The list of asks
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.Bids">
|
||||
<summary>
|
||||
The list of bids
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.BestBid">
|
||||
<summary>
|
||||
The best bid currently in the order book
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBook.BestAsk">
|
||||
<summary>
|
||||
The best ask currently in the order book
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Interfaces.ISymbolOrderBook.Start">
|
||||
<summary>
|
||||
Start connecting and synchronizing the order book
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Interfaces.ISymbolOrderBook.StartAsync">
|
||||
<summary>
|
||||
Start connecting and synchronizing the order book
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Interfaces.ISymbolOrderBook.Stop">
|
||||
<summary>
|
||||
Stop syncing the order book
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Interfaces.ISymbolOrderBook.StopAsync">
|
||||
<summary>
|
||||
Stop syncing the order book
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry">
|
||||
<summary>
|
||||
Interface for order book entries
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry.Quantity">
|
||||
<summary>
|
||||
The quantity of the entry
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry.Price">
|
||||
<summary>
|
||||
The price of the entry
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:CryptoExchange.Net.Interfaces.IWebsocket">
|
||||
<summary>
|
||||
Interface for websocket interaction
|
||||
@ -1445,21 +1549,6 @@
|
||||
<typeparam name="T"></typeparam>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry">
|
||||
<summary>
|
||||
Interface for order book entries
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry.Quantity">
|
||||
<summary>
|
||||
The quantity of the entry
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry.Price">
|
||||
<summary>
|
||||
The price of the entry
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:CryptoExchange.Net.OrderBook.OrderBookEntry">
|
||||
<summary>
|
||||
Order book entry
|
||||
@ -1522,7 +1611,7 @@
|
||||
The type
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.OrderBook.ProcessEntry.#ctor(CryptoExchange.Net.Objects.OrderBookEntryType,CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry)">
|
||||
<member name="M:CryptoExchange.Net.OrderBook.ProcessEntry.#ctor(CryptoExchange.Net.Objects.OrderBookEntryType,CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry)">
|
||||
<summary>
|
||||
ctor
|
||||
</summary>
|
||||
@ -1576,12 +1665,12 @@
|
||||
</member>
|
||||
<member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnOrderBookUpdate">
|
||||
<summary>
|
||||
Event when orderbook 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>
|
||||
</member>
|
||||
<member name="F:CryptoExchange.Net.OrderBook.SymbolOrderBook.LastOrderBookUpdate">
|
||||
<member name="P:CryptoExchange.Net.OrderBook.SymbolOrderBook.LastOrderBookUpdate">
|
||||
<summary>
|
||||
Should be useful for low-liquidity order-books to monitor market activity
|
||||
Timestamp of the last update
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.OrderBook.SymbolOrderBook.AskCount">
|
||||
@ -1662,7 +1751,7 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.SetInitialOrderBook(System.Int64,System.Collections.Generic.IEnumerable{CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry},System.Collections.Generic.IEnumerable{CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry})">
|
||||
<member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.SetInitialOrderBook(System.Int64,System.Collections.Generic.IEnumerable{CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry},System.Collections.Generic.IEnumerable{CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry})">
|
||||
<summary>
|
||||
Set the initial data for the order book
|
||||
</summary>
|
||||
@ -1683,7 +1772,7 @@
|
||||
Check and empty the process buffer; see what entries to update the book with
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.ProcessUpdate(CryptoExchange.Net.Objects.OrderBookEntryType,CryptoExchange.Net.OrderBook.ISymbolOrderBookEntry)">
|
||||
<member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.ProcessUpdate(CryptoExchange.Net.Objects.OrderBookEntryType,CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry)">
|
||||
<summary>
|
||||
Update order book with an entry
|
||||
</summary>
|
||||
@ -1789,7 +1878,7 @@
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Requests.Request.#ctor(System.Net.WebRequest)">
|
||||
<summary>
|
||||
Create request object for webrequest
|
||||
Create request object for web request
|
||||
</summary>
|
||||
<param name="request"></param>
|
||||
</member>
|
||||
@ -2126,7 +2215,7 @@
|
||||
<summary>
|
||||
Query for data
|
||||
</summary>
|
||||
<typeparam name="T">Exepected result type</typeparam>
|
||||
<typeparam name="T">Expected result type</typeparam>
|
||||
<param name="request">The request to send</param>
|
||||
<param name="authenticated">Whether the socket should be authenticated</param>
|
||||
<returns></returns>
|
||||
|
@ -127,7 +127,7 @@ namespace CryptoExchange.Net
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Header collection to inenumerable
|
||||
/// Header collection to IEnumerable
|
||||
/// </summary>
|
||||
/// <param name="headers"></param>
|
||||
/// <returns></returns>
|
||||
@ -153,7 +153,7 @@ namespace CryptoExchange.Net
|
||||
public static async Task<bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout, CancellationToken cancellationToken)
|
||||
{
|
||||
RegisteredWaitHandle registeredHandle = null;
|
||||
CancellationTokenRegistration tokenRegistration = default(CancellationTokenRegistration);
|
||||
CancellationTokenRegistration tokenRegistration = default;
|
||||
try
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using CryptoExchange.Net.Objects;
|
||||
using CryptoExchange.Net.RateLimiter;
|
||||
|
||||
|
93
CryptoExchange.Net/Interfaces/ISymbolOrderBook.cs
Normal file
93
CryptoExchange.Net/Interfaces/ISymbolOrderBook.cs
Normal file
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CryptoExchange.Net.Objects;
|
||||
|
||||
namespace CryptoExchange.Net.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for order book
|
||||
/// </summary>
|
||||
public interface ISymbolOrderBook
|
||||
{
|
||||
/// <summary>
|
||||
/// The status of the order book. Order book is up to date when the status is `Synced`
|
||||
/// </summary>
|
||||
OrderBookStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Last update identifier
|
||||
/// </summary>
|
||||
long LastSequenceNumber { get; }
|
||||
/// <summary>
|
||||
/// The symbol of the order book
|
||||
/// </summary>
|
||||
string Symbol { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event when the state changes
|
||||
/// </summary>
|
||||
event Action<OrderBookStatus, OrderBookStatus> OnStatusChange;
|
||||
/// <summary>
|
||||
/// Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
|
||||
/// </summary>
|
||||
event Action OnOrderBookUpdate;
|
||||
/// <summary>
|
||||
/// Timestamp of the last update
|
||||
/// </summary>
|
||||
DateTime LastOrderBookUpdate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of asks in the book
|
||||
/// </summary>
|
||||
int AskCount { get; }
|
||||
/// <summary>
|
||||
/// The number of bids in the book
|
||||
/// </summary>
|
||||
int BidCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of asks
|
||||
/// </summary>
|
||||
IEnumerable<ISymbolOrderBookEntry> Asks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of bids
|
||||
/// </summary>
|
||||
IEnumerable<ISymbolOrderBookEntry> Bids { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The best bid currently in the order book
|
||||
/// </summary>
|
||||
ISymbolOrderBookEntry BestBid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The best ask currently in the order book
|
||||
/// </summary>
|
||||
ISymbolOrderBookEntry BestAsk { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Start connecting and synchronizing the order book
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
CallResult<bool> Start();
|
||||
|
||||
/// <summary>
|
||||
/// Start connecting and synchronizing the order book
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<CallResult<bool>> StartAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Stop syncing the order book
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// Stop syncing the order book
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task StopAsync();
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
namespace CryptoExchange.Net.OrderBook
|
||||
namespace CryptoExchange.Net.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for order book entries
|
@ -21,8 +21,8 @@ namespace CryptoExchange.Net.Objects
|
||||
|
||||
// If one is null and the other isn't, then the
|
||||
// one that is null is "lesser".
|
||||
if (x == null && y != null) return -1;
|
||||
if (x != null && y == null) return 1;
|
||||
if (x == null) return -1;
|
||||
if (y == null) return 1;
|
||||
|
||||
// Both arrays are non-null. Find the shorter
|
||||
// of the two lengths.
|
||||
|
@ -71,7 +71,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public static WebCallResult<T> CreateErrorResult(Error error)
|
||||
{
|
||||
return new WebCallResult<T>(null, null, default(T), error);
|
||||
return new WebCallResult<T>(null, null, default, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -83,7 +83,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public static WebCallResult<T> CreateErrorResult(HttpStatusCode? code, IEnumerable<Tuple<string, string>> responseHeaders, Error error)
|
||||
{
|
||||
return new WebCallResult<T>(code, responseHeaders, default(T), error);
|
||||
return new WebCallResult<T>(code, responseHeaders, default, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@
|
||||
/// <summary>
|
||||
/// Data synced, order book is up to date
|
||||
/// </summary>
|
||||
Synced,
|
||||
Synced
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,4 +1,6 @@
|
||||
namespace CryptoExchange.Net.OrderBook
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
|
||||
namespace CryptoExchange.Net.OrderBook
|
||||
{
|
||||
/// <summary>
|
||||
/// Order book entry
|
||||
|
@ -1,4 +1,5 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using CryptoExchange.Net.Objects;
|
||||
|
||||
namespace CryptoExchange.Net.OrderBook
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using CryptoExchange.Net.Logging;
|
||||
using CryptoExchange.Net.Objects;
|
||||
using CryptoExchange.Net.Sockets;
|
||||
@ -13,7 +14,7 @@ namespace CryptoExchange.Net.OrderBook
|
||||
/// <summary>
|
||||
/// Base for order book implementations
|
||||
/// </summary>
|
||||
public abstract class SymbolOrderBook : IDisposable
|
||||
public abstract class SymbolOrderBook : ISymbolOrderBook, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The process buffer, used while syncing
|
||||
@ -23,12 +24,12 @@ namespace CryptoExchange.Net.OrderBook
|
||||
/// <summary>
|
||||
/// The ask list
|
||||
/// </summary>
|
||||
protected SortedList<decimal, OrderBookEntry> asks;
|
||||
protected SortedList<decimal, ISymbolOrderBookEntry> asks;
|
||||
/// <summary>
|
||||
/// The bid list
|
||||
/// </summary>
|
||||
|
||||
protected SortedList<decimal, OrderBookEntry> bids;
|
||||
protected SortedList<decimal, ISymbolOrderBookEntry> bids;
|
||||
private OrderBookStatus status;
|
||||
private UpdateSubscription subscription;
|
||||
private readonly bool sequencesAreConsecutive;
|
||||
@ -72,13 +73,13 @@ namespace CryptoExchange.Net.OrderBook
|
||||
/// </summary>
|
||||
public event Action<OrderBookStatus, OrderBookStatus> OnStatusChange;
|
||||
/// <summary>
|
||||
/// Event when orderbook 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>
|
||||
public event Action OnOrderBookUpdate;
|
||||
/// <summary>
|
||||
/// Should be useful for low-liquidity order-books to monitor market activity
|
||||
/// Timestamp of the last update
|
||||
/// </summary>
|
||||
public DateTime LastOrderBookUpdate;
|
||||
public DateTime LastOrderBookUpdate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of asks in the book
|
||||
@ -150,8 +151,8 @@ namespace CryptoExchange.Net.OrderBook
|
||||
Symbol = symbol;
|
||||
Status = OrderBookStatus.Disconnected;
|
||||
|
||||
asks = new SortedList<decimal, OrderBookEntry>();
|
||||
bids = new SortedList<decimal, OrderBookEntry>(new DescComparer<decimal>());
|
||||
asks = new SortedList<decimal, ISymbolOrderBookEntry>();
|
||||
bids = new SortedList<decimal, ISymbolOrderBookEntry>(new DescComparer<decimal>());
|
||||
|
||||
log = new Log { Level = options.LogVerbosity };
|
||||
var writers = options.LogWriters ?? new List<TextWriter> { new DebugTextWriter() };
|
||||
@ -177,7 +178,7 @@ namespace CryptoExchange.Net.OrderBook
|
||||
|
||||
subscription = startResult.Data;
|
||||
subscription.ConnectionLost += Reset;
|
||||
subscription.ConnectionRestored += (time) => Resync();
|
||||
subscription.ConnectionRestored += time => Resync();
|
||||
Status = OrderBookStatus.Synced;
|
||||
return new CallResult<bool>(true, null);
|
||||
}
|
||||
@ -194,7 +195,7 @@ namespace CryptoExchange.Net.OrderBook
|
||||
private void Resync()
|
||||
{
|
||||
Status = OrderBookStatus.Syncing;
|
||||
bool success = false;
|
||||
var success = false;
|
||||
while (!success)
|
||||
{
|
||||
if (Status != OrderBookStatus.Syncing)
|
||||
@ -289,7 +290,7 @@ namespace CryptoExchange.Net.OrderBook
|
||||
|
||||
if (!bookSet)
|
||||
{
|
||||
var entry = new ProcessBufferEntry()
|
||||
var entry = new ProcessBufferEntry
|
||||
{
|
||||
FirstSequence = firstSequenceNumber,
|
||||
LastSequence = lastSequenceNumber,
|
||||
@ -350,25 +351,25 @@ namespace CryptoExchange.Net.OrderBook
|
||||
var listToChange = type == OrderBookEntryType.Ask ? asks : bids;
|
||||
if (entry.Quantity == 0)
|
||||
{
|
||||
var bookEntry = listToChange.SingleOrDefault(i => i.Key == entry.Price);
|
||||
if (!bookEntry.Equals(default(KeyValuePair<decimal, OrderBookEntry>)))
|
||||
{
|
||||
listToChange.Remove(entry.Price);
|
||||
if (type == OrderBookEntryType.Ask) AskCount--;
|
||||
else BidCount--;
|
||||
}
|
||||
if (!listToChange.ContainsKey(entry.Price))
|
||||
return;
|
||||
|
||||
listToChange.Remove(entry.Price);
|
||||
if (type == OrderBookEntryType.Ask) AskCount--;
|
||||
else BidCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
var bookEntry = listToChange.SingleOrDefault(i => i.Key == entry.Price);
|
||||
if (bookEntry.Equals(default(KeyValuePair<decimal, OrderBookEntry>)))
|
||||
if (!listToChange.ContainsKey(entry.Price))
|
||||
{
|
||||
listToChange.Add(entry.Price, new OrderBookEntry(entry.Price, entry.Quantity));
|
||||
if (type == OrderBookEntryType.Ask) AskCount++;
|
||||
else BidCount++;
|
||||
}
|
||||
else
|
||||
bookEntry.Value.Quantity = entry.Quantity;
|
||||
{
|
||||
listToChange[entry.Price].Quantity = entry.Quantity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace CryptoExchange.Net.RateLimiter
|
||||
if(client.authProvider?.Credentials == null)
|
||||
return new CallResult<double>(0, null);
|
||||
|
||||
string key = client.authProvider.Credentials.Key.GetString();
|
||||
var key = client.authProvider.Credentials.Key.GetString();
|
||||
|
||||
int waitTime;
|
||||
RateLimitObject rlo;
|
||||
|
@ -14,7 +14,7 @@ namespace CryptoExchange.Net.Requests
|
||||
private readonly WebRequest request;
|
||||
|
||||
/// <summary>
|
||||
/// Create request object for webrequest
|
||||
/// Create request object for web request
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
public Request(WebRequest request)
|
||||
|
@ -126,14 +126,14 @@ namespace CryptoExchange.Net
|
||||
catch(PingException e)
|
||||
{
|
||||
if (e.InnerException == null)
|
||||
return new CallResult<long>(0, new CantConnectError() {Message = "Ping failed: " + e.Message});
|
||||
return new CallResult<long>(0, new CantConnectError {Message = "Ping failed: " + e.Message});
|
||||
|
||||
if (e.InnerException is SocketException exception)
|
||||
return new CallResult<long>(0, new CantConnectError() { Message = "Ping failed: " + exception.SocketErrorCode });
|
||||
return new CallResult<long>(0, new CantConnectError() { Message = "Ping failed: " + e.InnerException.Message });
|
||||
return new CallResult<long>(0, new CantConnectError { Message = "Ping failed: " + exception.SocketErrorCode });
|
||||
return new CallResult<long>(0, new CantConnectError { Message = "Ping failed: " + e.InnerException.Message });
|
||||
}
|
||||
|
||||
return reply.Status == IPStatus.Success ? new CallResult<long>(reply.RoundtripTime, null) : new CallResult<long>(0, new CantConnectError() { Message = "Ping failed: " + reply.Status });
|
||||
return reply.Status == IPStatus.Success ? new CallResult<long>(reply.RoundtripTime, null) : new CallResult<long>(0, new CantConnectError { Message = "Ping failed: " + reply.Status });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -280,7 +280,7 @@ namespace CryptoExchange.Net
|
||||
}
|
||||
else if(requestBodyFormat == RequestBodyFormat.FormData)
|
||||
{
|
||||
var formData = HttpUtility.ParseQueryString(String.Empty);
|
||||
var formData = HttpUtility.ParseQueryString(string.Empty);
|
||||
foreach (var kvp in parameters.OrderBy(p => p.Key))
|
||||
formData.Add(kvp.Key, kvp.Value.ToString());
|
||||
var stringData = formData.ToString();
|
||||
@ -320,19 +320,24 @@ namespace CryptoExchange.Net
|
||||
|
||||
try
|
||||
{
|
||||
using (var reader = new StreamReader(response.GetResponseStream()))
|
||||
var responseStream = response?.GetResponseStream();
|
||||
if (response != null && responseStream != null)
|
||||
{
|
||||
returnedData = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||
log.Write(LogVerbosity.Warning, "Server returned an error: " + returnedData);
|
||||
using (var reader = new StreamReader(responseStream))
|
||||
{
|
||||
returnedData = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||
log.Write(LogVerbosity.Warning, "Server returned an error: " + returnedData);
|
||||
}
|
||||
|
||||
response.Close();
|
||||
|
||||
var jsonResult = ValidateJson(returnedData);
|
||||
return !jsonResult.Success ? new WebCallResult<string>(statusCode, returnHeaders, null, jsonResult.Error) : new WebCallResult<string>(statusCode, returnHeaders, null, ParseErrorResponse(jsonResult.Data));
|
||||
}
|
||||
|
||||
response.Close();
|
||||
|
||||
var jsonResult = ValidateJson(returnedData);
|
||||
return !jsonResult.Success ? new WebCallResult<string>(statusCode, returnHeaders, null, jsonResult.Error) : new WebCallResult<string>(statusCode, returnHeaders, null, ParseErrorResponse(jsonResult.Data));
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Write(LogVerbosity.Debug, "Not able to read server response: " + e.Message);
|
||||
}
|
||||
|
||||
var infoMessage = "No response from server";
|
||||
|
@ -141,7 +141,7 @@ namespace CryptoExchange.Net
|
||||
{
|
||||
SocketConnection socket;
|
||||
SocketSubscription handler;
|
||||
bool released = false;
|
||||
var released = false;
|
||||
await semaphoreSlim.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
@ -193,13 +193,7 @@ namespace CryptoExchange.Net
|
||||
protected internal virtual async Task<CallResult<bool>> SubscribeAndWait(SocketConnection socket, object request, SocketSubscription subscription)
|
||||
{
|
||||
CallResult<object> callResult = null;
|
||||
await socket.SendAndWait(request, ResponseTimeout, (data) =>
|
||||
{
|
||||
if (!HandleSubscriptionResponse(socket, subscription, request, data, out callResult))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}).ConfigureAwait(false);
|
||||
await socket.SendAndWait(request, ResponseTimeout, data => HandleSubscriptionResponse(socket, subscription, request, data, out callResult)).ConfigureAwait(false);
|
||||
|
||||
if (callResult?.Success == true)
|
||||
subscription.Confirmed = true;
|
||||
@ -210,7 +204,7 @@ namespace CryptoExchange.Net
|
||||
/// <summary>
|
||||
/// Query for data
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Exepected result type</typeparam>
|
||||
/// <typeparam name="T">Expected result type</typeparam>
|
||||
/// <param name="request">The request to send</param>
|
||||
/// <param name="authenticated">Whether the socket should be authenticated</param>
|
||||
/// <returns></returns>
|
||||
@ -230,7 +224,7 @@ namespace CryptoExchange.Net
|
||||
protected virtual async Task<CallResult<T>> Query<T>(string url, object request, bool authenticated)
|
||||
{
|
||||
SocketConnection socket;
|
||||
bool released = false;
|
||||
var released = false;
|
||||
await semaphoreSlim.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
@ -244,7 +238,7 @@ namespace CryptoExchange.Net
|
||||
|
||||
var connectResult = await ConnectIfNeeded(socket, authenticated).ConfigureAwait(false);
|
||||
if (!connectResult.Success)
|
||||
return new CallResult<T>(default(T), connectResult.Error);
|
||||
return new CallResult<T>(default, connectResult.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -257,7 +251,7 @@ namespace CryptoExchange.Net
|
||||
if (socket.PausedActivity)
|
||||
{
|
||||
log.Write(LogVerbosity.Info, "Socket has been paused, can't send query at this moment");
|
||||
return new CallResult<T>(default(T), new ServerError("Socket is paused"));
|
||||
return new CallResult<T>(default, new ServerError("Socket is paused"));
|
||||
}
|
||||
|
||||
return await QueryAndWait<T>(socket, request).ConfigureAwait(false);
|
||||
@ -272,8 +266,8 @@ namespace CryptoExchange.Net
|
||||
/// <returns></returns>
|
||||
protected virtual async Task<CallResult<T>> QueryAndWait<T>(SocketConnection socket, object request)
|
||||
{
|
||||
CallResult<T> dataResult = new CallResult<T>(default(T), new ServerError("No response on query received"));
|
||||
await socket.SendAndWait(request, ResponseTimeout, (data) =>
|
||||
var dataResult = new CallResult<T>(default, new ServerError("No response on query received"));
|
||||
await socket.SendAndWait(request, ResponseTimeout, data =>
|
||||
{
|
||||
if (!HandleQueryResponse<T>(socket, request, data, out var callResult))
|
||||
return false;
|
||||
@ -293,28 +287,25 @@ namespace CryptoExchange.Net
|
||||
/// <returns></returns>
|
||||
protected virtual async Task<CallResult<bool>> ConnectIfNeeded(SocketConnection socket, bool authenticated)
|
||||
{
|
||||
if (!socket.Connected)
|
||||
if (socket.Connected)
|
||||
return new CallResult<bool>(true, null);
|
||||
|
||||
var connectResult = await ConnectSocket(socket).ConfigureAwait(false);
|
||||
if (!connectResult.Success)
|
||||
return new CallResult<bool>(false, new CantConnectError());
|
||||
|
||||
if (!authenticated || socket.Authenticated)
|
||||
return new CallResult<bool>(true, null);
|
||||
|
||||
var result = await AuthenticateSocket(socket).ConfigureAwait(false);
|
||||
if (!result.Success)
|
||||
{
|
||||
var connectResult = await ConnectSocket(socket).ConfigureAwait(false);
|
||||
if (!connectResult.Success)
|
||||
{
|
||||
return new CallResult<bool>(false, new CantConnectError());
|
||||
}
|
||||
|
||||
if (authenticated && !socket.Authenticated)
|
||||
{
|
||||
var result = await AuthenticateSocket(socket).ConfigureAwait(false);
|
||||
if (!result.Success)
|
||||
{
|
||||
log.Write(LogVerbosity.Warning, "Socket authentication failed");
|
||||
result.Error.Message = "Authentication failed: " + result.Error.Message;
|
||||
return new CallResult<bool>(false, result.Error);
|
||||
}
|
||||
|
||||
socket.Authenticated = true;
|
||||
}
|
||||
log.Write(LogVerbosity.Warning, "Socket authentication failed");
|
||||
result.Error.Message = "Authentication failed: " + result.Error.Message;
|
||||
return new CallResult<bool>(false, result.Error);
|
||||
}
|
||||
|
||||
socket.Authenticated = true;
|
||||
return new CallResult<bool>(true, null);
|
||||
}
|
||||
|
||||
@ -388,11 +379,11 @@ namespace CryptoExchange.Net
|
||||
/// <returns></returns>
|
||||
protected virtual SocketSubscription AddHandler<T>(object request, string identifier, bool userSubscription, SocketConnection connection, Action<T> dataHandler)
|
||||
{
|
||||
Action<SocketConnection, JToken> internalHandler = (socketWrapper, data) =>
|
||||
void InternalHandler(SocketConnection socketWrapper, JToken data)
|
||||
{
|
||||
if (typeof(T) == typeof(string))
|
||||
{
|
||||
dataHandler((T)Convert.ChangeType(data.ToString(), typeof(T)));
|
||||
dataHandler((T) Convert.ChangeType(data.ToString(), typeof(T)));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -404,11 +395,9 @@ namespace CryptoExchange.Net
|
||||
}
|
||||
|
||||
dataHandler(desResult.Data);
|
||||
};
|
||||
}
|
||||
|
||||
if (request != null)
|
||||
return connection.AddHandler(request, userSubscription, internalHandler);
|
||||
return connection.AddHandler(identifier, userSubscription, internalHandler);
|
||||
return connection.AddHandler(request ?? identifier, userSubscription, InternalHandler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -515,16 +504,16 @@ namespace CryptoExchange.Net
|
||||
break;
|
||||
|
||||
var obj = objGetter(socket);
|
||||
if (obj != null)
|
||||
if (obj == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
socket.Send(obj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Write(LogVerbosity.Warning, "Periodic send failed: " + ex);
|
||||
}
|
||||
socket.Send(obj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Write(LogVerbosity.Warning, "Periodic send failed: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace CryptoExchange.Net.Sockets
|
||||
/// <summary>
|
||||
/// Socket implementation
|
||||
/// </summary>
|
||||
public class BaseSocket: IWebsocket
|
||||
internal class BaseSocket: IWebsocket
|
||||
{
|
||||
internal static int lastStreamId;
|
||||
private static readonly object streamIdLock = new object();
|
||||
@ -153,7 +153,7 @@ namespace CryptoExchange.Net.Sockets
|
||||
if (DateTime.UtcNow - LastActionTime > Timeout)
|
||||
{
|
||||
log.Write(LogVerbosity.Warning, $"No data received for {Timeout}, reconnecting socket");
|
||||
Close().ConfigureAwait(false);
|
||||
_ = Close().ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -267,7 +267,7 @@ namespace CryptoExchange.Net.Sockets
|
||||
if (connected)
|
||||
{
|
||||
log?.Write(LogVerbosity.Debug, $"Socket {Id} connected");
|
||||
if ((timeoutTask == null || timeoutTask.IsCompleted) && Timeout != default(TimeSpan))
|
||||
if ((timeoutTask == null || timeoutTask.IsCompleted) && Timeout != default)
|
||||
timeoutTask = Task.Run(CheckTimeout);
|
||||
}
|
||||
else
|
||||
|
@ -172,7 +172,7 @@ namespace CryptoExchange.Net.Sockets
|
||||
SocketSubscription currentSubscription = null;
|
||||
try
|
||||
{
|
||||
bool handled = false;
|
||||
var handled = false;
|
||||
var sw = Stopwatch.StartNew();
|
||||
lock (handlersLock)
|
||||
{
|
||||
@ -387,7 +387,7 @@ namespace CryptoExchange.Net.Sockets
|
||||
if (subscription.Confirmed)
|
||||
await socketClient.Unsubscribe(this, subscription).ConfigureAwait(false);
|
||||
|
||||
bool shouldCloseWrapper = false;
|
||||
var shouldCloseWrapper = false;
|
||||
lock (handlersLock)
|
||||
{
|
||||
handlers.Remove(subscription);
|
||||
|
Loading…
x
Reference in New Issue
Block a user