nodejs-order-book 10.0.0 → 10.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.
@@ -5,74 +5,76 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.OrderQueue = void 0;
7
7
  /* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
8
- var denque_1 = __importDefault(require("denque"));
9
- var OrderQueue = /** @class */ (function () {
10
- function OrderQueue(price) {
11
- var _this = this;
12
- this._ordersMap = {};
13
- // returns the number of orders in queue
14
- this.len = function () {
15
- return _this._orders.length;
16
- };
17
- this.toArray = function () {
18
- return _this._orders.toArray();
19
- };
20
- // returns price level of the queue
21
- this.price = function () {
22
- return _this._price;
23
- };
24
- // returns price level of the queue
25
- this.volume = function () {
26
- return _this._volume;
27
- };
28
- // returns top order in queue
29
- this.head = function () {
30
- return _this._orders.peekFront();
31
- };
32
- // returns bottom order in queue
33
- this.tail = function () {
34
- return _this._orders.peekBack();
35
- };
36
- // adds order to tail of the queue
37
- this.append = function (order) {
38
- _this._volume += order.size;
39
- _this._orders.push(order);
40
- _this._ordersMap[order.id] = _this._orders.length - 1;
41
- return order;
42
- };
43
- // sets up new order to list value
44
- this.update = function (oldOrder, newOrder) {
45
- _this._volume -= oldOrder.size;
46
- _this._volume += newOrder.size;
47
- // Remove old order from head
48
- _this._orders.shift();
49
- delete _this._ordersMap[oldOrder.id];
50
- // Add new order to head
51
- _this._orders.unshift(newOrder);
52
- _this._ordersMap[newOrder.id] = 0;
53
- };
54
- // removes order from the queue
55
- this.remove = function (order) {
56
- _this._volume -= order.size;
57
- var deletedOrderIndex = _this._ordersMap[order.id];
58
- _this._orders.removeOne(deletedOrderIndex);
59
- delete _this._ordersMap[order.id];
60
- // Update all orders indexes where index is greater than the deleted one
61
- for (var orderId in _this._ordersMap) {
62
- if (_this._ordersMap[orderId] > deletedOrderIndex) {
63
- _this._ordersMap[orderId] -= 1;
64
- }
65
- }
66
- };
67
- this.updateOrderSize = function (order, size) {
68
- _this._volume += size - order.size; // update volume
69
- order.size = size;
70
- order.time = Date.now();
71
- };
8
+ const denque_1 = __importDefault(require("denque"));
9
+ class OrderQueue {
10
+ _price;
11
+ _volume;
12
+ // { orderID: index } index in denque
13
+ _orders;
14
+ _ordersMap = {};
15
+ constructor(price) {
72
16
  this._price = price;
73
17
  this._volume = 0;
74
18
  this._orders = new denque_1.default();
75
19
  }
76
- return OrderQueue;
77
- }());
20
+ // returns the number of orders in queue
21
+ len = () => {
22
+ return this._orders.length;
23
+ };
24
+ toArray = () => {
25
+ return this._orders.toArray();
26
+ };
27
+ // returns price level of the queue
28
+ price = () => {
29
+ return this._price;
30
+ };
31
+ // returns price level of the queue
32
+ volume = () => {
33
+ return this._volume;
34
+ };
35
+ // returns top order in queue
36
+ head = () => {
37
+ return this._orders.peekFront();
38
+ };
39
+ // returns bottom order in queue
40
+ tail = () => {
41
+ return this._orders.peekBack();
42
+ };
43
+ // adds order to tail of the queue
44
+ append = (order) => {
45
+ this._volume += order.size;
46
+ this._orders.push(order);
47
+ this._ordersMap[order.id] = this._orders.length - 1;
48
+ return order;
49
+ };
50
+ // sets up new order to list value
51
+ update = (oldOrder, newOrder) => {
52
+ this._volume -= oldOrder.size;
53
+ this._volume += newOrder.size;
54
+ // Remove old order from head
55
+ this._orders.shift();
56
+ delete this._ordersMap[oldOrder.id];
57
+ // Add new order to head
58
+ this._orders.unshift(newOrder);
59
+ this._ordersMap[newOrder.id] = 0;
60
+ };
61
+ // removes order from the queue
62
+ remove = (order) => {
63
+ this._volume -= order.size;
64
+ const deletedOrderIndex = this._ordersMap[order.id];
65
+ this._orders.removeOne(deletedOrderIndex);
66
+ delete this._ordersMap[order.id];
67
+ // Update all orders indexes where index is greater than the deleted one
68
+ for (const orderId in this._ordersMap) {
69
+ if (this._ordersMap[orderId] > deletedOrderIndex) {
70
+ this._ordersMap[orderId] -= 1;
71
+ }
72
+ }
73
+ };
74
+ updateOrderSize = (order, size) => {
75
+ this._volume += size - order.size; // update volume
76
+ order.size = size;
77
+ order.time = Date.now();
78
+ };
79
+ }
78
80
  exports.OrderQueue = OrderQueue;
@@ -1,158 +1,150 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
4
  };
