1+ import { Network } from '../src/clients/constants' ;
2+ import { SocketClient } from '../src/clients/socket-client' ;
3+
4+ function test ( ) : void {
5+ let orderBookBidList : [ number , number , number ] [ ] = [ ] ;
6+ let orderBookAskList : [ number , number , number ] [ ] = [ ] ;
7+
8+ const mySocket = new SocketClient (
9+ Network . mainnet ( ) . indexerConfig ,
10+ ( ) => {
11+ console . log ( 'socket opened' ) ;
12+
13+ mySocket . subscribeToOrderbook ( 'ETH-USD' ) ;
14+ } ,
15+ ( ) => {
16+ console . log ( 'socket closed' ) ;
17+ } ,
18+ ( message ) => {
19+ try {
20+ if ( typeof message . data === "string" ) {
21+ const jsonString = message . data ;
22+ const parsingData = JSON . parse ( jsonString ) ;
23+ const messageId = parsingData . message_id ;
24+ const orderBookDataList = parsingData . contents ;
25+
26+ if ( orderBookDataList instanceof Array ) {
27+ // common orderBook data;
28+ [ orderBookBidList , orderBookAskList ] = updateOrderBook (
29+ orderBookDataList ,
30+ orderBookBidList ,
31+ orderBookAskList ,
32+ messageId ,
33+ ) ;
34+
35+ // sort
36+ orderBookBidList = sortByNthElementDesc (
37+ orderBookBidList ,
38+ 0 ,
39+ ) ;
40+ orderBookAskList = sortByNthElementAsc (
41+ orderBookAskList ,
42+ 0 ,
43+ ) ;
44+
45+ // resolving crossed orderBook
46+ if (
47+ orderBookBidList &&
48+ orderBookAskList &&
49+ orderBookBidList . length > 0 &&
50+ orderBookAskList . length > 0 &&
51+ orderBookBidList [ 0 ] [ 0 ] >= orderBookAskList [ 0 ] [ 0 ]
52+ ) {
53+ [ orderBookBidList , orderBookAskList ] =
54+ resolveCrossedOrderBook (
55+ orderBookBidList ,
56+ orderBookAskList ,
57+ ) ;
58+ }
59+
60+ printOrderBook ( orderBookBidList , orderBookAskList ) ;
61+
62+ if ( orderBookBidList . length > 300 ) {
63+ orderBookBidList . splice ( 50 ) ;
64+ }
65+
66+ if ( orderBookAskList . length > 300 ) {
67+ orderBookAskList . splice ( 50 ) ;
68+ }
69+ } else if (
70+ orderBookDataList !== null &&
71+ orderBookDataList !== undefined
72+ ) {
73+ // initial OrderBook data
74+ setInitialOrderBook (
75+ orderBookDataList ,
76+ orderBookBidList ,
77+ orderBookAskList ,
78+ messageId ,
79+ ) ;
80+ }
81+ }
82+ } catch ( e ) {
83+ console . error ( 'Error parsing JSON message:' , e ) ;
84+ }
85+ } ,
86+ ( event ) => {
87+ console . error ( 'Encountered error:' , event . message ) ;
88+ } ,
89+ ) ;
90+
91+ mySocket . connect ( ) ;
92+ }
93+
94+ const sortByNthElementAsc = ( arr : [ number , number , number ] [ ] , n : number ) : [ number , number , number ] [ ] => {
95+ return arr . sort ( ( a , b ) => {
96+ if ( a [ n ] < b [ n ] ) return - 1 ;
97+ if ( a [ n ] > b [ n ] ) return 1 ;
98+ return 0 ;
99+ } ) ;
100+ } ;
101+ const sortByNthElementDesc = ( arr : [ number , number , number ] [ ] , n : number ) : [ number , number , number ] [ ] => {
102+ return arr . sort ( ( a , b ) => {
103+ if ( a [ n ] > b [ n ] ) return - 1 ;
104+ if ( a [ n ] < b [ n ] ) return 1 ;
105+ return 0 ;
106+ } ) ;
107+ } ;
108+
109+ const printOrderBook = (
110+ orderBookBidList : [ number , number , number ] [ ] ,
111+ orderBookAskList : [ number , number , number ] [ ] ,
112+ ) : void => {
113+ // print
114+ console . log ( `OrderBook for ETH-USD:` ) ;
115+ console . log ( `Price Qty` ) ;
116+ for ( let i = 4 ; i > - 1 ; i -- ) {
117+ const priceStr = String ( orderBookAskList [ i ] [ 0 ] ) ;
118+ const spaces = createSpaces ( 10 - priceStr . length ) ;
119+ console . log ( `${ priceStr } ${ spaces } ${ orderBookAskList [ i ] [ 1 ] } ` ) ;
120+ }
121+ console . log ( '---------------------' ) ;
122+ for ( let i = 0 ; i < 5 ; i ++ ) {
123+ const priceStr = String ( orderBookBidList [ i ] [ 0 ] ) ;
124+ const spaces = createSpaces ( 10 - priceStr . length ) ;
125+ console . log ( `${ priceStr } ${ spaces } ${ orderBookBidList [ i ] [ 1 ] } ` ) ;
126+ }
127+ console . log ( '' ) ;
128+ } ;
129+
130+ function createSpaces ( count : number ) : string {
131+ if ( count <= 0 ) {
132+ return "" ;
133+ }
134+
135+ let spaces = "" ;
136+ for ( let i = 0 ; i < count ; i ++ ) {
137+ spaces += " " ;
138+ }
139+ return spaces ;
140+ }
141+
142+ const resolveCrossedOrderBook = (
143+ orderBookBidList : [ number , number , number ] [ ] ,
144+ orderBookAskList : [ number , number , number ] [ ] ,
145+ ) : [ [ number , number , number ] [ ] , [ number , number , number ] [ ] ] => {
146+ while ( orderBookBidList [ 0 ] [ 0 ] >= orderBookAskList [ 0 ] [ 0 ] ) {
147+ if ( orderBookBidList [ 0 ] [ 2 ] < orderBookAskList [ 0 ] [ 2 ] ) {
148+ orderBookBidList . shift ( ) ;
149+ } else if ( orderBookBidList [ 0 ] [ 2 ] > orderBookAskList [ 0 ] [ 2 ] ) {
150+ orderBookAskList . shift ( ) ;
151+ } else {
152+ if ( orderBookBidList [ 0 ] [ 1 ] > orderBookAskList [ 0 ] [ 1 ] ) {
153+ orderBookBidList [ 0 ] [ 1 ] -= orderBookAskList [ 0 ] [ 1 ] ;
154+ orderBookAskList . shift ( ) ;
155+ } else if ( orderBookBidList [ 0 ] [ 1 ] < orderBookAskList [ 0 ] [ 1 ] ) {
156+ orderBookAskList [ 0 ] [ 1 ] -= orderBookBidList [ 0 ] [ 1 ] ;
157+ orderBookBidList . shift ( ) ;
158+ } else {
159+ orderBookAskList . shift ( ) ;
160+ orderBookBidList . shift ( ) ;
161+ }
162+ }
163+ }
164+
165+ return [ orderBookBidList , orderBookAskList ] ;
166+ } ;
167+ const setInitialOrderBook = (
168+ orderBookDataList : { bids : [ ] ; asks : [ ] } ,
169+ orderBookBidList : [ number , number , number ] [ ] ,
170+ orderBookAskList : [ number , number , number ] [ ] ,
171+ messageId : number ,
172+ ) : void => {
173+ orderBookDataList . bids . forEach ( ( item : { price : string ; size : string } ) => {
174+ orderBookBidList . push ( [ Number ( item . price ) , Number ( item . size ) , messageId ] ) ;
175+ } ) ;
176+
177+ orderBookDataList . asks . forEach ( ( item : { price : string ; size : string } ) => {
178+ orderBookAskList . push ( [ Number ( item . price ) , Number ( item . size ) , messageId ] ) ;
179+ } ) ;
180+ } ;
181+
182+ const updateOrderBook = (
183+ orderBookDataList : { bids : [ [ ] ] ; asks : [ [ ] ] } [ ] ,
184+ orderBookBidList : [ number , number , number ] [ ] ,
185+ orderBookAskList : [ number , number , number ] [ ] ,
186+ messageId : number ,
187+ ) : [ [ number , number , number ] [ ] , [ number , number , number ] [ ] ] => {
188+ orderBookDataList . forEach ( ( entry : { bids : [ [ ] ] ; asks : [ [ ] ] } ) => {
189+ if ( entry . bids !== null && entry . bids !== undefined ) {
190+ const flattened = entry . bids . reduce ( ( acc : any [ ] , val : any [ ] ) => acc . concat ( val ) , [ ] ) ;
191+ const entryBidPrice = Number ( flattened [ 0 ] ) ;
192+ const entryBidSize = Number ( flattened [ 1 ] ) ;
193+
194+ // remove prices with zero Qty
195+ if ( entryBidSize === 0 ) {
196+ for ( let i = orderBookBidList . length - 1 ; i >= 0 ; i -- ) {
197+ if ( orderBookBidList [ i ] [ 0 ] === entryBidPrice ) {
198+ orderBookBidList . splice ( i , 1 ) ;
199+ }
200+ }
201+ } else {
202+ // The price that already exists in the order book is modified only Qty
203+ if (
204+ orderBookBidList . some ( ( innerArray ) => innerArray [ 0 ] === entryBidPrice )
205+ ) {
206+ orderBookBidList . forEach ( ( item , index ) => {
207+ if ( item [ 0 ] === entryBidPrice ) {
208+ orderBookBidList [ index ] [ 1 ] = entryBidSize ;
209+ orderBookBidList [ index ] [ 2 ] = messageId ;
210+ }
211+ } ) ;
212+ } else {
213+ // Add new data to order book
214+ orderBookBidList . push ( [ entryBidPrice , entryBidSize , messageId ] ) ;
215+ }
216+ }
217+ }
218+ if ( entry . asks !== null && entry . asks !== undefined ) {
219+ const flattened = entry . asks . reduce ( ( acc : any [ ] , val : any [ ] ) => acc . concat ( val ) , [ ] ) ;
220+ const entryAskPrice = Number ( flattened [ 0 ] ) ;
221+ const entryAskSize = Number ( flattened [ 1 ] ) ;
222+
223+ if ( entryAskSize === 0 ) {
224+ // remove prices with zero Qty
225+ for ( let i = orderBookAskList . length - 1 ; i >= 0 ; i -- ) {
226+ if ( orderBookAskList [ i ] [ 0 ] === entryAskPrice ) {
227+ orderBookAskList . splice ( i , 1 ) ;
228+ }
229+ }
230+ } else {
231+ // The price that already exists in the order book is modified only Qty
232+ if (
233+ orderBookAskList . some ( ( innerArray ) => innerArray [ 0 ] === entryAskPrice )
234+ ) {
235+ orderBookAskList . forEach ( ( item , index ) => {
236+ if ( item [ 0 ] === entryAskPrice ) {
237+ orderBookAskList [ index ] [ 1 ] = entryAskSize ;
238+ orderBookAskList [ index ] [ 2 ] = messageId ;
239+ }
240+ } ) ;
241+ } else {
242+ // Add new data to order book
243+ orderBookAskList . push ( [ entryAskPrice , entryAskSize , messageId ] ) ;
244+ }
245+ }
246+ }
247+ } ) ;
248+
249+ return [ orderBookBidList , orderBookAskList ] ;
250+ } ;
251+
252+ test ( ) ;
0 commit comments