nodejs-order-book 9.0.0 → 9.1.1
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/README.md +3 -2
- package/dist/cjs/orderbook.js +35 -9
- package/dist/cjs/stopbook.js +11 -0
- package/dist/cjs/stopqueue.js +3 -0
- package/dist/cjs/stopside.js +3 -0
- package/dist/esm/orderbook.js +35 -9
- package/dist/esm/stopbook.js +11 -0
- package/dist/esm/stopqueue.js +3 -0
- package/dist/esm/stopside.js +3 -0
- package/dist/types/stopbook.d.ts +11 -1
- package/dist/types/stopqueue.d.ts +1 -0
- package/dist/types/stopside.d.ts +2 -0
- package/dist/types/types.d.ts +10 -0
- package/package.json +6 -14
- package/dist/umd/index.js +0 -2
- package/dist/umd/index.js.LICENSE.txt +0 -10
package/README.md
CHANGED
|
@@ -387,6 +387,7 @@ A `snapshot` represents the state of the order book at a specific point in time.
|
|
|
387
387
|
|
|
388
388
|
- `asks`: List of ask orders, each with a `price` and a list of associated `orders`.
|
|
389
389
|
- `bids`: List of bid orders, each with a `price` and a list of associated `orders`.
|
|
390
|
+
- `stopBook`: an object with `bids` and `asks` properties related to every `StopOrder` in the orderbook.
|
|
390
391
|
- `ts`: A timestamp indicating when the snapshot was taken, in Unix timestamp format.
|
|
391
392
|
- `lastOp`: The id of the last operation included in the snapshot
|
|
392
393
|
|
|
@@ -405,7 +406,7 @@ await saveLog(order.log)
|
|
|
405
406
|
// ... after some time take a snapshot of the order book and save it on the database
|
|
406
407
|
|
|
407
408
|
const snapshot = ob.snapshot()
|
|
408
|
-
await saveSnapshot(snapshot)
|
|
409
|
+
await saveSnapshot(JSON.stringify(snapshot))
|
|
409
410
|
|
|
410
411
|
// If you want you can safely remove all logs preceding the `lastOp` id of the snapshot, and continue to save each subsequent log to the database
|
|
411
412
|
await removePreviousLogs(snapshot.lastOp)
|
|
@@ -414,7 +415,7 @@ await removePreviousLogs(snapshot.lastOp)
|
|
|
414
415
|
const logs = await getLogs()
|
|
415
416
|
const snapshot = await getSnapshot()
|
|
416
417
|
|
|
417
|
-
const ob = new OrderBook({ snapshot, journal: log, enableJournaling: true })
|
|
418
|
+
const ob = new OrderBook({ snapshot: JSON.parse(snapshot), journal: log, enableJournaling: true })
|
|
418
419
|
```
|
|
419
420
|
|
|
420
421
|
### Journal Logs
|
package/dist/cjs/orderbook.js
CHANGED
|
@@ -252,7 +252,8 @@ var OrderBook = /** @class */ (function () {
|
|
|
252
252
|
_this.asks.priceTree().forEach(function (price, orders) {
|
|
253
253
|
asks.push({ price: price, orders: orders.toArray().map(function (o) { return o.toObject(); }) });
|
|
254
254
|
});
|
|
255
|
-
|
|
255
|
+
var stopBook = _this.stopBook.snapshot();
|
|
256
|
+
return { bids: bids, asks: asks, stopBook: stopBook, ts: Date.now(), lastOp: _this._lastOp };
|
|
256
257
|
};
|
|
257
258
|
this._market = function (options, incomingResponse) {
|
|
258
259
|
var response = incomingResponse !== null && incomingResponse !== void 0 ? incomingResponse : _this.validateMarketOrder(options);
|
|
@@ -355,25 +356,50 @@ var OrderBook = /** @class */ (function () {
|
|
|
355
356
|
return response;
|
|
356
357
|
};
|
|
357
358
|
this.restoreSnapshot = function (snapshot) {
|
|
359
|
+
var _a, _b, _c, _d;
|
|
358
360
|
_this._lastOp = snapshot.lastOp;
|
|
359
|
-
for (var _i = 0,
|
|
360
|
-
var level =
|
|
361
|
-
for (var
|
|
362
|
-
var order =
|
|
361
|
+
for (var _i = 0, _e = snapshot.bids; _i < _e.length; _i++) {
|
|
362
|
+
var level = _e[_i];
|
|
363
|
+
for (var _f = 0, _g = level.orders; _f < _g.length; _f++) {
|
|
364
|
+
var order = _g[_f];
|
|
363
365
|
var newOrder = order_1.OrderFactory.createOrder(order);
|
|
364
366
|
_this.orders[newOrder.id] = newOrder;
|
|
365
367
|
_this.bids.append(newOrder);
|
|
366
368
|
}
|
|
367
369
|
}
|
|
368
|
-
for (var
|
|
369
|
-
var level =
|
|
370
|
-
for (var
|
|
371
|
-
var order =
|
|
370
|
+
for (var _h = 0, _j = snapshot.asks; _h < _j.length; _h++) {
|
|
371
|
+
var level = _j[_h];
|
|
372
|
+
for (var _k = 0, _l = level.orders; _k < _l.length; _k++) {
|
|
373
|
+
var order = _l[_k];
|
|
372
374
|
var newOrder = order_1.OrderFactory.createOrder(order);
|
|
373
375
|
_this.orders[newOrder.id] = newOrder;
|
|
374
376
|
_this.asks.append(newOrder);
|
|
375
377
|
}
|
|
376
378
|
}
|
|
379
|
+
if (((_b = (_a = snapshot.stopBook) === null || _a === void 0 ? void 0 : _a.bids) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
380
|
+
for (var _m = 0, _o = snapshot.stopBook.bids; _m < _o.length; _m++) {
|
|
381
|
+
var level = _o[_m];
|
|
382
|
+
for (var _p = 0, _q = level.orders; _p < _q.length; _p++) {
|
|
383
|
+
var order = _q[_p];
|
|
384
|
+
// @ts-expect-error // TODO fix types
|
|
385
|
+
var newOrder = order_1.OrderFactory.createOrder(order);
|
|
386
|
+
// @ts-expect-error // TODO fix types
|
|
387
|
+
_this.stopBook.add(newOrder);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (((_d = (_c = snapshot.stopBook) === null || _c === void 0 ? void 0 : _c.asks) === null || _d === void 0 ? void 0 : _d.length) > 0) {
|
|
392
|
+
for (var _r = 0, _s = snapshot.stopBook.asks; _r < _s.length; _r++) {
|
|
393
|
+
var level = _s[_r];
|
|
394
|
+
for (var _t = 0, _u = level.orders; _t < _u.length; _t++) {
|
|
395
|
+
var order = _u[_t];
|
|
396
|
+
// @ts-expect-error // TODO fix types
|
|
397
|
+
var newOrder = order_1.OrderFactory.createOrder(order);
|
|
398
|
+
// @ts-expect-error // TODO fix types
|
|
399
|
+
_this.stopBook.add(newOrder);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
377
403
|
};
|
|
378
404
|
/**
|
|
379
405
|
* Remove an existing order with given ID from the order book
|
package/dist/cjs/stopbook.js
CHANGED
|
@@ -57,6 +57,17 @@ var StopBook = /** @class */ (function () {
|
|
|
57
57
|
}
|
|
58
58
|
return response;
|
|
59
59
|
};
|
|
60
|
+
this.snapshot = function () {
|
|
61
|
+
var bids = [];
|
|
62
|
+
var asks = [];
|
|
63
|
+
_this.bids.priceTree().forEach(function (price, orders) {
|
|
64
|
+
bids.push({ price: price, orders: orders.toArray().map(function (o) { return o.toObject(); }) });
|
|
65
|
+
});
|
|
66
|
+
_this.asks.priceTree().forEach(function (price, orders) {
|
|
67
|
+
asks.push({ price: price, orders: orders.toArray().map(function (o) { return o.toObject(); }) });
|
|
68
|
+
});
|
|
69
|
+
return { bids: bids, asks: asks };
|
|
70
|
+
};
|
|
60
71
|
this.bids = new stopside_1.StopSide(types_1.Side.BUY);
|
|
61
72
|
this.asks = new stopside_1.StopSide(types_1.Side.SELL);
|
|
62
73
|
}
|
package/dist/cjs/stopqueue.js
CHANGED
package/dist/cjs/stopside.js
CHANGED
|
@@ -65,6 +65,9 @@ var StopSide = /** @class */ (function () {
|
|
|
65
65
|
upperBound);
|
|
66
66
|
return queues;
|
|
67
67
|
};
|
|
68
|
+
this.priceTree = function () {
|
|
69
|
+
return _this._priceTree;
|
|
70
|
+
};
|
|
68
71
|
var compare = side === types_1.Side.SELL
|
|
69
72
|
? function (a, b) { return a - b; }
|
|
70
73
|
: function (a, b) { return b - a; };
|
package/dist/esm/orderbook.js
CHANGED
|
@@ -249,7 +249,8 @@ var OrderBook = /** @class */ (function () {
|
|
|
249
249
|
_this.asks.priceTree().forEach(function (price, orders) {
|
|
250
250
|
asks.push({ price: price, orders: orders.toArray().map(function (o) { return o.toObject(); }) });
|
|
251
251
|
});
|
|
252
|
-
|
|
252
|
+
var stopBook = _this.stopBook.snapshot();
|
|
253
|
+
return { bids: bids, asks: asks, stopBook: stopBook, ts: Date.now(), lastOp: _this._lastOp };
|
|
253
254
|
};
|
|
254
255
|
this._market = function (options, incomingResponse) {
|
|
255
256
|
var response = incomingResponse !== null && incomingResponse !== void 0 ? incomingResponse : _this.validateMarketOrder(options);
|
|
@@ -352,25 +353,50 @@ var OrderBook = /** @class */ (function () {
|
|
|
352
353
|
return response;
|
|
353
354
|
};
|
|
354
355
|
this.restoreSnapshot = function (snapshot) {
|
|
356
|
+
var _a, _b, _c, _d;
|
|
355
357
|
_this._lastOp = snapshot.lastOp;
|
|
356
|
-
for (var _i = 0,
|
|
357
|
-
var level =
|
|
358
|
-
for (var
|
|
359
|
-
var order =
|
|
358
|
+
for (var _i = 0, _e = snapshot.bids; _i < _e.length; _i++) {
|
|
359
|
+
var level = _e[_i];
|
|
360
|
+
for (var _f = 0, _g = level.orders; _f < _g.length; _f++) {
|
|
361
|
+
var order = _g[_f];
|
|
360
362
|
var newOrder = OrderFactory.createOrder(order);
|
|
361
363
|
_this.orders[newOrder.id] = newOrder;
|
|
362
364
|
_this.bids.append(newOrder);
|
|
363
365
|
}
|
|
364
366
|
}
|
|
365
|
-
for (var
|
|
366
|
-
var level =
|
|
367
|
-
for (var
|
|
368
|
-
var order =
|
|
367
|
+
for (var _h = 0, _j = snapshot.asks; _h < _j.length; _h++) {
|
|
368
|
+
var level = _j[_h];
|
|
369
|
+
for (var _k = 0, _l = level.orders; _k < _l.length; _k++) {
|
|
370
|
+
var order = _l[_k];
|
|
369
371
|
var newOrder = OrderFactory.createOrder(order);
|
|
370
372
|
_this.orders[newOrder.id] = newOrder;
|
|
371
373
|
_this.asks.append(newOrder);
|
|
372
374
|
}
|
|
373
375
|
}
|
|
376
|
+
if (((_b = (_a = snapshot.stopBook) === null || _a === void 0 ? void 0 : _a.bids) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
377
|
+
for (var _m = 0, _o = snapshot.stopBook.bids; _m < _o.length; _m++) {
|
|
378
|
+
var level = _o[_m];
|
|
379
|
+
for (var _p = 0, _q = level.orders; _p < _q.length; _p++) {
|
|
380
|
+
var order = _q[_p];
|
|
381
|
+
// @ts-expect-error // TODO fix types
|
|
382
|
+
var newOrder = OrderFactory.createOrder(order);
|
|
383
|
+
// @ts-expect-error // TODO fix types
|
|
384
|
+
_this.stopBook.add(newOrder);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (((_d = (_c = snapshot.stopBook) === null || _c === void 0 ? void 0 : _c.asks) === null || _d === void 0 ? void 0 : _d.length) > 0) {
|
|
389
|
+
for (var _r = 0, _s = snapshot.stopBook.asks; _r < _s.length; _r++) {
|
|
390
|
+
var level = _s[_r];
|
|
391
|
+
for (var _t = 0, _u = level.orders; _t < _u.length; _t++) {
|
|
392
|
+
var order = _u[_t];
|
|
393
|
+
// @ts-expect-error // TODO fix types
|
|
394
|
+
var newOrder = OrderFactory.createOrder(order);
|
|
395
|
+
// @ts-expect-error // TODO fix types
|
|
396
|
+
_this.stopBook.add(newOrder);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
374
400
|
};
|
|
375
401
|
/**
|
|
376
402
|
* Remove an existing order with given ID from the order book
|
package/dist/esm/stopbook.js
CHANGED
|
@@ -54,6 +54,17 @@ var StopBook = /** @class */ (function () {
|
|
|
54
54
|
}
|
|
55
55
|
return response;
|
|
56
56
|
};
|
|
57
|
+
this.snapshot = function () {
|
|
58
|
+
var bids = [];
|
|
59
|
+
var asks = [];
|
|
60
|
+
_this.bids.priceTree().forEach(function (price, orders) {
|
|
61
|
+
bids.push({ price: price, orders: orders.toArray().map(function (o) { return o.toObject(); }) });
|
|
62
|
+
});
|
|
63
|
+
_this.asks.priceTree().forEach(function (price, orders) {
|
|
64
|
+
asks.push({ price: price, orders: orders.toArray().map(function (o) { return o.toObject(); }) });
|
|
65
|
+
});
|
|
66
|
+
return { bids: bids, asks: asks };
|
|
67
|
+
};
|
|
57
68
|
this.bids = new StopSide(Side.BUY);
|
|
58
69
|
this.asks = new StopSide(Side.SELL);
|
|
59
70
|
}
|
package/dist/esm/stopqueue.js
CHANGED
package/dist/esm/stopside.js
CHANGED
|
@@ -59,6 +59,9 @@ var StopSide = /** @class */ (function () {
|
|
|
59
59
|
upperBound);
|
|
60
60
|
return queues;
|
|
61
61
|
};
|
|
62
|
+
this.priceTree = function () {
|
|
63
|
+
return _this._priceTree;
|
|
64
|
+
};
|
|
62
65
|
var compare = side === Side.SELL
|
|
63
66
|
? function (a, b) { return a - b; }
|
|
64
67
|
: function (a, b) { return b - a; };
|
package/dist/types/stopbook.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StopQueue } from "./stopqueue";
|
|
2
|
-
import { Side, type StopOrder } from "./types";
|
|
2
|
+
import { type IStopOrder, Side, type StopOrder } from "./types";
|
|
3
3
|
export declare class StopBook {
|
|
4
4
|
private readonly bids;
|
|
5
5
|
private readonly asks;
|
|
@@ -17,4 +17,14 @@ export declare class StopBook {
|
|
|
17
17
|
* Sell: marketPrice > stopPrice
|
|
18
18
|
*/
|
|
19
19
|
validConditionalOrder: (marketPrice: number, order: StopOrder) => boolean;
|
|
20
|
+
snapshot: () => {
|
|
21
|
+
bids: {
|
|
22
|
+
price: number;
|
|
23
|
+
orders: IStopOrder[];
|
|
24
|
+
}[];
|
|
25
|
+
asks: {
|
|
26
|
+
price: number;
|
|
27
|
+
orders: IStopOrder[];
|
|
28
|
+
}[];
|
|
29
|
+
};
|
|
20
30
|
}
|
package/dist/types/stopside.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import createRBTree from "functional-red-black-tree";
|
|
1
2
|
import { StopQueue } from "./stopqueue";
|
|
2
3
|
import { Side, type StopOrder } from "./types";
|
|
3
4
|
export declare class StopSide {
|
|
@@ -9,4 +10,5 @@ export declare class StopSide {
|
|
|
9
10
|
remove: (id: string, stopPrice: number) => StopOrder | undefined;
|
|
10
11
|
removePriceLevel: (priceLevel: number) => void;
|
|
11
12
|
between: (priceBefore: number, marketPrice: number) => StopQueue[];
|
|
13
|
+
priceTree: () => createRBTree.Tree<number, StopQueue>;
|
|
12
14
|
}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -357,6 +357,16 @@ export interface Snapshot {
|
|
|
357
357
|
/** List of orders associated with this price */
|
|
358
358
|
orders: ILimitOrder[];
|
|
359
359
|
}>;
|
|
360
|
+
stopBook: {
|
|
361
|
+
asks: Array<{
|
|
362
|
+
price: number;
|
|
363
|
+
orders: IStopOrder[];
|
|
364
|
+
}>;
|
|
365
|
+
bids: Array<{
|
|
366
|
+
price: number;
|
|
367
|
+
orders: IStopOrder[];
|
|
368
|
+
}>;
|
|
369
|
+
};
|
|
360
370
|
/** Unix timestamp representing when the snapshot was taken */
|
|
361
371
|
ts: number;
|
|
362
372
|
/** The id of the last operation inserted in the orderbook */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodejs-order-book",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1.1",
|
|
4
4
|
"description": "Node.js Lmit Order Book for high-frequency trading (HFT).",
|
|
5
5
|
"author": "Andrea Fassina <fasenderos@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,15 +14,13 @@
|
|
|
14
14
|
},
|
|
15
15
|
"main": "dist/cjs/index.js",
|
|
16
16
|
"module": "dist/esm/index.js",
|
|
17
|
-
"umd:main": "dist/umd/index.js",
|
|
18
17
|
"types": "dist/types/index.d.js",
|
|
19
18
|
"scripts": {
|
|
20
19
|
"addscope": "node tools/packagejson name @fasenderos/nodejs-order-book",
|
|
21
20
|
"bench": "node benchmarks/benchmark_lob.js",
|
|
22
|
-
"build": "npm run build:cjs && npm run build:esm && npm run build:
|
|
21
|
+
"build": "npm run build:cjs && npm run build:esm && npm run build:types",
|
|
23
22
|
"build:cjs": "node tools/cleanup cjs && tsc -p config/tsconfig.cjs.json",
|
|
24
23
|
"build:esm": "node tools/cleanup esm && tsc -p config/tsconfig.esm.json",
|
|
25
|
-
"build:umd": "node tools/cleanup umd && webpack --config config/webpack.config.js",
|
|
26
24
|
"build:types": "node tools/cleanup types && tsc -p config/tsconfig.types.json",
|
|
27
25
|
"clean": "node tools/cleanup",
|
|
28
26
|
"lint": "biome check ./src ./test",
|
|
@@ -46,26 +44,20 @@
|
|
|
46
44
|
"functional-red-black-tree": "1.0.1"
|
|
47
45
|
},
|
|
48
46
|
"devDependencies": {
|
|
49
|
-
"@biomejs/biome": "^1.
|
|
47
|
+
"@biomejs/biome": "^2.1.2",
|
|
50
48
|
"@commitlint/cli": "^19.3.0",
|
|
51
49
|
"@commitlint/config-conventional": "^19.2.2",
|
|
52
|
-
"@release-it/conventional-changelog": "^
|
|
50
|
+
"@release-it/conventional-changelog": "^10.0.0",
|
|
53
51
|
"@types/functional-red-black-tree": "^1.0.6",
|
|
54
52
|
"c8": "^10.1.2",
|
|
55
|
-
"crypto-browserify": "^3.12.0",
|
|
56
53
|
"gaussian": "^1.0.0",
|
|
57
54
|
"husky": "^9.1.1",
|
|
58
55
|
"nanobench": "^3.0.0",
|
|
59
56
|
"pinst": "^3.0.0",
|
|
60
|
-
"release-it": "^
|
|
61
|
-
"stream-browserify": "^3.0.0",
|
|
62
|
-
"ts-loader": "^9.0.0",
|
|
57
|
+
"release-it": "^19.0.2",
|
|
63
58
|
"ts-node": "^10.0.0",
|
|
64
59
|
"tsx": "^4.16.5",
|
|
65
|
-
"typescript": "^5.0.0"
|
|
66
|
-
"vm-browserify": "^1.1.2",
|
|
67
|
-
"webpack": "^5.0.0",
|
|
68
|
-
"webpack-cli": "^5.0.0"
|
|
60
|
+
"typescript": "^5.0.0"
|
|
69
61
|
},
|
|
70
62
|
"publishConfig": {
|
|
71
63
|
"access": "public"
|