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 ] [ ] = [ ] ;
6+ let orderBookAskList : [ 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 orderBookDataList = JSON . parse ( jsonString ) . contents ;
23+
24+ if ( orderBookDataList instanceof Array ) {
25+ // common orderBook data;
26+ [ orderBookBidList , orderBookAskList ] = updateOrderBook (
27+ orderBookDataList ,
28+ orderBookBidList ,
29+ orderBookAskList ,
30+ ) ;
31+
32+ // sort
33+ orderBookBidList = sortByNthElementDesc ( orderBookBidList , 0 ) ;
34+ orderBookAskList = sortByNthElementAsc ( orderBookAskList , 0 ) ;
35+
36+ // resolving crossed orderBook
37+ [ orderBookBidList , orderBookAskList ] = resolveCrossedOrderBook (
38+ orderBookBidList ,
39+ orderBookAskList ,
40+ ) ;
41+
42+ printOrderBook ( orderBookBidList , orderBookAskList ) ;
43+ } else if ( orderBookDataList !== null && orderBookDataList !== undefined ) {
44+ // initial OrderBook data
45+ setInitialOrderBook ( orderBookDataList , orderBookBidList , orderBookAskList ) ;
46+ }
47+ }
48+ } catch ( e ) {
49+ console . error ( 'Error parsing JSON message:' , e ) ;
50+ }
51+ } ,
52+ ( event ) => {
53+ console . error ( 'Encountered error:' , event . message ) ;
54+ } ,
55+ ) ;
56+ mySocket . connect ( ) ;
57+ }
58+
59+ const sortByNthElementAsc = ( arr : [ number , number ] [ ] , n : number ) : [ number , number ] [ ] => {
60+ return arr . sort ( ( a , b ) => {
61+ if ( a [ n ] < b [ n ] ) return - 1 ;
62+ if ( a [ n ] > b [ n ] ) return 1 ;
63+ return 0 ;
64+ } ) ;
65+ } ;
66+ const sortByNthElementDesc = ( arr : [ number , number ] [ ] , n : number ) : [ number , number ] [ ] => {
67+ return arr . sort ( ( a , b ) => {
68+ if ( a [ n ] > b [ n ] ) return - 1 ;
69+ if ( a [ n ] < b [ n ] ) return 1 ;
70+ return 0 ;
71+ } ) ;
72+ } ;
73+
74+ const printOrderBook = (
75+ orderBookBidList : [ number , number ] [ ] ,
76+ orderBookAskList : [ number , number ] [ ] ,
77+ ) : void => {
78+ // print
79+ console . log ( `OrderBook for ETH-USD:` ) ;
80+ console . log ( `Price Qty` ) ;
81+ for ( let i = 4 ; i > - 1 ; i -- ) {
82+ console . log ( `${ String ( orderBookAskList [ i ] [ 0 ] ) . padEnd ( 10 , ' ' ) } ${ orderBookAskList [ i ] [ 1 ] } ` ) ;
83+ }
84+ console . log ( '---------------------' ) ;
85+ for ( let i = 0 ; i < 5 ; i ++ ) {
86+ console . log ( `${ String ( orderBookBidList [ i ] [ 0 ] ) . padEnd ( 10 , ' ' ) } ${ orderBookBidList [ i ] [ 1 ] } ` ) ;
87+ }
88+ console . log ( '' ) ;
89+ } ;
90+
91+ const resolveCrossedOrderBook = (
92+ orderBookBidList : [ number , number ] [ ] ,
93+ orderBookAskList : [ number , number ] [ ] ,
94+ ) : [ [ number , number ] [ ] , [ number , number ] [ ] ] => {
95+ const bidList = [ ...orderBookBidList ] ;
96+ const askList = [ ...orderBookAskList ] ;
97+
98+ while ( bidList [ 0 ] [ 0 ] >= askList [ 0 ] [ 0 ] ) {
99+ if ( bidList [ 0 ] [ 1 ] > askList [ 0 ] [ 1 ] ) {
100+ bidList [ 0 ] [ 1 ] -= askList [ 0 ] [ 1 ] ;
101+ askList . shift ( ) ;
102+ } else if ( bidList [ 0 ] [ 1 ] < askList [ 0 ] [ 1 ] ) {
103+ askList [ 0 ] [ 1 ] -= bidList [ 0 ] [ 1 ] ;
104+ bidList . shift ( ) ;
105+ } else {
106+ askList . shift ( ) ;
107+ bidList . shift ( ) ;
108+ }
109+ }
110+
111+ return [ bidList , askList ] ;
112+ } ;
113+
114+ const setInitialOrderBook = (
115+ orderBookDataList : { bids : [ ] ; asks : [ ] } ,
116+ orderBookBidList : [ number , number ] [ ] ,
117+ orderBookAskList : [ number , number ] [ ] ,
118+ ) : void => {
119+ orderBookDataList . bids . forEach ( ( item : { price : string ; size : string } ) => {
120+ orderBookBidList . push ( [ Number ( item . price ) , Number ( item . size ) ] ) ;
121+ } ) ;
122+
123+ orderBookDataList . asks . forEach ( ( item : { price : string ; size : string } ) => {
124+ orderBookAskList . push ( [ Number ( item . price ) , Number ( item . size ) ] ) ;
125+ } ) ;
126+ } ;
127+
128+ const updateOrderBook = (
129+ orderBookDataList : { bids : [ [ ] ] ; asks : [ [ ] ] } [ ] ,
130+ orderBookBidList : [ number , number ] [ ] ,
131+ orderBookAskList : [ number , number ] [ ] ,
132+ ) : [ [ number , number ] [ ] , [ number , number ] [ ] ] => {
133+ let bidList = [ ...orderBookBidList ] ;
134+ let askList = [ ...orderBookAskList ] ;
135+
136+ orderBookDataList . forEach ( ( entry : { bids : [ [ ] ] ; asks : [ [ ] ] } ) => {
137+ if ( entry . bids !== null && entry . bids !== undefined ) {
138+ const entryBidPrice = Number ( entry . bids . flat ( ) [ 0 ] ) ;
139+ const entryBidSize = Number ( entry . bids . flat ( ) [ 1 ] ) ;
140+
141+ // remove prices with zero Qty
142+ if ( entryBidSize === 0 ) {
143+ bidList . forEach ( ( item , index ) => {
144+ if ( item [ 0 ] === entryBidPrice ) {
145+ bidList . splice ( index , 1 ) ;
146+ }
147+ } ) ;
148+ } else {
149+ // The price that already exists in the order book is modified only Qty
150+ if ( bidList . some ( ( innerArray ) => innerArray [ 0 ] === entryBidPrice ) ) {
151+ bidList = bidList . map ( ( item , index ) => {
152+ if ( item [ 0 ] === entryBidPrice ) {
153+ bidList [ index ] [ 1 ] = entryBidSize ;
154+ return item ;
155+ } else {
156+ return item ;
157+ }
158+ } ) ;
159+ } else {
160+ // Add new data to order book
161+ bidList . push ( [ entryBidPrice , entryBidSize ] ) ;
162+ }
163+ }
164+ }
165+ if ( entry . asks !== null && entry . asks !== undefined ) {
166+ const entryAskPrice = Number ( entry . asks . flat ( ) [ 0 ] ) ;
167+ const entryAskSize = Number ( entry . asks . flat ( ) [ 1 ] ) ;
168+
169+ if ( entryAskSize === 0 ) {
170+ // remove prices with zero Qty
171+ askList . forEach ( ( item , index ) => {
172+ if ( item [ 0 ] === entryAskPrice ) {
173+ askList . splice ( index , 1 ) ;
174+ }
175+ } ) ;
176+ } else {
177+ // The price that already exists in the order book is modified only Qty
178+ if ( askList . some ( ( innerArray ) => innerArray [ 0 ] === entryAskPrice ) ) {
179+ askList = askList . map ( ( item , index ) => {
180+ if ( item [ 0 ] === entryAskPrice ) {
181+ askList [ index ] [ 1 ] = entryAskSize ;
182+ return item ;
183+ } else {
184+ return item ;
185+ }
186+ } ) ;
187+ } else {
188+ // Add new data to order book
189+ askList . push ( [ entryAskPrice , entryAskSize ] ) ;
190+ }
191+ }
192+ }
193+ } ) ;
194+
195+ return [ orderBookBidList , orderBookAskList ] ;
196+ } ;
197+
198+ test ( ) ;
0 commit comments