@xapy/orderbook 0.1.3 → 0.1.4
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.
- package/dist/exchanges/bingx/index.cjs +102 -23
- package/dist/exchanges/bingx/index.cjs.map +1 -1
- package/dist/exchanges/bingx/index.d.cts +9 -2
- package/dist/exchanges/bingx/index.d.ts +9 -2
- package/dist/exchanges/bingx/index.js +102 -23
- package/dist/exchanges/bingx/index.js.map +1 -1
- package/dist/index.cjs +102 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +102 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1231,29 +1231,50 @@ function streamBingxOrderbook(opts) {
|
|
|
1231
1231
|
const wsSymbol = opts.symbol.toUpperCase().replace("/", "-");
|
|
1232
1232
|
const level = opts.depth ?? 20;
|
|
1233
1233
|
const interval = opts.interval ?? "500ms";
|
|
1234
|
-
const
|
|
1234
|
+
const depthDataType = `${wsSymbol}@depth${level}@${interval}`;
|
|
1235
|
+
const tickerDataType = `${wsSymbol}@bookTicker`;
|
|
1235
1236
|
const merger = new BookMerger();
|
|
1236
1237
|
let ws = null;
|
|
1237
1238
|
const stream = new OrderbookStream(() => ws?.close());
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1239
|
+
const subId = Date.now();
|
|
1240
|
+
const subscribeDepth = JSON.stringify({
|
|
1241
|
+
id: `sub-depth-${subId}`,
|
|
1240
1242
|
reqType: "sub",
|
|
1241
|
-
dataType
|
|
1243
|
+
dataType: depthDataType
|
|
1242
1244
|
});
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1245
|
+
const subscribeTicker = JSON.stringify({
|
|
1246
|
+
id: `sub-ticker-${subId}`,
|
|
1247
|
+
reqType: "sub",
|
|
1248
|
+
dataType: tickerDataType
|
|
1249
|
+
});
|
|
1250
|
+
let lastMerged = null;
|
|
1251
|
+
let lastTicker = null;
|
|
1252
|
+
const emitOverlayed = () => {
|
|
1253
|
+
if (!lastMerged) return;
|
|
1254
|
+
let bids = lastMerged.bids;
|
|
1255
|
+
let asks = lastMerged.asks;
|
|
1256
|
+
let timestamp = lastMerged.timestamp;
|
|
1257
|
+
let sequence = lastMerged.sequence;
|
|
1258
|
+
if (lastTicker) {
|
|
1259
|
+
bids = overlayBid(bids, lastTicker.bid);
|
|
1260
|
+
asks = overlayAsk(asks, lastTicker.ask);
|
|
1261
|
+
if (lastTicker.ts > timestamp) {
|
|
1262
|
+
timestamp = lastTicker.ts;
|
|
1263
|
+
sequence = Math.max(sequence, lastTicker.ts);
|
|
1264
|
+
}
|
|
1253
1265
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1266
|
+
const book = {
|
|
1267
|
+
exchange: "bingx",
|
|
1268
|
+
symbol: opts.symbol,
|
|
1269
|
+
market: opts.market,
|
|
1270
|
+
bids,
|
|
1271
|
+
asks,
|
|
1272
|
+
timestamp,
|
|
1273
|
+
sequence
|
|
1274
|
+
};
|
|
1275
|
+
stream.emit("update", book);
|
|
1276
|
+
};
|
|
1277
|
+
const handleDepth = (d) => {
|
|
1257
1278
|
const ts = d.T ?? d.ts ?? Date.now();
|
|
1258
1279
|
const event = {
|
|
1259
1280
|
kind: "snapshot",
|
|
@@ -1264,16 +1285,45 @@ function streamBingxOrderbook(opts) {
|
|
|
1264
1285
|
};
|
|
1265
1286
|
const r = merger.apply(event);
|
|
1266
1287
|
if (!r.ok) return;
|
|
1267
|
-
|
|
1268
|
-
exchange: "bingx",
|
|
1269
|
-
symbol: opts.symbol,
|
|
1270
|
-
market: opts.market,
|
|
1288
|
+
lastMerged = {
|
|
1271
1289
|
bids: r.bids,
|
|
1272
1290
|
asks: r.asks,
|
|
1273
1291
|
timestamp: r.timestamp,
|
|
1274
1292
|
sequence: r.sequence
|
|
1275
1293
|
};
|
|
1276
|
-
|
|
1294
|
+
emitOverlayed();
|
|
1295
|
+
};
|
|
1296
|
+
const handleTicker = (t) => {
|
|
1297
|
+
const bidPrice = Number(t.b);
|
|
1298
|
+
const askPrice = Number(t.a);
|
|
1299
|
+
const bidSize = Number(t.B);
|
|
1300
|
+
const askSize = Number(t.A);
|
|
1301
|
+
if (!Number.isFinite(bidPrice) || !Number.isFinite(askPrice)) return;
|
|
1302
|
+
lastTicker = {
|
|
1303
|
+
bid: { price: bidPrice, size: bidSize },
|
|
1304
|
+
ask: { price: askPrice, size: askSize },
|
|
1305
|
+
ts: t.T ?? t.E ?? Date.now()
|
|
1306
|
+
};
|
|
1307
|
+
emitOverlayed();
|
|
1308
|
+
};
|
|
1309
|
+
const handlePayload = (text) => {
|
|
1310
|
+
if (text === "Ping" || text === "ping") {
|
|
1311
|
+
ws?.send(text === "Ping" ? "Pong" : "pong");
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
let msg;
|
|
1315
|
+
try {
|
|
1316
|
+
msg = JSON.parse(text);
|
|
1317
|
+
} catch {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
if (msg.id && !msg.data) return;
|
|
1321
|
+
if (!msg.dataType || !msg.data) return;
|
|
1322
|
+
if (msg.dataType === depthDataType) {
|
|
1323
|
+
handleDepth(msg.data);
|
|
1324
|
+
} else if (msg.dataType === tickerDataType) {
|
|
1325
|
+
handleTicker(msg.data);
|
|
1326
|
+
}
|
|
1277
1327
|
};
|
|
1278
1328
|
const onMessage = async (raw) => {
|
|
1279
1329
|
if (typeof raw === "string") {
|
|
@@ -1287,7 +1337,10 @@ function streamBingxOrderbook(opts) {
|
|
|
1287
1337
|
url: isSpot ? WS_SPOT3 : WS_SWAP,
|
|
1288
1338
|
onOpen: (sock) => {
|
|
1289
1339
|
merger.reset();
|
|
1290
|
-
|
|
1340
|
+
lastMerged = null;
|
|
1341
|
+
lastTicker = null;
|
|
1342
|
+
sock.send(subscribeDepth);
|
|
1343
|
+
sock.send(subscribeTicker);
|
|
1291
1344
|
},
|
|
1292
1345
|
onMessage
|
|
1293
1346
|
// bingx server is the one that sends Ping frames; we don't need client pings.
|
|
@@ -1299,6 +1352,32 @@ function streamBingxOrderbook(opts) {
|
|
|
1299
1352
|
ws.connect().catch((e) => stream.emit("error", e));
|
|
1300
1353
|
return stream;
|
|
1301
1354
|
}
|
|
1355
|
+
function overlayAsk(asks, top) {
|
|
1356
|
+
if (!(top.size > 0)) return asks;
|
|
1357
|
+
let i = 0;
|
|
1358
|
+
for (; i < asks.length; i++) {
|
|
1359
|
+
const level = asks[i];
|
|
1360
|
+
if (!level || level.price >= top.price) break;
|
|
1361
|
+
}
|
|
1362
|
+
const at = asks[i];
|
|
1363
|
+
if (at && at.price === top.price) {
|
|
1364
|
+
return [{ price: top.price, size: top.size }, ...asks.slice(i + 1)];
|
|
1365
|
+
}
|
|
1366
|
+
return [{ price: top.price, size: top.size }, ...asks.slice(i)];
|
|
1367
|
+
}
|
|
1368
|
+
function overlayBid(bids, top) {
|
|
1369
|
+
if (!(top.size > 0)) return bids;
|
|
1370
|
+
let i = 0;
|
|
1371
|
+
for (; i < bids.length; i++) {
|
|
1372
|
+
const level = bids[i];
|
|
1373
|
+
if (!level || level.price <= top.price) break;
|
|
1374
|
+
}
|
|
1375
|
+
const at = bids[i];
|
|
1376
|
+
if (at && at.price === top.price) {
|
|
1377
|
+
return [{ price: top.price, size: top.size }, ...bids.slice(i + 1)];
|
|
1378
|
+
}
|
|
1379
|
+
return [{ price: top.price, size: top.size }, ...bids.slice(i)];
|
|
1380
|
+
}
|
|
1302
1381
|
|
|
1303
1382
|
// src/exchanges/bingx/index.ts
|
|
1304
1383
|
var BingxClient = class {
|