Skip to content

Commit 6f249be

Browse files
authored
Fix Kraken WS orderbook updates and add checksum support (#626)
1 parent b96452d commit 6f249be

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,15 @@ private async Task<List<string>> GetMarketSymbolList(string[] marketSymbols)
11421142
return marketSymbolList;
11431143
}
11441144

1145+
/// <summary>
1146+
/// Handle Kraken "book" channel message: https://docs.kraken.com/websockets/#message-book
1147+
/// Note in the "update payload" case there may be varying number of update blocks for
1148+
/// bid/ask updates. The last such block has a checksum. The market symbol is always the last item.
1149+
/// </summary>
1150+
/// <param name="callback"></param>
1151+
/// <param name="maxCount"></param>
1152+
/// <param name="marketSymbols"></param>
1153+
/// <returns></returns>
11451154
protected override async Task<IWebSocket> OnGetDeltaOrderBookWebSocketAsync(
11461155
Action<ExchangeOrderBook> callback,
11471156
int maxCount = 20,
@@ -1158,15 +1167,16 @@ params string[] marketSymbols
11581167
string message = msg.ToStringFromUTF8();
11591168
var book = new ExchangeOrderBook();
11601169

1170+
// SNAPSHOT payload
11611171
if (message.Contains("\"as\"") || message.Contains("\"bs\""))
11621172
{
11631173
// parse delta update
1164-
var delta = JsonConvert.DeserializeObject(message) as JArray;
1174+
var snapshot = JsonConvert.DeserializeObject(message) as JArray;
11651175

1166-
book.MarketSymbol = delta[3].ToString();
1176+
book.MarketSymbol = snapshot[3].ToString();
11671177

1168-
var asks = delta[1]["as"].ToList();
1169-
var bids = delta[1]["bs"].ToList();
1178+
var asks = snapshot[1]["as"].ToList();
1179+
var bids = snapshot[1]["bs"].ToList();
11701180

11711181
var lastUpdatedTime = DateTime.MinValue;
11721182

@@ -1205,16 +1215,16 @@ params string[] marketSymbols
12051215
{
12061216
// parse delta update
12071217
var delta = JsonConvert.DeserializeObject(message) as JArray;
1218+
book.MarketSymbol = delta.Last.ToString();
12081219

1209-
book.MarketSymbol = delta[3].ToString();
1220+
var _a = delta.FirstOrDefault(token => token is JObject && token["a"] != null);
1221+
var _b = delta.FirstOrDefault(token => token is JObject && token["b"] != null);
12101222

12111223
var lastUpdatedTime = DateTime.MinValue;
12121224

1213-
var updates = delta[1];
1214-
1215-
if (updates["a"] != null)
1225+
if (_a != null)
12161226
{
1217-
var asks = updates["a"].ToList();
1227+
var asks = _a["a"].ToList();
12181228

12191229
foreach (var ask in asks)
12201230
{
@@ -1230,9 +1240,9 @@ params string[] marketSymbols
12301240
}
12311241
}
12321242

1233-
if (updates["b"] != null)
1243+
if (_b != null)
12341244
{
1235-
var bids = updates["b"].ToList();
1245+
var bids = _b["b"].ToList();
12361246

12371247
foreach (var bid in bids)
12381248
{
@@ -1251,6 +1261,11 @@ params string[] marketSymbols
12511261
book.LastUpdatedUtc = lastUpdatedTime;
12521262
book.SequenceId = lastUpdatedTime.Ticks;
12531263

1264+
//https://docs.kraken.com/websockets/#book-checksum
1265+
//"c" belongs to the last update block
1266+
var checksum = _b?["c"] ?? _a?["c"];
1267+
book.Checksum = (checksum as JValue)?.ToString();
1268+
12541269
callback(book);
12551270
}
12561271

src/ExchangeSharp/Model/ExchangeOrderBook.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,17 @@ public sealed class ExchangeOrderBook
9393
public SortedDictionary<decimal, ExchangeOrderPrice> Bids { get; } = new SortedDictionary<decimal, ExchangeOrderPrice>(new DescendingComparer<decimal>());
9494

9595
/// <summary>
96-
/// ToString
97-
/// </summary>
98-
/// <returns>String</returns>
99-
public override string ToString()
96+
/// If provided by the exchange, a checksum value that may be used to check orderbook integrity.
97+
/// Otherwise it will be null.
98+
/// This property is not serialized using the ToBinary and FromBinary methods.
99+
/// </summary>
100+
public string Checksum { get; set; }
101+
102+
/// <summary>
103+
/// ToString
104+
/// </summary>
105+
/// <returns>String</returns>
106+
public override string ToString()
100107
{
101108
return string.Format("Book {0}, Asks: {1} ({2:0.00}), Bids: {3} ({4:0.00})", MarketSymbol,
102109
Asks.Count,

0 commit comments

Comments
 (0)