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,75 +5,75 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.StopSide = void 0;
7
7
  /* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
8
- var functional_red_black_tree_1 = __importDefault(require("functional-red-black-tree"));
9
- var errors_1 = require("./errors");
10
- var stopqueue_1 = require("./stopqueue");
11
- var types_1 = require("./types");
12
- var StopSide = /** @class */ (function () {
13
- function StopSide(side) {
14
- var _this = this;
15
- this._prices = {};
16
- // appends order to definite price level
17
- this.append = function (order) {
18
- var price = order.stopPrice;
19
- var strPrice = price.toString();
20
- if (_this._prices[strPrice] === undefined) {
21
- var priceQueue = new stopqueue_1.StopQueue(price);
22
- _this._prices[strPrice] = priceQueue;
23
- _this._priceTree = _this._priceTree.insert(price, priceQueue);
24
- }
25
- return _this._prices[strPrice].append(order);
26
- };
27
- // removes order from definite price level
28
- this.remove = function (id, stopPrice) {
29
- var strPrice = stopPrice.toString();
30
- if (_this._prices[strPrice] === undefined) {
31
- throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_PRICE_LEVEL);
32
- }
33
- var deletedOrder = _this._prices[strPrice].remove(id);
34
- if (_this._prices[strPrice].len() === 0) {
35
- delete _this._prices[strPrice];
36
- _this._priceTree = _this._priceTree.remove(stopPrice);
37
- }
38
- return deletedOrder;
39
- };
40
- this.removePriceLevel = function (priceLevel) {
41
- delete _this._prices[priceLevel.toString()];
42
- _this._priceTree = _this._priceTree.remove(priceLevel);
43
- };
44
- // Get orders queue between two price levels
45
- this.between = function (priceBefore, marketPrice) {
46
- var queues = [];
47
- var lowerBound = priceBefore;
48
- var upperBound = marketPrice;
49
- var highest = Math.max(priceBefore, marketPrice);
50
- var lowest = Math.min(priceBefore, marketPrice);
51
- if (_this._side === types_1.Side.BUY) {
52
- lowerBound = highest;
53
- upperBound = lowest - 1;
54
- }
55
- else {
56
- lowerBound = lowest;
57
- upperBound = highest + 1;
58
- }
59
- _this._priceTree.forEach(function (price, queue) {
60
- if ((_this._side === types_1.Side.BUY && price >= lowest) ||
61
- (_this._side === types_1.Side.SELL && price <= highest)) {
62
- queues.push(queue);
63
- }
64
- }, lowerBound, // Inclusive
65
- upperBound);
66
- return queues;
67
- };
68
- this.priceTree = function () {
69
- return _this._priceTree;
70
- };
71
- var compare = side === types_1.Side.SELL
72
- ? function (a, b) { return a - b; }
73
- : 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 stopqueue_1 = require("./stopqueue");
11
+ const types_1 = require("./types");
12
+ class StopSide {
13
+ _priceTree;
14
+ _prices = {};
15
+ _side;
16
+ constructor(side) {
17
+ const compare = side === types_1.Side.SELL
18
+ ? (a, b) => a - b
19
+ : (a, b) => b - a;
74
20
  this._priceTree = (0, functional_red_black_tree_1.default)(compare);
75
21
  this._side = side;
76
22
  }
77
- return StopSide;
78
- }());
23
+ // appends order to definite price level
24
+ append = (order) => {
25
+ const price = order.stopPrice;
26
+ const strPrice = price.toString();
27
+ if (this._prices[strPrice] === undefined) {
28
+ const priceQueue = new stopqueue_1.StopQueue(price);
29
+ this._prices[strPrice] = priceQueue;
30
+ this._priceTree = this._priceTree.insert(price, priceQueue);
31
+ }
32
+ return this._prices[strPrice].append(order);
33
+ };
34
+ // removes order from definite price level
35
+ remove = (id, stopPrice) => {
36
+ const strPrice = stopPrice.toString();
37
+ if (this._prices[strPrice] === undefined) {
38
+ throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_PRICE_LEVEL);
39
+ }
40
+ const deletedOrder = this._prices[strPrice].remove(id);
41
+ if (this._prices[strPrice].len() === 0) {
42
+ delete this._prices[strPrice];
43
+ this._priceTree = this._priceTree.remove(stopPrice);
44
+ }
45
+ return deletedOrder;
46
+ };
47
+ removePriceLevel = (priceLevel) => {
48
+ delete this._prices[priceLevel.toString()];
49
+ this._priceTree = this._priceTree.remove(priceLevel);
50
+ };
51
+ // Get orders queue between two price levels
52
+ between = (priceBefore, marketPrice) => {
53
+ const queues = [];
54
+ let lowerBound = priceBefore;
55
+ let upperBound = marketPrice;
56
+ const highest = Math.max(priceBefore, marketPrice);
57
+ const lowest = Math.min(priceBefore, marketPrice);
58
+ if (this._side === types_1.Side.BUY) {
59
+ lowerBound = highest;
60
+ upperBound = lowest - 1;
61
+ }
62
+ else {
63
+ lowerBound = lowest;
64
+ upperBound = highest + 1;
65
+ }
66
+ this._priceTree.forEach((price, queue) => {
67
+ if ((this._side === types_1.Side.BUY && price >= lowest) ||
68
+ (this._side === types_1.Side.SELL && price <= highest)) {
69
+ queues.push(queue);
70
+ }
71
+ }, lowerBound, // Inclusive
72
+ upperBound);
73
+ return queues;
74
+ };
75
+ priceTree = () => {
76
+ return this._priceTree;
77
+ };
78
+ }
79
79
  exports.StopSide = StopSide;
