11const moment = require ( "moment" ) ;
22const BasicClient = require ( "../basic-client" ) ;
33const Trade = require ( "../trade" ) ;
4+ const Level2Point = require ( "../level2-point" ) ;
5+ const Level2Snapshot = require ( "../level2-snapshot" ) ;
46const Level3Point = require ( "../level3-point" ) ;
57const Level3Snapshot = require ( "../level3-snapshot" ) ;
68const Level3Update = require ( "../level3-update" ) ;
@@ -19,13 +21,16 @@ class ErisXClient extends BasicClient {
1921 watcherMs = 600000 ,
2022 apiKey,
2123 apiSecret,
24+ l2depth = 20 ,
2225 } = { } ) {
2326 super ( wssPath , "ErisX" , undefined , watcherMs ) ;
2427
2528 this . apiKey = apiKey ;
2629 this . apiSecret = apiSecret ;
2730 this . hasTrades = true ;
31+ this . hasLevel2Snapshots = true ;
2832 this . hasLevel3Updates = true ;
33+ this . l2depth = l2depth ;
2934 this . _messageId = 0 ;
3035 }
3136
@@ -87,6 +92,28 @@ class ErisXClient extends BasicClient {
8792 ) ;
8893 }
8994
95+ _sendSubLevel2Snapshots ( remote_id ) {
96+ this . _wss . send (
97+ JSON . stringify ( {
98+ correlation : this . _nextId ( ) ,
99+ type : "TopOfBookMarketDataSubscribe" ,
100+ symbol : remote_id ,
101+ topOfBookDepth : this . l2depth ,
102+ } )
103+ ) ;
104+ }
105+
106+ _sendUnsubLevel2Snapshots ( remote_id ) {
107+ this . _wss . send (
108+ JSON . stringify ( {
109+ correlation : this . _nextId ( ) ,
110+ type : "TopOfBookMarketDataUnsubscribe" ,
111+ symbol : remote_id ,
112+ topOfBookDepth : this . l2depth ,
113+ } )
114+ ) ;
115+ }
116+
90117 _sendSubLevel3Updates ( remote_id ) {
91118 this . _wss . send (
92119 JSON . stringify ( {
@@ -155,6 +182,16 @@ class ErisXClient extends BasicClient {
155182 return ;
156183 }
157184
185+ // l2 snapshot
186+ if ( msg . type === "TopOfBookMarketData" ) {
187+ let market = this . _level2SnapshotSubs . get ( msg . symbol ) ;
188+ if ( ! market ) return ;
189+
190+ const snapshot = this . _constructLevel2Snapshot ( msg , market ) ;
191+ this . emit ( "l2snapshot" , snapshot , market ) ;
192+ return ;
193+ }
194+
158195 // l3
159196 if ( msg . type === "MarketDataIncrementalRefresh" ) {
160197 let market = this . _level3UpdateSubs . get ( msg . symbol ) ;
@@ -227,6 +264,65 @@ class ErisXClient extends BasicClient {
227264 } ) ;
228265 }
229266
267+ /**
268+ {
269+ "correlation": "15978412650812",
270+ "type": "TopOfBookMarketData",
271+ "bids": [
272+ {
273+ "action": "NEW",
274+ "count": 1,
275+ "totalVolume": 1.0,
276+ "price": 413.2,
277+ "lastUpdate": "20200819-12:47:49.975"
278+ },
279+ {
280+ "action": "UPDATE",
281+ "count": 2,
282+ "totalVolume": 2.00,
283+ "price": 412.9,
284+ "lastUpdate": "20200819-12:47:39.984"
285+ }
286+ ],
287+ "offers": [
288+ {
289+ "action": "NO CHANGE",
290+ "count": 1,
291+ "totalVolume": 1.00,
292+ "price": 413.3,
293+ "lastUpdate": "20200819-12:47:40.166"
294+ },
295+ {
296+ "action": "NO CHANGE",
297+ "count": 1,
298+ "totalVolume": 1.56,
299+ "price": 413.4,
300+ "lastUpdate": "20200819-12:47:20.196"
301+ }
302+ ],
303+ "symbol": "ETH/USD"
304+ }
305+ */
306+ _constructLevel2Snapshot ( msg , market ) {
307+ const map = p =>
308+ new Level2Point (
309+ p . price . toFixed ( 8 ) ,
310+ p . totalVolume . toFixed ( 8 ) ,
311+ p . count ,
312+ undefined ,
313+ moment . utc ( p . lastUpdate , "YYYYMMDD-hh:mm:ss.SSSSSSSSS" ) . valueOf ( )
314+ ) ;
315+ const bids = msg . bids . map ( map ) ;
316+ const asks = msg . offers . map ( map ) ;
317+ return new Level2Snapshot ( {
318+ exchange : this . _name ,
319+ base : market . base ,
320+ quote : market . quote ,
321+ asks,
322+ bids,
323+ } ) ;
324+ }
325+
230326 /**
231327 {
232328 "correlation": "4",
0 commit comments