-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathstream_l4_book.ts
More file actions
97 lines (79 loc) · 2.83 KB
/
stream_l4_book.ts
File metadata and controls
97 lines (79 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env npx ts-node
// @ts-nocheck
/**
* L4 Order Book Streaming via gRPC - Individual Orders with Order IDs
*
* L4 order book is CRITICAL for:
* - Market making: Know your exact queue position
* - Order flow analysis: Detect large orders, icebergs
* - Optimal execution: See exactly what you're crossing
* - HFT: Lower latency than WebSocket
*
* Usage:
* export ENDPOINT="https://your-endpoint.example.com/TOKEN"
* npx ts-node stream_l4_book.ts
*/
import { HyperliquidSDK } from '@quicknode/hyperliquid-sdk';
const ENDPOINT = process.env.ENDPOINT;
if (!ENDPOINT) {
console.log("L4 Order Book Streaming Example");
console.log("=".repeat(60));
console.log();
console.log("L4 book shows EVERY individual order with order IDs.");
console.log("This is essential for market making and order flow analysis.");
console.log();
console.log("Usage:");
console.log(" export ENDPOINT='https://your-endpoint.example.com/TOKEN'");
console.log(" npx ts-node stream_l4_book.ts");
process.exit(1);
}
function timestamp(): string {
return new Date().toISOString().slice(11, 23);
}
async function main() {
console.log("=".repeat(60));
console.log("L4 Order Book Streaming (Individual Orders)");
console.log("=".repeat(60));
let updateCount = 0;
// Create SDK client
const sdk = new HyperliquidSDK(ENDPOINT!);
// Configure gRPC stream
sdk.grpc.onConnect = () => console.log("[CONNECTED]");
sdk.grpc.onError = (err) => console.log(`[ERROR] ${err.message}`);
sdk.grpc.l4Book("BTC", (data: any) => {
updateCount++;
if (data.type === "snapshot") {
const bids = data.bids || [];
const asks = data.asks || [];
console.log(`[${timestamp()}] L4 SNAPSHOT`);
console.log(` ${bids.length} bid orders, ${asks.length} ask orders`);
// Show top 3 orders on each side
console.log(" Top bids:");
for (const order of bids.slice(0, 3)) {
console.log(` OID ${order.oid}: ${order.sz} @ ${order.limit_px}`);
}
console.log(" Top asks:");
for (const order of asks.slice(0, 3)) {
console.log(` OID ${order.oid}: ${order.sz} @ ${order.limit_px}`);
}
} else if (data.type === "diff") {
console.log(`[${timestamp()}] L4 DIFF (height: ${data.height})`);
const diffData = data.data || {};
console.log(` Changes: ${JSON.stringify(diffData).slice(0, 100)}...`);
}
if (updateCount >= 5) {
console.log(`\nReceived ${updateCount} L4 updates.`);
}
});
console.log("\nSubscribing to BTC L4 order book...");
console.log("-".repeat(60));
await sdk.grpc.start();
const start = Date.now();
while (updateCount < 5 && Date.now() - start < 30000) {
await new Promise(resolve => setTimeout(resolve, 100));
}
sdk.grpc.stop();
console.log("\n" + "=".repeat(60));
console.log("Done!");
}
main().catch(console.error);