16
5
  Object.defineProperty(exports, "__esModule", { value: true });
17
6
  exports.OrderSide = void 0;
18
7
  /* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
19
- var functional_red_black_tree_1 = __importDefault(require("functional-red-black-tree"));
20
- var errors_1 = require("./errors");
21
- var order_1 = require("./order");
22
- var orderqueue_1 = require("./orderqueue");
23
- var types_1 = require("./types");
24
- var OrderSide = /** @class */ (function () {
25
- function OrderSide(side) {
26
- var _this = this;
27
- this._prices = {};
28
- this._volume = 0;
29
- this._total = 0;
30
- this._numOrders = 0;
31
- this._depthSide = 0;
32
- this._side = types_1.Side.SELL;
33
- // returns amount of orders
34
- this.len = function () {
35
- return _this._numOrders;
36
- };
37
- // returns depth of market
38
- this.depth = function () {
39
- return _this._depthSide;
40
- };
41
- // returns total amount of quantity in side
42
- this.volume = function () {
43
- return _this._volume;
44
- };
45
- // returns the total (size * price of each price level) in side
46
- this.total = function () {
47
- return _this._total;
48
- };
49
- // returns the price tree in side
50
- this.priceTree = function () {
51
- return _this._priceTree;
52
- };
53
- // appends order to definite price level
54
- this.append = function (order) {
55
- var price = order.price;
56
- var strPrice = price.toString();
57
- if (_this._prices[strPrice] === undefined) {
58
- var priceQueue = new orderqueue_1.OrderQueue(price);
59
- _this._prices[strPrice] = priceQueue;
60
- _this._priceTree = _this._priceTree.insert(price, priceQueue);
61
- _this._depthSide += 1;
62
- }
63
- _this._numOrders += 1;
64
- _this._volume += order.size;
65
- _this._total += order.size * order.price;
66
- return _this._prices[strPrice].append(order);
67
- };
68
- // removes order from definite price level
69
- this.remove = function (order) {
70
- var price = order.price;
71
- var strPrice = price.toString();
72
- if (_this._prices[strPrice] === undefined) {
73
- throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_PRICE_LEVEL);
74
- }
75
- _this._prices[strPrice].remove(order);
76
- if (_this._prices[strPrice].len() === 0) {
77
- delete _this._prices[strPrice];
78
- _this._priceTree = _this._priceTree.remove(price);
79
- _this._depthSide -= 1;
80
- }
81
- _this._numOrders -= 1;
82
- _this._volume -= order.size;
83
- _this._total -= order.size * order.price;
84
- return order;
85
- };
86
- // Update the price of an order and return the order with the updated price
87
- this.updateOrderPrice = function (oldOrder, orderUpdate) {
88
- _this.remove(oldOrder);
89
- var newOrder = order_1.OrderFactory.createOrder(__assign(__assign({}, oldOrder.toObject()), { size: orderUpdate.size !== undefined ? orderUpdate.size : oldOrder.size, price: orderUpdate.price, time: Date.now() }));
90
- _this.append(newOrder);
91
- return newOrder;
92
- };
93
- // Update the price of an order and return the order with the updated price
94
- this.updateOrderSize = function (oldOrder, orderUpdate) {
95
- var _a;
96
- var newOrderPrice = (_a = orderUpdate.price) !== null && _a !== void 0 ? _a : oldOrder.price;
97
- _this._volume += orderUpdate.size - oldOrder.size;
98
- _this._total +=
99
- orderUpdate.size * newOrderPrice - oldOrder.size * oldOrder.price;
100
- _this._prices[oldOrder.price.toString()].updateOrderSize(oldOrder, orderUpdate.size);
101
- return oldOrder;
102
- };
103
- // returns max level of price
104
- this.maxPriceQueue = function () {
105
- if (_this._depthSide > 0) {
106
- var max = _this._side === types_1.Side.SELL ? _this._priceTree.end : _this._priceTree.begin;
107
- return max.value;
108
- }
109
- };
110
- // returns min level of price
111
- this.minPriceQueue = function () {
112
- if (_this._depthSide > 0) {
113
- var min = _this._side === types_1.Side.SELL ? _this._priceTree.begin : _this._priceTree.end;
114
- return min.value;
115
- }
116
- };
117
- // returns nearest OrderQueue with price less than given
118
- this.lowerThan = function (price) {
119
- var node = _this._side === types_1.Side.SELL
120
- ? _this._priceTree.lt(price)
121
- : _this._priceTree.gt(price);
122
- return node.value;
123
- };
124
- // returns nearest OrderQueue with price greater than given
125
- this.greaterThan = function (price) {
126
- var node = _this._side === types_1.Side.SELL
127
- ? _this._priceTree.gt(price)
128
- : _this._priceTree.lt(price);
129
- return node.value;
130
- };
131
- // returns all orders
132
- this.orders = function () {
133
- var orders = [];
134
- for (var price in _this._prices) {
135
- var allOrders = _this._prices[price].toArray();
136
- orders = orders.concat(allOrders);
137
- }
138
- return orders;
139
- };
140
- this.toString = function () {
141
- var s = "";
142
- var level = _this.maxPriceQueue();
143
- while (level !== undefined) {
144
- var volume = level.volume().toString();
145
- s += "\n".concat(level.price(), " -> ").concat(volume);
146
- level = _this.lowerThan(level.price());
147
- }
148
- return s;
149
- };
150
- var compare = side === types_1.Side.SELL
151
- ? function (a, b) { return a - b; }
152
- : function (a, b) { return b - a; };
8
+ const functional_red_black_tree_1 = __importDefault(require("functional-red-black-tree"));
9
+ const errors_1 = require("./errors");
10
+ const order_1 = require("./order");
11
+ const orderqueue_1 = require("./orderqueue");
12
+ const types_1 = require("./types");
13
+ class OrderSide {
14
+ _priceTree;
15
+ _prices = {};
16
+ _volume = 0;
17
+ _total = 0;
18
+ _numOrders = 0;
19
+ _depthSide = 0;
20
+ _side = types_1.Side.SELL;
21
+ constructor(side) {
22
+ const compare = side === types_1.Side.SELL
23
+ ? (a, b) => a - b
24
+ : (a, b) => b - a;
153
25
  this._priceTree = (0, functional_red_black_tree_1.default)(compare);
154
26
  this._side = side;
155
27
  }
156
- return OrderSide;
157
- }());
28
+ // returns amount of orders
29
+ len = () => {
30
+ return this._numOrders;
31
+ };
32
+ // returns depth of market
33
+ depth = () => {
34
+ return this._depthSide;
35
+ };
36
+ // returns total amount of quantity in side
37
+ volume = () => {
38
+ return this._volume;
39
+ };
40
+ // returns the total (size * price of each price level) in side
41
+ total = () => {
42
+ return this._total;
43
+ };
44
+ // returns the price tree in side
45
+ priceTree = () => {
46
+ return this._priceTree;
47
+ };
48
+ // appends order to definite price level
49
+ append = (order) => {
50
+ const price = order.price;
51
+ const strPrice = price.toString();
52
+ if (this._prices[strPrice] === undefined) {
53
+ const priceQueue = new orderqueue_1.OrderQueue(price);
54
+ this._prices[strPrice] = priceQueue;
55
+ this._priceTree = this._priceTree.insert(price, priceQueue);
56
+ this._depthSide += 1;
57
+ }
58
+ this._numOrders += 1;
59
+ this._volume += order.size;
60
+ this._total += order.size * order.price;
61
+ return this._prices[strPrice].append(order);
62
+ };
63
+ // removes order from definite price level
64
+ remove = (order) => {
65
+ const price = order.price;
66
+ const strPrice = price.toString();
67
+ if (this._prices[strPrice] === undefined) {
68
+ throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_PRICE_LEVEL);
69
+ }
70
+ this._prices[strPrice].remove(order);
71
+ if (this._prices[strPrice].len() === 0) {
72
+ delete this._prices[strPrice];
73
+ this._priceTree = this._priceTree.remove(price);
74
+ this._depthSide -= 1;
75
+ }
76
+ this._numOrders -= 1;
77
+ this._volume -= order.size;
78
+ this._total -= order.size * order.price;
79
+ return order;
80
+ };
81
+ // Update the price of an order and return the order with the updated price
82
+ updateOrderPrice = (oldOrder, orderUpdate) => {
83
+ this.remove(oldOrder);
84
+ const newOrder = order_1.OrderFactory.createOrder({
85
+ ...oldOrder.toObject(),
86
+ size: orderUpdate.size !== undefined ? orderUpdate.size : oldOrder.size,
87
+ price: orderUpdate.price,
88
+ time: Date.now(),
89
+ });
90
+ this.append(newOrder);
91
+ return newOrder;
92
+ };
93
+ // Update the price of an order and return the order with the updated price
94
+ updateOrderSize = (oldOrder, orderUpdate) => {
95
+ const newOrderPrice = orderUpdate.price ?? oldOrder.price;
96
+ this._volume += orderUpdate.size - oldOrder.size;
97
+ this._total +=
98
+ orderUpdate.size * newOrderPrice - oldOrder.size * oldOrder.price;
99
+ this._prices[oldOrder.price.toString()].updateOrderSize(oldOrder, orderUpdate.size);
100
+ return oldOrder;
101
+ };
102
+ // returns max level of price
103
+ maxPriceQueue = () => {
104
+ if (this._depthSide > 0) {
105
+ const max = this._side === types_1.Side.SELL ? this._priceTree.end : this._priceTree.begin;
106
+ return max.value;
107
+ }
108
+ };
109
+ // returns min level of price
110
+ minPriceQueue = () => {
111
+ if (this._depthSide > 0) {
112
+ const min = this._side === types_1.Side.SELL ? this._priceTree.begin : this._priceTree.end;
113
+ return min.value;
114
+ }
115
+ };
116
+ // returns nearest OrderQueue with price less than given
117
+ lowerThan = (price) => {
118
+ const node = this._side === types_1.Side.SELL
119
+ ? this._priceTree.lt(price)
120
+ : this._priceTree.gt(price);
121
+ return node.value;
122
+ };
123
+ // returns nearest OrderQueue with price greater than given
124
+ greaterThan = (price) => {
125
+ const node = this._side === types_1.Side.SELL
126
+ ? this._priceTree.gt(price)
127
+ : this._priceTree.lt(price);
128
+ return node.value;
129
+ };
130
+ // returns all orders
131
+ orders = () => {
132
+ let orders = [];
133
+ for (const price in this._prices) {
134
+ const allOrders = this._prices[price].toArray();
135
+ orders = orders.concat(allOrders);
136
+ }
137
+ return orders;
138
+ };
139
+ toString = () => {
140
+ let s = "";
141
+ let level = this.maxPriceQueue();
142
+ while (level !== undefined) {
143
+ const volume = level.volume().toString();
144
+ s += `\n${level.price()} -> ${volume}`;
145
+ level = this.lowerThan(level.price());
146
+ }
147
+ return s;
148
+ };
149
+ }
158
150
  exports.OrderSide = OrderSide;
