@dydxprotocol/v4-client-js 1.17.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,252 @@
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dydxprotocol/v4-client-js",
3
- "version": "1.17.0",
3
+ "version": "1.18.0",
4
4
  "description": "General client library for the new dYdX system (v4 decentralized)",
5
5
  "main": "build/src/index.js",
6
6
  "scripts": {