diff --git a/CryptoExchange.Net/Clients/BaseApiClient.cs b/CryptoExchange.Net/Clients/BaseApiClient.cs
index 639b4fc..80377dd 100644
--- a/CryptoExchange.Net/Clients/BaseApiClient.cs
+++ b/CryptoExchange.Net/Clients/BaseApiClient.cs
@@ -25,6 +25,8 @@ namespace CryptoExchange.Net
{
private readonly ApiCredentials? _apiCredentials;
private AuthenticationProvider? _authenticationProvider;
+ private bool _created;
+
///
/// The authentication provider for this API client. (null if no credentials are set)
///
@@ -32,8 +34,11 @@ namespace CryptoExchange.Net
{
get
{
- if (_authenticationProvider == null && _apiCredentials != null)
+ if (!_created && _apiCredentials != null)
+ {
_authenticationProvider = CreateAuthenticationProvider(_apiCredentials);
+ _created = true;
+ }
return _authenticationProvider;
}
@@ -51,7 +56,7 @@ namespace CryptoExchange.Net
/// Api client options
protected BaseApiClient(BaseClientOptions options, ApiClientOptions apiOptions)
{
- _apiCredentials = apiOptions.ApiCredentials ?? options.ApiCredentials;
+ _apiCredentials = apiOptions.ApiCredentials?.Copy() ?? options.ApiCredentials?.Copy();
BaseAddress = apiOptions.BaseAddress;
}
diff --git a/CryptoExchange.Net/Converters/DateTimeConverter.cs b/CryptoExchange.Net/Converters/DateTimeConverter.cs
index 79714ab..a49459f 100644
--- a/CryptoExchange.Net/Converters/DateTimeConverter.cs
+++ b/CryptoExchange.Net/Converters/DateTimeConverter.cs
@@ -12,6 +12,7 @@ namespace CryptoExchange.Net.Converters
public class DateTimeConverter: JsonConverter
{
private static readonly DateTime _epoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ private const long ticksPerSecond = TimeSpan.TicksPerMillisecond * 1000;
private const decimal ticksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000;
private const decimal ticksPerNanosecond = TimeSpan.TicksPerMillisecond / 1000m / 1000;
@@ -127,7 +128,7 @@ namespace CryptoExchange.Net.Converters
///
///
///
- public static DateTime ConvertFromSeconds(double seconds) => _epoch.AddSeconds(seconds);
+ public static DateTime ConvertFromSeconds(double seconds) => _epoch.AddTicks((long)Math.Round(seconds * ticksPerSecond));
///
/// Convert a milliseconds since epoch (01-01-1970) value to DateTime
///
diff --git a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs
index 1a10689..c506d3e 100644
--- a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs
+++ b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CryptoExchange.Net.Interfaces;
@@ -493,15 +494,15 @@ namespace CryptoExchange.Net.OrderBook
///
public string ToString(int numberOfEntries)
{
- var result = string.Empty;
- result += $"Asks ({AskCount}): {Environment.NewLine}";
- foreach (var entry in Asks.Take(numberOfEntries).Reverse())
- result += $" {entry.Price.ToString(CultureInfo.InvariantCulture).PadLeft(8)} | {entry.Quantity.ToString(CultureInfo.InvariantCulture).PadRight(8)}{Environment.NewLine}";
-
- result += $"Bids ({BidCount}): {Environment.NewLine}";
- foreach (var entry in Bids.Take(numberOfEntries))
- result += $" {entry.Price.ToString(CultureInfo.InvariantCulture).PadLeft(8)} | {entry.Quantity.ToString(CultureInfo.InvariantCulture).PadRight(8)}{Environment.NewLine}";
- return result;
+ var stringBuilder = new StringBuilder();
+ stringBuilder.AppendLine($" Ask quantity Ask price | Bid price Bid quantity");
+ for(var i = 0; i < numberOfEntries; i++)
+ {
+ var ask = asks.Count > i ? asks.ElementAt(i).Value: null;
+ var bid = bids.Count > i ? bids.ElementAt(i).Value: null;
+ stringBuilder.AppendLine($"[{ask?.Quantity.ToString(CultureInfo.InvariantCulture),14}] {ask?.Price.ToString(CultureInfo.InvariantCulture),14} | {bid?.Price.ToString(CultureInfo.InvariantCulture),-14} [{bid?.Quantity.ToString(CultureInfo.InvariantCulture),-14}]");
+ }
+ return stringBuilder.ToString();
}
private void CheckBestOffersChanged(ISymbolOrderBookEntry prevBestBid, ISymbolOrderBookEntry prevBestAsk)