package/dist/cjs/types.js CHANGED
@@ -1,11 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimeInForce = exports.OrderType = exports.Side = void 0;
3
+ exports.TimeInForce = exports.OrderType = exports.SelfTradePreventionMode = exports.Side = void 0;
4
4
  var Side;
5
5
  (function (Side) {
6
6
  Side["BUY"] = "buy";
7
7
  Side["SELL"] = "sell";
8
8
  })(Side || (exports.Side = Side = {}));
9
+ var SelfTradePreventionMode;
10
+ (function (SelfTradePreventionMode) {
11
+ SelfTradePreventionMode["NONE"] = "NONE";
12
+ SelfTradePreventionMode["EXPIRE_TAKER"] = "EXPIRE_TAKER";
13
+ SelfTradePreventionMode["EXPIRE_MAKER"] = "EXPIRE_MAKER";
14
+ SelfTradePreventionMode["EXPIRE_BOTH"] = "EXPIRE_BOTH";
15
+ })(SelfTradePreventionMode || (exports.SelfTradePreventionMode = SelfTradePreventionMode = {}));
9
16
  var OrderType;
10
17
  (function (OrderType) {
11
18
  OrderType["LIMIT"] = "limit";
package/dist/cjs/utils.js CHANGED
@@ -2,22 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.safeParse = exports.safeStringify = void 0;
4
4
  /* node:coverage ignore next - Don't know why this line is uncovered */
5
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
6
- var safeStringify = function (value) {
5
+ const safeStringify = (value) => {
7
6
  try {
8
7
  return JSON.stringify(value);
9
8
  }
10
- catch (error) {
9
+ catch (_error) {
11
10
  return null;
12
11
  }
13
12
  };
14
13
  exports.safeStringify = safeStringify;
15
14
  /* node:coverage ignore next - Don't know why this line is uncovered */
16
- var safeParse = function (value) {
15
+ const safeParse = (value) => {
17
16
  try {
18
17
  return JSON.parse(value);
19
18
  }
20
- catch (error) {
19
+ catch (_error) {
21
20
  return null;
22
21
  }
23
22
  };
@@ -1,4 +1,3 @@
1
- var _a, _b;
2
1
  export var ERROR;
3
2
  (function (ERROR) {
4
3
  ERROR["DEFAULT"] = "DEFAULT";
@@ -16,62 +15,64 @@ export var ERROR;
16
15
  ERROR["LIMIT_ORDER_POST_ONLY"] = "LIMIT_ORDER_POST_ONLY";
17
16
  ERROR["ORDER_ALREDY_EXISTS"] = "ORDER_ALREDY_EXISTS";
18
17
  ERROR["ORDER_NOT_FOUND"] = "ORDER_NOT_FOUND";
18
+ ERROR["STP_TRIGGERED"] = "STP_TRIGGERED";
19
19
  })(ERROR || (ERROR = {}));
20
- export var ErrorCodes = (_a = {},
20
+ export const ErrorCodes = {
21
21
  // 10xx General issues
22
- _a[ERROR.DEFAULT] = 1000,
22
+ [ERROR.DEFAULT]: 1000,
23
23
  // 11xx Request issues
24
- _a[ERROR.INVALID_ORDER_TYPE] = 1100,
25
- _a[ERROR.INVALID_SIDE] = 1101,
26
- _a[ERROR.INVALID_QUANTITY] = 1102,
27
- _a[ERROR.INVALID_PRICE] = 1103,
28
- _a[ERROR.INVALID_PRICE_OR_QUANTITY] = 1104,
29
- _a[ERROR.INVALID_TIF] = 1105,
30
- _a[ERROR.LIMIT_ORDER_FOK_NOT_FILLABLE] = 1106,
31
- _a[ERROR.LIMIT_ORDER_POST_ONLY] = 1107,
32
- _a[ERROR.INVALID_CONDITIONAL_ORDER] = 1108,
33
- _a[ERROR.ORDER_ALREDY_EXISTS] = 1109,
34
- _a[ERROR.ORDER_NOT_FOUND] = 1110,
24
+ [ERROR.INVALID_ORDER_TYPE]: 1100,
25
+ [ERROR.INVALID_SIDE]: 1101,
26
+ [ERROR.INVALID_QUANTITY]: 1102,
27
+ [ERROR.INVALID_PRICE]: 1103,
28
+ [ERROR.INVALID_PRICE_OR_QUANTITY]: 1104,
29
+ [ERROR.INVALID_TIF]: 1105,
30
+ [ERROR.LIMIT_ORDER_FOK_NOT_FILLABLE]: 1106,
31
+ [ERROR.LIMIT_ORDER_POST_ONLY]: 1107,
32
+ [ERROR.INVALID_CONDITIONAL_ORDER]: 1108,
33
+ [ERROR.ORDER_ALREDY_EXISTS]: 1109,
34
+ [ERROR.ORDER_NOT_FOUND]: 1110,
35
35
  // 12xx Internal error
36
- _a[ERROR.INSUFFICIENT_QUANTITY] = 1200,
37
- _a[ERROR.INVALID_PRICE_LEVEL] = 1201,
38
- _a[ERROR.INVALID_JOURNAL_LOG] = 1201,
39
- _a);
40
- export var ErrorMessages = (_b = {},
41
- _b[ERROR.DEFAULT] = "Something wrong",
42
- _b[ERROR.INSUFFICIENT_QUANTITY] = "Insufficient quantity to calculate price",
43
- _b[ERROR.INVALID_CONDITIONAL_ORDER] = "Stop-Limit Order (BUY: marketPrice < stopPrice <= price, SELL: marketPrice > stopPrice >= price). Stop-Market Order (BUY: marketPrice < stopPrice, SELL: marketPrice > stopPrice). OCO order (BUY: price < marketPrice < stopPrice, SELL: price > marketPrice > stopPrice)",
44
- _b[ERROR.INVALID_ORDER_TYPE] = "Supported order type are 'limit' and 'market'",
45
- _b[ERROR.INVALID_PRICE] = "Invalid order price",
46
- _b[ERROR.INVALID_PRICE_LEVEL] = "Invalid order price level",
47
- _b[ERROR.INVALID_PRICE_OR_QUANTITY] = "Invalid order price or quantity",
48
- _b[ERROR.INVALID_QUANTITY] = "Invalid order quantity",
49
- _b[ERROR.INVALID_SIDE] = "Invalid side: must be either 'sell' or 'buy'",
50
- _b[ERROR.INVALID_TIF] = "Invalid TimeInForce: must be one of 'GTC', 'IOC' or 'FOK'",
51
- _b[ERROR.LIMIT_ORDER_FOK_NOT_FILLABLE] = "Limit FOK order not fillable",
52
- _b[ERROR.LIMIT_ORDER_POST_ONLY] = "Post-only limit order rejected because would execute immediately",
53
- _b[ERROR.ORDER_ALREDY_EXISTS] = "Order already exists",
54
- _b[ERROR.ORDER_NOT_FOUND] = "Order not found",
55
- _b[ERROR.INVALID_JOURNAL_LOG] = "Invalid journal log format",
56
- _b);
57
- var OrderBookError = /** @class */ (function () {
58
- function OrderBookError(error) {
59
- var _a;
60
- var errorMessage;
36
+ [ERROR.INSUFFICIENT_QUANTITY]: 1200,
37
+ [ERROR.INVALID_PRICE_LEVEL]: 1201,
38
+ [ERROR.INVALID_JOURNAL_LOG]: 1201,
39
+ [ERROR.STP_TRIGGERED]: 1202,
40
+ };
41
+ export const ErrorMessages = {
42
+ [ERROR.DEFAULT]: "Something wrong",
43
+ [ERROR.INSUFFICIENT_QUANTITY]: "Insufficient quantity to calculate price",
44
+ [ERROR.INVALID_CONDITIONAL_ORDER]: "Stop-Limit Order (BUY: marketPrice < stopPrice <= price, SELL: marketPrice > stopPrice >= price). Stop-Market Order (BUY: marketPrice < stopPrice, SELL: marketPrice > stopPrice). OCO order (BUY: price < marketPrice < stopPrice, SELL: price > marketPrice > stopPrice)",
45
+ [ERROR.INVALID_ORDER_TYPE]: "Supported order type are 'limit' and 'market'",
46
+ [ERROR.INVALID_PRICE]: "Invalid order price",
47
+ [ERROR.INVALID_PRICE_LEVEL]: "Invalid order price level",
48
+ [ERROR.INVALID_PRICE_OR_QUANTITY]: "Invalid order price or quantity",
49
+ [ERROR.INVALID_QUANTITY]: "Invalid order quantity",
50
+ [ERROR.INVALID_SIDE]: "Invalid side: must be either 'sell' or 'buy'",
51
+ [ERROR.INVALID_TIF]: "Invalid TimeInForce: must be one of 'GTC', 'IOC' or 'FOK'",
52
+ [ERROR.LIMIT_ORDER_FOK_NOT_FILLABLE]: "Limit FOK order not fillable",
53
+ [ERROR.LIMIT_ORDER_POST_ONLY]: "Post-only limit order rejected because would execute immediately",
54
+ [ERROR.ORDER_ALREDY_EXISTS]: "Order already exists",
55
+ [ERROR.ORDER_NOT_FOUND]: "Order not found",
56
+ [ERROR.INVALID_JOURNAL_LOG]: "Invalid journal log format",
57
+ [ERROR.STP_TRIGGERED]: "Self-trade prevention triggered",
58
+ };
59
+ export class OrderBookError {
60
+ message;
61
+ code;
62
+ constructor(error) {
63
+ let errorMessage;
61
64
  if (error != null && ErrorMessages[error] != null) {
62
65
  errorMessage = ErrorMessages[error];
63
66
  }
64
67
  else {
65
- var customMessage = error === undefined || error === "" ? "" : ": ".concat(error);
66
- errorMessage = "".concat(ErrorMessages.DEFAULT).concat(customMessage);
68
+ const customMessage = error === undefined || error === "" ? "" : `: ${error}`;
69
+ errorMessage = `${ErrorMessages.DEFAULT}${customMessage}`;
67
70
  }
68
71
  this.message = errorMessage;
69
- this.code = (_a = ErrorCodes[error]) !== null && _a !== void 0 ? _a : ErrorCodes[ERROR.DEFAULT];
72
+ this.code = ErrorCodes[error] ?? ErrorCodes[ERROR.DEFAULT];
70
73
  }
71
- return OrderBookError;
72
- }());
73
- export { OrderBookError };
74
+ }
74
75
  /* node:coverage ignore next - Don't know why this line is uncoverd */
75
- export var CustomError = function (error) {
76
+ export const CustomError = (error) => {
76
77
  return new OrderBookError(error);
77
78
  };
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* node:coverage disable */
2
2
  import { OrderBook } from "./orderbook";
3
- import { OrderType, Side } from "./types";
4
- export { OrderBook, OrderType, Side, };
3
+ import { OrderType, SelfTradePreventionMode, Side } from "./types";
4
+ export { OrderBook, OrderType, SelfTradePreventionMode, Side, };
5
5
  /* node:coverage enable */