Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 252 additions & 0 deletions v4-client-js/examples/websocket_orderbook_example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
import { Network } from '../src/clients/constants';
import { SocketClient } from '../src/clients/socket-client';

function test(): void {
let orderBookBidList: [number, number, number][] = [];
let orderBookAskList: [number, number, number][] = [];

const mySocket = new SocketClient(
Network.mainnet().indexerConfig,
() => {
console.log('socket opened');

mySocket.subscribeToOrderbook('ETH-USD');
},
() => {
console.log('socket closed');
},
(message) => {
try {
if (typeof message.data === "string") {
const jsonString = message.data;
const parsingData = JSON.parse(jsonString);
const messageId = parsingData.message_id;
const orderBookDataList = parsingData.contents;

if (orderBookDataList instanceof Array) {
// common orderBook data;
[orderBookBidList, orderBookAskList] = updateOrderBook(
orderBookDataList,
orderBookBidList,
orderBookAskList,
messageId,
);

// sort
orderBookBidList = sortByNthElementDesc(
orderBookBidList,
0,
);
orderBookAskList = sortByNthElementAsc(
orderBookAskList,
0,
);

// resolving crossed orderBook
if (
orderBookBidList &&

Check failure on line 47 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected object value in conditional. The condition is always true
orderBookAskList &&

Check failure on line 48 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected object value in conditional. The condition is always true
orderBookBidList.length > 0 &&
orderBookAskList.length > 0 &&
orderBookBidList[0][0] >= orderBookAskList[0][0]
) {
[orderBookBidList, orderBookAskList] =
resolveCrossedOrderBook(
orderBookBidList,
orderBookAskList,
);
}

printOrderBook(orderBookBidList, orderBookAskList);

if (orderBookBidList.length > 300) {
orderBookBidList.splice(50);
}

if (orderBookAskList.length > 300) {
orderBookAskList.splice(50);
}
} else if (
orderBookDataList !== null &&
orderBookDataList !== undefined
) {
// initial OrderBook data
setInitialOrderBook(
orderBookDataList,
orderBookBidList,
orderBookAskList,
messageId,
);
}
}
} catch (e) {
console.error('Error parsing JSON message:', e);
}
},
(event) => {
console.error('Encountered error:', event.message);
},
);

mySocket.connect();
}

const sortByNthElementAsc = (arr: [number, number, number][], n: number): [number, number, number][] => {
return arr.sort((a, b) => {
if (a[n] < b[n]) return -1;
if (a[n] > b[n]) return 1;
return 0;
});
};
const sortByNthElementDesc = (arr: [number, number, number][], n: number): [number, number, number][] => {
return arr.sort((a, b) => {
if (a[n] > b[n]) return -1;
if (a[n] < b[n]) return 1;
return 0;
});
};

const printOrderBook = (
orderBookBidList: [number, number, number][],
orderBookAskList: [number, number, number][],
): void => {
// print
console.log(`OrderBook for ETH-USD:`);
console.log(`Price Qty`);
for (let i = 4; i > -1; i--) {
const priceStr = String(orderBookAskList[i][0]);
const spaces = createSpaces(10 - priceStr.length);
console.log(`${priceStr}${spaces}${orderBookAskList[i][1]}`);
}
console.log('---------------------');
for (let i = 0; i < 5; i++) {
const priceStr = String(orderBookBidList[i][0]);
const spaces = createSpaces(10 - priceStr.length);
console.log(`${priceStr}${spaces}${orderBookBidList[i][1]}`);
}
console.log('');
};

function createSpaces(count: number): string {
if(count <= 0 ){
return "";
}

let spaces = "";
for (let i = 0; i < count; i++) {
spaces += " ";
}
return spaces;
}

