From a0764a88fc3c01eda1d94d6086264c3d9b95ffab Mon Sep 17 00:00:00 2001
From: Vlad Dumitru <vlad-dumitru@outlook.com>
Date: Mon, 20 Jan 2025 16:14:10 +0200
Subject: [PATCH] Fix cap problem
---
.../API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs | 25 +++++-----
.../API/Exchanges/MEXC/ExchangeMEXCAPI.cs | 43 +++++++++-------
.../Exchanges/_Base/ExchangeAPIExtensions.cs | 50 +++++++++++++------
3 files changed, 72 insertions(+), 46 deletions(-)
diff --git a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs
index 5b79ad70..a0735912 100644
--- a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs
+++ b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs
@@ -40,7 +40,7 @@ private ExchangeKuCoinAPI()
NonceEndPointField = "data";
NonceEndPointStyle = NonceStyle.UnixMilliseconds;
MarketSymbolSeparator = "-";
- RateLimit = new RateGate(20, TimeSpan.FromSeconds(60.0));
+ RateLimit = new RateGate(60, TimeSpan.FromSeconds(1)); // https://www.kucoin.com/docs/basic-info/request-rate-limit/rest-api
WebSocketOrderBookType = WebSocketOrderBookType.FullBookFirstThenDeltas;
}
@@ -875,6 +875,16 @@ params string[] marketSymbols
var initialSequenceIds = new Dictionary<string, long>();
+ foreach (var marketSymbol in marketSymbols)
+ {
+ var initialBook = await OnGetOrderBookAsync(marketSymbol, maxCount);
+ initialBook.IsFromSnapshot = true;
+
+ callback(initialBook);
+
+ initialSequenceIds[marketSymbol] = initialBook.SequenceId;
+ }
+
var websocketUrlToken = GetWebsocketBulletToken();
return await ConnectPublicWebSocketAsync(
@@ -958,19 +968,10 @@ params string[] marketSymbols
},
connectCallback: async (_socket) =>
{
- // Get full order book snapshot when connecting
- foreach (var marketSymbol in marketSymbols)
- {
- var initialBook = await OnGetOrderBookAsync(marketSymbol, maxCount);
- initialBook.IsFromSnapshot = true;
-
- callback(initialBook);
-
- initialSequenceIds[marketSymbol] = initialBook.SequenceId;
- }
+ var marketSymbolsForSubscriptionString = string.Join(",", marketSymbols);
var id = CryptoUtility.UtcNow.Ticks;
- var topic = $"/market/level2:{string.Join(",", marketSymbols)}";
+ var topic = $"/market/level2:{marketSymbolsForSubscriptionString}";
await _socket.SendMessageAsync(
new
{
diff --git a/src/ExchangeSharp/API/Exchanges/MEXC/ExchangeMEXCAPI.cs b/src/ExchangeSharp/API/Exchanges/MEXC/ExchangeMEXCAPI.cs
index c7f6280b..de30ec78 100644
--- a/src/ExchangeSharp/API/Exchanges/MEXC/ExchangeMEXCAPI.cs
+++ b/src/ExchangeSharp/API/Exchanges/MEXC/ExchangeMEXCAPI.cs
@@ -384,12 +384,28 @@ params string[] marketSymbols
var initialSequenceIds = new Dictionary<string, long>();
+ foreach (var marketSymbol in marketSymbols)
+ {
+ var initialBook = await OnGetOrderBookAsync(marketSymbol, maxCount);
+ initialBook.IsFromSnapshot = true;
+
+ callback(initialBook);
+
+ initialSequenceIds[marketSymbol] = initialBook.SequenceId;
+ }
+
return await ConnectPublicWebSocketAsync(
string.Empty,
(_socket, msg) =>
{
var json = msg.ToStringFromUTF8();
+ if (json.Contains("invalid") || json.Contains("Not Subscribed"))
+ {
+ Logger.Warn(json);
+ return Task.CompletedTask;
+ }
+
MarketDepthDiffUpdate update = null;
try
{
@@ -451,26 +467,15 @@ params string[] marketSymbols
},
async (_socket) =>
{
- foreach (var marketSymbol in marketSymbols) // "Every websocket connection maximum support 30 subscriptions at one time." - API docs
- {
- var initialBook = await OnGetOrderBookAsync(marketSymbol, maxCount);
- initialBook.IsFromSnapshot = true;
-
- callback(initialBook);
-
- initialSequenceIds[marketSymbol] = initialBook.SequenceId;
-
- var subscriptionParams = new List<string>
- {
- $"spot@public.increase.depth.v3.api@{marketSymbol}"
- };
+ var subscriptionParams = marketSymbols
+ .Select(ms => $"spot@public.increase.depth.v3.api@{ms}")
+ .ToList();
- await _socket.SendMessageAsync(new WebSocketSubscription
- {
- Method = "SUBSCRIPTION",
- Params = subscriptionParams,
- });
- }
+ await _socket.SendMessageAsync(new WebSocketSubscription
+ {
+ Method = "SUBSCRIPTION",
+ Params = subscriptionParams,
+ });
}
);
}
diff --git a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs
index 30606150..11016076 100644
--- a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs
+++ b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs
@@ -474,28 +474,48 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenArrays(
string sequence = "ts"
)
{
- var book = new ExchangeOrderBook
+ var book = new ExchangeOrderBook();
+
+ if (token == null)
{
- SequenceId = token[sequence].ConvertInvariant<long>()
- };
- foreach (var array in token[asks])
+ Logger.Warn($"Null token in {nameof(ParseOrderBookFromJTokenArrays)}");
+ return book;
+ }
+
+ book.SequenceId = token[sequence].ConvertInvariant<long>();
+
+ if (token[asks] != null)
{
- var depth = new ExchangeOrderPrice
+ foreach (var array in token[asks])
{
- Price = array[0].ConvertInvariant<decimal>(),
- Amount = array[1].ConvertInvariant<decimal>()
- };
- book.Asks[depth.Price] = depth;
+ var depth = new ExchangeOrderPrice
+ {
+ Price = array[0].ConvertInvariant<decimal>(),
+ Amount = array[1].ConvertInvariant<decimal>()
+ };
+ book.Asks[depth.Price] = depth;
+ }
+ }
+ else
+ {
+ Logger.Warn($"No asks in {nameof(ParseOrderBookFromJTokenArrays)}");
}
- foreach (var array in token[bids])
+ if (token[bids] != null)
{
- var depth = new ExchangeOrderPrice
+ foreach (var array in token[bids])
{
- Price = array[0].ConvertInvariant<decimal>(),
- Amount = array[1].ConvertInvariant<decimal>()
- };
- book.Bids[depth.Price] = depth;
+ var depth = new ExchangeOrderPrice
+ {
+ Price = array[0].ConvertInvariant<decimal>(),
+ Amount = array[1].ConvertInvariant<decimal>()
+ };
+ book.Bids[depth.Price] = depth;
+ }
+ }
+ else
+ {
+ Logger.Error($"No bids in {nameof(ParseOrderBookFromJTokenArrays)}");
}
return book;