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