const resolveCrossedOrderBook = (
orderBookBidList: [number, number, number][],
orderBookAskList: [number, number, number][],
): [[number, number, number][], [number, number, number][]] => {
while (orderBookBidList[0][0] >= orderBookAskList[0][0]) {
if (orderBookBidList[0][2] < orderBookAskList[0][2]) {
orderBookBidList.shift();
} else if (orderBookBidList[0][2] > orderBookAskList[0][2]) {
orderBookAskList.shift();
} else {
if (orderBookBidList[0][1] > orderBookAskList[0][1]) {
orderBookBidList[0][1] -= orderBookAskList[0][1];

Check failure on line 153 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Assignment to property of function parameter 'orderBookBidList'
orderBookAskList.shift();
} else if (orderBookBidList[0][1] < orderBookAskList[0][1]) {
orderBookAskList[0][1] -= orderBookBidList[0][1];

Check failure on line 156 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Assignment to property of function parameter 'orderBookAskList'
orderBookBidList.shift();
} else {
orderBookAskList.shift();
orderBookBidList.shift();
}
}
}

return [orderBookBidList, orderBookAskList];
};
const setInitialOrderBook = (
orderBookDataList: { bids: []; asks: [] },
orderBookBidList: [number, number, number][],
orderBookAskList: [number, number, number][],
messageId: number,
): void => {
orderBookDataList.bids.forEach((item: { price: string; size: string }) => {
orderBookBidList.push([Number(item.price), Number(item.size), messageId]);
});

orderBookDataList.asks.forEach((item: { price: string; size: string }) => {
orderBookAskList.push([Number(item.price), Number(item.size), messageId]);
});
};

const updateOrderBook = (
orderBookDataList: { bids: [[]]; asks: [[]] }[],
orderBookBidList: [number, number, number][],
orderBookAskList: [number, number, number][],
messageId: number,
): [[number, number, number][], [number, number, number][]] => {
orderBookDataList.forEach((entry: { bids: [[]]; asks: [[]] }) => {
if (entry.bids !== null && entry.bids !== undefined) {
const flattened = entry.bids.reduce((acc: any[], val: any[]) => acc.concat(val), []);

Check failure on line 190 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected any. Specify a different type

Check failure on line 190 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected any. Specify a different type
const entryBidPrice = Number(flattened[0]);
const entryBidSize = Number(flattened[1]);

// remove prices with zero Qty
if (entryBidSize === 0) {
for (let i = orderBookBidList.length - 1; i >= 0; i--) {
if (orderBookBidList[i][0] === entryBidPrice) {
orderBookBidList.splice(i, 1);
}
}
} else {
// The price that already exists in the order book is modified only Qty
if (
orderBookBidList.some((innerArray) => innerArray[0] === entryBidPrice)
) {
orderBookBidList.forEach((item, index) => {
if (item[0] === entryBidPrice) {
orderBookBidList[index][1] = entryBidSize;

Check failure on line 208 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Assignment to property of function parameter 'orderBookBidList'
orderBookBidList[index][2] = messageId;

Check failure on line 209 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Assignment to property of function parameter 'orderBookBidList'
}
});
} else {
// Add new data to order book
orderBookBidList.push([entryBidPrice, entryBidSize, messageId]);
}
}
}
if (entry.asks !== null && entry.asks !== undefined) {
const flattened = entry.asks.reduce((acc: any[], val: any[]) => acc.concat(val), []);

Check failure on line 219 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected any. Specify a different type

Check failure on line 219 in v4-client-js/examples/websocket_orderbook_example.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected any. Specify a different type
const entryAskPrice = Number(flattened[0]);
const entryAskSize = Number(flattened[1]);

if (entryAskSize === 0) {
// remove prices with zero Qty
for (let i = orderBookAskList.length - 1; i >= 0; i--) {
if (orderBookAskList[i][0] === entryAskPrice) {
orderBookAskList.splice(i, 1);
}
}
} else {
// The price that already exists in the order book is modified only Qty
if (
orderBookAskList.some((innerArray) => innerArray[0] === entryAskPrice)
) {
orderBookAskList.forEach((item, index) => {
if (item[0] === entryAskPrice) {
orderBookAskList[index][1] = entryAskSize;
orderBookAskList[index][2] = messageId;
}
});
} else {
// Add new data to order book
orderBookAskList.push([entryAskPrice, entryAskSize, messageId]);
}
}
}
});

return [orderBookBidList, orderBookAskList];
};

test();