nodejs-order-book 9.0.0 → 9.1.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.
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
@@ -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
- return { bids: bids, asks: asks, ts: Date.now(), lastOp: _this._lastOp };
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, _a = snapshot.bids; _i < _a.length; _i++) {
360
- var level = _a[_i];
361
- for (var _b = 0, _c = level.orders; _b < _c.length; _b++) {
362
- var order = _c[_b];
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 _d = 0, _e = snapshot.asks; _d < _e.length; _d++) {
369
- var level = _e[_d];
370
- for (var _f = 0, _g = level.orders; _f < _g.length; _f++) {
371
- var order = _g[_f];
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
@@ -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
  }
@@ -44,6 +44,9 @@ var StopQueue = /** @class */ (function () {
44
44
  }
45
45
  return deletedOrder;
46
46
  };
47
+ this.toArray = function () {
48
+ return _this._orders.toArray();
49
+ };
47
50
  this._price = price;
48
51
  this._orders = new denque_1.default();
49
52
  }
@@ -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; };
@@ -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
- return { bids: bids, asks: asks, ts: Date.now(), lastOp: _this._lastOp };
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, _a = snapshot.bids; _i < _a.length; _i++) {
357
- var level = _a[_i];
358
- for (var _b = 0, _c = level.orders; _b < _c.length; _b++) {
359
- var order = _c[_b];
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 _d = 0, _e = snapshot.asks; _d < _e.length; _d++) {
366
- var level = _e[_d];
367
- for (var _f = 0, _g = level.orders; _f < _g.length; _f++) {
368
- var order = _g[_f];
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
@@ -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
  }
@@ -38,6 +38,9 @@ var StopQueue = /** @class */ (function () {
38
38
  }
39
39
  return deletedOrder;
40
40
  };
41
+ this.toArray = function () {
42
+ return _this._orders.toArray();
43
+ };
41
44
  this._price = price;
42
45
  this._orders = new Denque();
43
46
  }
@@ -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; };
@@ -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
  }
@@ -9,4 +9,5 @@ export declare class StopQueue {
9
9
  removeFromHead: () => StopOrder | undefined;
10
10
  append: (order: StopOrder) => StopOrder;
11
11
  remove: (id: string) => StopOrder | undefined;
12
+ toArray: () => StopOrder[];
12
13
  }
@@ -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
  }
@@ -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 */