Skip to content

Commit bd49299

Browse files
committed
feat: add orderdbook example using websocket
1 parent ddb5237 commit bd49299

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
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

Comments
 (0)