@@ -1,76 +1,76 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StopBook = void 0;
4
- var stopside_1 = require("./stopside");
5
- var types_1 = require("./types");
6
- var StopBook = /** @class */ (function () {
7
- function StopBook() {
8
- var _this = this;
9
- this.add = function (order) {
10
- var stopSide = order.side === types_1.Side.BUY ? _this.bids : _this.asks;
11
- stopSide.append(order);
12
- };
13
- this.remove = function (side, id, stopPrice) {
14
- var stopSide = side === types_1.Side.BUY ? _this.bids : _this.asks;
15
- return stopSide.remove(id, stopPrice);
16
- };
17
- this.removePriceLevel = function (side, priceLevel) {
18
- var stopSide = side === types_1.Side.BUY ? _this.bids : _this.asks;
19
- stopSide.removePriceLevel(priceLevel);
20
- };
21
- this.getConditionalOrders = function (side, priceBefore, marketPrice) {
22
- var stopSide = side === types_1.Side.BUY ? _this.bids : _this.asks;
23
- return stopSide.between(priceBefore, marketPrice);
24
- };
25
- /**
26
- * Stop-Limit Order:
27
- * Buy: marketPrice < stopPrice <= price
28
- * Sell: marketPrice > stopPrice >= price
29
- * Stop-Market Order:
30
- * Buy: marketPrice < stopPrice
31
- * Sell: marketPrice > stopPrice
32
- */
33
- this.validConditionalOrder = function (marketPrice, order) {
34
- var response = false;
35
- var type = order.type, side = order.side, stopPrice = order.stopPrice;
36
- if (type === types_1.OrderType.STOP_LIMIT) {
37
- // Buy: marketPrice < stopPrice <= price
38
- if (side === types_1.Side.BUY &&
39
- marketPrice < stopPrice &&
40
- stopPrice <= order.price) {
41
- response = true;
42
- }
43
- // Sell: marketPrice > stopPrice >= price
44
- if (side === types_1.Side.SELL &&
45
- marketPrice > stopPrice &&
46
- stopPrice >= order.price) {
47
- response = true;
48
- }
49
- }
50
- else {
51
- // Buy: marketPrice < stopPrice
52
- if (side === types_1.Side.BUY && marketPrice < stopPrice)
53
- response = true;
54
- // Sell: marketPrice > stopPrice
55
- if (side === types_1.Side.SELL && marketPrice > stopPrice)
56
- response = true;
57
- }
58
- return response;
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
- };
4
+ const stopside_1 = require("./stopside");
5
+ const types_1 = require("./types");
6
+ class StopBook {
7
+ bids;
8
+ asks;
9
+ constructor() {
71
10
  this.bids = new stopside_1.StopSide(types_1.Side.BUY);
72
11
  this.asks = new stopside_1.StopSide(types_1.Side.SELL);
73
12
  }
74
- return StopBook;
75
- }());
13
+ add = (order) => {
14
+ const stopSide = order.side === types_1.Side.BUY ? this.bids : this.asks;
15
+ stopSide.append(order);
16
+ };
17
+ remove = (side, id, stopPrice) => {
18
+ const stopSide = side === types_1.Side.BUY ? this.bids : this.asks;
19
+ return stopSide.remove(id, stopPrice);
20
+ };
21
+ removePriceLevel = (side, priceLevel) => {
22
+ const stopSide = side === types_1.Side.BUY ? this.bids : this.asks;
23
+ stopSide.removePriceLevel(priceLevel);
24
+ };
25
+ getConditionalOrders = (side, priceBefore, marketPrice) => {
26
+ const stopSide = side === types_1.Side.BUY ? this.bids : this.asks;
27
+ return stopSide.between(priceBefore, marketPrice);
28
+ };
29
+ /**
30
+ * Stop-Limit Order:
31
+ * Buy: marketPrice < stopPrice <= price
32
+ * Sell: marketPrice > stopPrice >= price
33
+ * Stop-Market Order:
34
+ * Buy: marketPrice < stopPrice
35
+ * Sell: marketPrice > stopPrice
36
+ */
37
+ validConditionalOrder = (marketPrice, order) => {
38
+ let response = false;
39
+ const { type, side, stopPrice } = order;
40
+ if (type === types_1.OrderType.STOP_LIMIT) {
41
+ // Buy: marketPrice < stopPrice <= price
42
+ if (side === types_1.Side.BUY &&
43
+ marketPrice < stopPrice &&
44
+ stopPrice <= order.price) {
45
+ response = true;
46
+ }
47
+ // Sell: marketPrice > stopPrice >= price
48
+ if (side === types_1.Side.SELL &&
49
+ marketPrice > stopPrice &&
50
+ stopPrice >= order.price) {
51
+ response = true;
52
+ }
53
+ }
54
+ else {
55
+ // Buy: marketPrice < stopPrice
56
+ if (side === types_1.Side.BUY && marketPrice < stopPrice)
57
+ response = true;
58
+ // Sell: marketPrice > stopPrice
59
+ if (side === types_1.Side.SELL && marketPrice > stopPrice)
60
+ response = true;
61
+ }
62
+ return response;
63
+ };
64
+ snapshot = () => {
65
+ const bids = [];
66
+ const asks = [];
67
+ this.bids.priceTree().forEach((price, orders) => {
68
+ bids.push({ price, orders: orders.toArray().map((o) => o.toObject()) });
69
+ });
70
+ this.asks.priceTree().forEach((price, orders) => {
71
+ asks.push({ price, orders: orders.toArray().map((o) => o.toObject()) });
72
+ });
73
+ return { bids, asks };
74
+ };
75
+ }
76
76
  exports.StopBook = StopBook;
@@ -5,58 +5,54 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.StopQueue = void 0;
7
7
  /* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
8
- var denque_1 = __importDefault(require("denque"));
9
- var StopQueue = /** @class */ (function () {
10
- function StopQueue(price) {
11
- var _this = this;
12
- this._ordersMap = {};
13
- // returns the number of orders in queue
14
- this.len = function () {
15
- return _this._orders.length;
16
- };
17
- // remove order from head of queue
18
- this.removeFromHead = function () {
19
- // We can't use the shift method here because we need
20
- // to update index in the map, so we use the remove(id) function
21
- var order = _this._orders.peekFront();
22
- if (order === undefined)
23
- return;
24
- return _this.remove(order.id);
25
- };
26
- // adds order to tail of the queue
27
- this.append = function (order) {
28
- _this._orders.push(order);
29
- _this._ordersMap[order.id] = _this._orders.length - 1;
30
- return order;
31
- };
32
- // removes order from the queue
33
- this.remove = function (id) {
34
- var deletedOrderIndex = _this._ordersMap[id];
35
- if (deletedOrderIndex === undefined)
36
- return;
37
- var deletedOrder = _this._orders.removeOne(deletedOrderIndex);
38
- delete _this._ordersMap[id];
39
- // Update all orders indexes where index is greater than the deleted one
40
- for (var orderId in _this._ordersMap) {
41
- if (_this._ordersMap[orderId] > deletedOrderIndex) {
42
- _this._ordersMap[orderId] -= 1;
43
- }
44
- }
45
- return deletedOrder;
46
- };
47
- this.toArray = function () {
48
- return _this._orders.toArray();
49
- };
8
+ const denque_1 = __importDefault(require("denque"));
9
+ class StopQueue {
10
+ _price;
11
+ _orders;
12
+ _ordersMap = {};
13
+ constructor(price) {
50
14
  this._price = price;
51
15
  this._orders = new denque_1.default();
52
16
  }
53
- Object.defineProperty(StopQueue.prototype, "price", {
54
- get: function () {
55
- return this._price;
56
- },
57
- enumerable: false,
58
- configurable: true
59
- });
60
- return StopQueue;
61
- }());
17
+ get price() {
18
+ return this._price;
19
+ }
20
+ // returns the number of orders in queue
21
+ len = () => {
22
+ return this._orders.length;
23
+ };
24
+ // remove order from head of queue
25
+ removeFromHead = () => {
26
+ // We can't use the shift method here because we need
27
+ // to update index in the map, so we use the remove(id) function
28
+ const order = this._orders.peekFront();
29
+ if (order === undefined)
30
+ return;
31
+ return this.remove(order.id);
32
+ };
33
+ // adds order to tail of the queue
34
+ append = (order) => {
35
+ this._orders.push(order);
36
+ this._ordersMap[order.id] = this._orders.length - 1;
37
+ return order;
38
+ };
39
+ // removes order from the queue
40
+ remove = (id) => {
41
+ const deletedOrderIndex = this._ordersMap[id];
42
+ if (deletedOrderIndex === undefined)
43
+ return;
44
+ const deletedOrder = this._orders.removeOne(deletedOrderIndex);
45
+ delete this._ordersMap[id];
46
+ // Update all orders indexes where index is greater than the deleted one
47
+ for (const orderId in this._ordersMap) {
48
+ if (this._ordersMap[orderId] > deletedOrderIndex) {
49
+ this._ordersMap[orderId] -= 1;
50
+ }
51
+ }
52
+ return deletedOrder;
53
+ };
54
+ toArray = () => {
55
+ return this._orders.toArray();
56
+ };
57
+ }
62
58
  exports.StopQueue = StopQueue;