Skip to content

Commit 54ae638

Browse files
committed
Gemini delta order book web socket
1 parent 24f6ed8 commit 54ae638

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,66 @@ await _socket.SendMessageAsync(new
593593
});
594594
}
595595

596+
protected override async Task<IWebSocket> OnGetDeltaOrderBookWebSocketAsync(Action<ExchangeOrderBook> callback, int maxCount = 20, params string[] marketSymbols)
597+
{
598+
if (marketSymbols == null || marketSymbols.Length == 0)
599+
{
600+
marketSymbols = (await GetMarketSymbolsAsync()).ToArray();
601+
}
602+
ConcurrentDictionary<string, ExchangeOrderBook> books = new ConcurrentDictionary<string, ExchangeOrderBook>(StringComparer.OrdinalIgnoreCase);
603+
return await ConnectWebSocketAsync(BaseUrlWebSocket, (_socket, msg) =>
604+
{
605+
JToken token = JToken.Parse(msg.ToStringFromUTF8());
606+
if (token["type"].ToStringInvariant() == "l2_updates")
607+
{
608+
string marketSymbol = token["symbol"].ToStringInvariant();
609+
ExchangeOrderBook bookObj = books.GetOrAdd(marketSymbol, _marketSymbol =>
610+
{
611+
return new ExchangeOrderBook { MarketSymbol = _marketSymbol };
612+
});
613+
if (token["changes"] is JArray book)
614+
{
615+
foreach (JArray item in book)
616+
{
617+
if (item.Count == 3)
618+
{
619+
bool sell = item[0].ToStringInvariant() == "sell";
620+
SortedDictionary<decimal, ExchangeOrderPrice> dict = (sell ? bookObj.Bids : bookObj.Asks);
621+
decimal price = item[1].ConvertInvariant<decimal>();
622+
decimal amount = item[2].ConvertInvariant<decimal>();
623+
if (amount == 0m)
624+
{
625+
dict.Remove(price);
626+
}
627+
else
628+
{
629+
var depth = new ExchangeOrderPrice { Price = price, Amount = amount };
630+
dict[price] = depth;
631+
}
632+
}
633+
}
634+
callback(bookObj);
635+
}
636+
}
637+
return Task.CompletedTask;
638+
}, connectCallback: async (_socket) =>
639+
{
640+
//{ "type": "subscribe","subscriptions":[{ "name":"l2","symbols":["BTCUSD","ETHUSD","ETHBTC"]}]}
641+
await _socket.SendMessageAsync(new
642+
{
643+
type = "subscribe",
644+
subscriptions = new[]
645+
{
646+
new
647+
{
648+
name = "l2",
649+
symbols = marketSymbols
650+
}
651+
}
652+
});
653+
});
654+
}
655+
596656
private static ExchangeTrade ParseWebSocketTrade(JToken token) => token.ParseTrade(
597657
amountKey: "quantity", priceKey: "price",
598658
typeKey: "side", timestampKey: "timestamp",

src/ExchangeSharp/Model/ExchangeOrderBook.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
MIT LICENSE
33
44
Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
@@ -98,7 +98,11 @@ public sealed class ExchangeOrderBook
9898
/// <returns>String</returns>
9999
public override string ToString()
100100
{
101-
return string.Format("Asks: {0}, Bids: {1}", Asks.Count, Bids.Count);
101+
return string.Format("Book {0}, Asks: {1} ({2:0.00}), Bids: {3} ({4:0.00})", MarketSymbol,
102+
Asks.Count,
103+
Asks.Values.Sum(a => a.Amount * a.Price),
104+
Bids.Count,
105+
Bids.Values.Sum(b => b.Amount * b.Price));
102106
}
103107

104108
/// <summary>

0 commit comments

Comments
 (0)