nodejs-order-book 8.0.1 → 8.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 +29 -1
- package/dist/cjs/orderbook.js +130 -109
- package/dist/esm/orderbook.js +130 -109
- package/dist/types/orderbook.d.ts +1 -45
- package/dist/types/types.d.ts +53 -15
- package/dist/umd/index.js +1 -1
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -13,6 +13,34 @@ Ultra-fast Node.js Order Book written in TypeScript for high-frequency trading (
|
|
|
13
13
|
|
|
14
14
|
:star: Star me on GitHub — it motivates me a lot!
|
|
15
15
|
|
|
16
|
+
## Table of Contents
|
|
17
|
+
|
|
18
|
+
- [Features](#features)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Usage](#usage)
|
|
21
|
+
- [Experimental Conditional Orders](#conditional-orders-)
|
|
22
|
+
- [About Primary Functions](#about-primary-functions)
|
|
23
|
+
- [Create order `createOrder()`](#create-order)
|
|
24
|
+
- [Create Limit order `limit()`](#create-limit-order)
|
|
25
|
+
- [Create Market order `market()`](#create-market-order)
|
|
26
|
+
- [Create Stop Limit order `stopLimit()`](#create-stop-limit-order)
|
|
27
|
+
- [Create Stop Market order `stopMarket()`](#create-stop-market-order)
|
|
28
|
+
- [Create OCO (One-Cancels-the-Other) order `oco()`](#create-oco-one-cancels-the-other-order)
|
|
29
|
+
- [Modify an existing order `modifiy()`](#modify-an-existing-order)
|
|
30
|
+
- [Cancel order `cancel()`](#cancel-order)
|
|
31
|
+
- [Order Book Options](#order-book-options)
|
|
32
|
+
- [Snapshot](#snapshot)
|
|
33
|
+
- [Journal Logs](#journal-logs)
|
|
34
|
+
- [Enable Journaling](#enable-journaling)
|
|
35
|
+
- [Development](#development)
|
|
36
|
+
- [Build](#build)
|
|
37
|
+
- [Testing](#testing)
|
|
38
|
+
- [Coverage](#coverage)
|
|
39
|
+
- [Benchmarking](#benchmarking)
|
|
40
|
+
- [Contributing](#contributing)
|
|
41
|
+
- [Donation](#donation)
|
|
42
|
+
- [License](#license)
|
|
43
|
+
|
|
16
44
|
## Features
|
|
17
45
|
|
|
18
46
|
- Standard price-time priority
|
|
@@ -348,7 +376,7 @@ bids: 90 -> 5 90 -> 5
|
|
|
348
376
|
80 -> 1 80 -> 1
|
|
349
377
|
```
|
|
350
378
|
|
|
351
|
-
## Options
|
|
379
|
+
## Order Book Options
|
|
352
380
|
|
|
353
381
|
The orderbook can be initialized with the following options by passing them to the constructor:
|
|
354
382
|
|
package/dist/cjs/orderbook.js
CHANGED
|
@@ -47,7 +47,16 @@ var OrderBook = /** @class */ (function () {
|
|
|
47
47
|
/* node:coverage ignore next 4 - We don't need test for this */
|
|
48
48
|
if (!_this.experimentalConditionalOrders)
|
|
49
49
|
throw new Error("In order to use conditional orders you need to instantiate the order book with the `experimentalConditionalOrders` option set to true");
|
|
50
|
-
|
|
50
|
+
var response = _this._stopMarket(options);
|
|
51
|
+
if (_this.enableJournaling && response.err === null) {
|
|
52
|
+
response.log = {
|
|
53
|
+
opId: ++_this._lastOp,
|
|
54
|
+
ts: Date.now(),
|
|
55
|
+
op: "sm",
|
|
56
|
+
o: options,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return response;
|
|
51
60
|
};
|
|
52
61
|
/**
|
|
53
62
|
* Create a stop limit order. See {@link StopLimitOrderOptions} for details.
|
|
@@ -65,7 +74,16 @@ var OrderBook = /** @class */ (function () {
|
|
|
65
74
|
/* node:coverage ignore next 4 - We don't need test for this */
|
|
66
75
|
if (!_this.experimentalConditionalOrders)
|
|
67
76
|
throw new Error("In order to use conditional orders you need to instantiate the order book with the `experimentalConditionalOrders` option set to true");
|
|
68
|
-
|
|
77
|
+
var response = _this._stopLimit(options);
|
|
78
|
+
if (_this.enableJournaling && response.err === null) {
|
|
79
|
+
response.log = {
|
|
80
|
+
opId: ++_this._lastOp,
|
|
81
|
+
ts: Date.now(),
|
|
82
|
+
op: "sl",
|
|
83
|
+
o: options,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return response;
|
|
69
87
|
};
|
|
70
88
|
/**
|
|
71
89
|
* Create an OCO (One-Cancels-the-Other) order.
|
|
@@ -94,7 +112,16 @@ var OrderBook = /** @class */ (function () {
|
|
|
94
112
|
/* node:coverage ignore next 4 - We don't need test for this */
|
|
95
113
|
if (!_this.experimentalConditionalOrders)
|
|
96
114
|
throw new Error("In order to use conditional orders you need to instantiate the order book with the `experimentalConditionalOrders` option set to true");
|
|
97
|
-
|
|
115
|
+
var response = _this._oco(options);
|
|
116
|
+
if (_this.enableJournaling && response.err === null) {
|
|
117
|
+
response.log = {
|
|
118
|
+
opId: ++_this._lastOp,
|
|
119
|
+
ts: Date.now(),
|
|
120
|
+
op: "oco",
|
|
121
|
+
o: options,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return response;
|
|
98
125
|
};
|
|
99
126
|
/**
|
|
100
127
|
* Modify an existing order with given ID. When an order is modified by price or quantity,
|
|
@@ -228,7 +255,7 @@ var OrderBook = /** @class */ (function () {
|
|
|
228
255
|
};
|
|
229
256
|
this._market = function (options, incomingResponse) {
|
|
230
257
|
var response = incomingResponse !== null && incomingResponse !== void 0 ? incomingResponse : _this.validateMarketOrder(options);
|
|
231
|
-
if (response.err
|
|
258
|
+
if (response.err !== null)
|
|
232
259
|
return response;
|
|
233
260
|
var quantityToTrade = options.size;
|
|
234
261
|
var iter;
|
|
@@ -253,41 +280,19 @@ var OrderBook = /** @class */ (function () {
|
|
|
253
280
|
}
|
|
254
281
|
response.quantityLeft = quantityToTrade;
|
|
255
282
|
_this.executeConditionalOrder(options.side, priceBefore, response);
|
|
256
|
-
if (_this.enableJournaling) {
|
|
257
|
-
response.log = {
|
|
258
|
-
opId: ++_this._lastOp,
|
|
259
|
-
ts: Date.now(),
|
|
260
|
-
op: "m",
|
|
261
|
-
o: { side: options.side, size: options.size },
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
283
|
return response;
|
|
265
284
|
};
|
|
266
285
|
this._limit = function (options, incomingResponse) {
|
|
267
286
|
var _a, _b;
|
|
268
287
|
var response = incomingResponse !== null && incomingResponse !== void 0 ? incomingResponse : _this.validateLimitOrder(options);
|
|
269
|
-
if (response.err
|
|
288
|
+
if (response.err !== null)
|
|
270
289
|
return response;
|
|
271
|
-
|
|
272
|
-
if (_this.enableJournaling && order != null) {
|
|
273
|
-
response.log = {
|
|
274
|
-
opId: ++_this._lastOp,
|
|
275
|
-
ts: Date.now(),
|
|
276
|
-
op: "l",
|
|
277
|
-
o: {
|
|
278
|
-
side: order.side,
|
|
279
|
-
id: order.id,
|
|
280
|
-
size: order.size,
|
|
281
|
-
price: order.price,
|
|
282
|
-
timeInForce: order.timeInForce,
|
|
283
|
-
},
|
|
284
|
-
};
|
|
285
|
-
}
|
|
290
|
+
_this.createLimitOrder(response, options.side, options.id, options.size, options.price, (_a = options.postOnly) !== null && _a !== void 0 ? _a : false, (_b = options.timeInForce) !== null && _b !== void 0 ? _b : types_1.TimeInForce.GTC, options.ocoStopPrice);
|
|
286
291
|
return response;
|
|
287
292
|
};
|
|
288
293
|
this._stopMarket = function (options) {
|
|
289
294
|
var response = _this.validateMarketOrder(options);
|
|
290
|
-
if (response.err
|
|
295
|
+
if (response.err !== null)
|
|
291
296
|
return response;
|
|
292
297
|
var stopMarket = order_1.OrderFactory.createOrder(__assign(__assign({}, options), { type: types_1.OrderType.STOP_MARKET }));
|
|
293
298
|
return _this._stopOrder(stopMarket, response);
|
|
@@ -295,7 +300,7 @@ var OrderBook = /** @class */ (function () {
|
|
|
295
300
|
this._stopLimit = function (options) {
|
|
296
301
|
var _a;
|
|
297
302
|
var response = _this.validateLimitOrder(options);
|
|
298
|
-
if (response.err
|
|
303
|
+
if (response.err !== null)
|
|
299
304
|
return response;
|
|
300
305
|
var stopLimit = order_1.OrderFactory.createOrder(__assign(__assign({}, options), { type: types_1.OrderType.STOP_LIMIT, timeInForce: (_a = options.timeInForce) !== null && _a !== void 0 ? _a : types_1.TimeInForce.GTC }));
|
|
301
306
|
return _this._stopOrder(stopLimit, response);
|
|
@@ -304,7 +309,7 @@ var OrderBook = /** @class */ (function () {
|
|
|
304
309
|
var _a;
|
|
305
310
|
var response = _this.validateLimitOrder(options);
|
|
306
311
|
/* node:coverage ignore next - Already validated with limit test */
|
|
307
|
-
if (response.err
|
|
312
|
+
if (response.err !== null)
|
|
308
313
|
return response;
|
|
309
314
|
if (_this.validateOCOOrder(options)) {
|
|
310
315
|
// We use the same ID for Stop Limit and Limit Order, since
|
|
@@ -318,7 +323,7 @@ var OrderBook = /** @class */ (function () {
|
|
|
318
323
|
ocoStopPrice: options.stopPrice,
|
|
319
324
|
}, response);
|
|
320
325
|
/* node:coverage ignore next - Already validated with limit test */
|
|
321
|
-
if (response.err
|
|
326
|
+
if (response.err !== null)
|
|
322
327
|
return response;
|
|
323
328
|
var stopLimit = order_1.OrderFactory.createOrder({
|
|
324
329
|
type: types_1.OrderType.STOP_LIMIT,
|
|
@@ -546,21 +551,48 @@ var OrderBook = /** @class */ (function () {
|
|
|
546
551
|
if (side == null || size == null) {
|
|
547
552
|
throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_JOURNAL_LOG);
|
|
548
553
|
}
|
|
549
|
-
_this.market(
|
|
554
|
+
_this.market(log.o);
|
|
550
555
|
break;
|
|
551
556
|
}
|
|
552
557
|
case "l": {
|
|
553
|
-
var _b = log.o, side = _b.side, id = _b.id, size = _b.size, price = _b.price
|
|
558
|
+
var _b = log.o, side = _b.side, id = _b.id, size = _b.size, price = _b.price;
|
|
554
559
|
if (side == null || id == null || size == null || price == null) {
|
|
555
560
|
throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_JOURNAL_LOG);
|
|
556
561
|
}
|
|
557
|
-
_this.limit(
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
562
|
+
_this.limit(log.o);
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
565
|
+
case "sm": {
|
|
566
|
+
var _c = log.o, side = _c.side, size = _c.size, stopPrice = _c.stopPrice;
|
|
567
|
+
if (side == null || size == null || stopPrice == null) {
|
|
568
|
+
throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_JOURNAL_LOG);
|
|
569
|
+
}
|
|
570
|
+
_this.stopMarket(log.o);
|
|
571
|
+
break;
|
|
572
|
+
}
|
|
573
|
+
case "sl": {
|
|
574
|
+
var _d = log.o, side = _d.side, id = _d.id, size = _d.size, price = _d.price, stopPrice = _d.stopPrice;
|
|
575
|
+
if (side == null ||
|
|
576
|
+
id == null ||
|
|
577
|
+
size == null ||
|
|
578
|
+
price == null ||
|
|
579
|
+
stopPrice == null) {
|
|
580
|
+
throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_JOURNAL_LOG);
|
|
581
|
+
}
|
|
582
|
+
_this.stopLimit(log.o);
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
case "oco": {
|
|
586
|
+
var _e = log.o, side = _e.side, id = _e.id, size = _e.size, price = _e.price, stopPrice = _e.stopPrice, stopLimitPrice = _e.stopLimitPrice;
|
|
587
|
+
if (side == null ||
|
|
588
|
+
id == null ||
|
|
589
|
+
size == null ||
|
|
590
|
+
price == null ||
|
|
591
|
+
stopPrice == null ||
|
|
592
|
+
stopLimitPrice == null) {
|
|
593
|
+
throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_JOURNAL_LOG);
|
|
594
|
+
}
|
|
595
|
+
_this.oco(log.o);
|
|
564
596
|
break;
|
|
565
597
|
}
|
|
566
598
|
case "d":
|
|
@@ -751,40 +783,23 @@ var OrderBook = /** @class */ (function () {
|
|
|
751
783
|
enumerable: false,
|
|
752
784
|
configurable: true
|
|
753
785
|
});
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
// @ts-expect-error
|
|
772
|
-
stopPrice: stopPrice,
|
|
773
|
-
// @ts-expect-error
|
|
774
|
-
stopLimitPrice: stopLimitPrice,
|
|
775
|
-
stopLimitTimeInForce: stopLimitTimeInForce,
|
|
776
|
-
postOnly: postOnly,
|
|
777
|
-
};
|
|
778
|
-
/* node:coverage enable */
|
|
779
|
-
}
|
|
780
|
-
else if (typeof typeOrOptions === "object") {
|
|
781
|
-
options = typeOrOptions;
|
|
782
|
-
/* node:coverage disable */
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
throw new Error("Invalid arguments.");
|
|
786
|
-
}
|
|
787
|
-
/* node:coverage enable */
|
|
786
|
+
/**
|
|
787
|
+
* Create new order. See {@link CreateOrderOptions} for details.
|
|
788
|
+
*
|
|
789
|
+
* @param options
|
|
790
|
+
* @param options.type - `limit` | `market` | 'stop_limit' | 'stop_market' | 'oco'
|
|
791
|
+
* @param options.side - `sell` or `buy`
|
|
792
|
+
* @param options.size - How much of currency you want to trade in units of base currency
|
|
793
|
+
* @param options.price - The price at which the order is to be fullfilled, in units of the quote currency. Param only for limit order
|
|
794
|
+
* @param options.orderID - Unique order ID. Param only for limit order
|
|
795
|
+
* @param options.postOnly - Can be used with 'limit' order and when it's `true` the order will be rejected if immediately matches and trades as a taker. Default is `false`
|
|
796
|
+
* @param options.stopPrice - The price at which the order will be triggered. Used with `stop_limit` and `stop_market` order.
|
|
797
|
+
* @param options.stopLimitPrice - The price at which the order will be triggered. Used with `stop_limit` and `stop_market` order.
|
|
798
|
+
* @param options.timeInForce - Time-in-force supported are: `GTC` (default), `FOK`, `IOC`. Param only for limit order
|
|
799
|
+
* @param options.stopLimitTimeInForce - Time-in-force supported are: `GTC` (default), `FOK`, `IOC`. Param only for limit order
|
|
800
|
+
* @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
|
|
801
|
+
*/
|
|
802
|
+
OrderBook.prototype.createOrder = function (options) {
|
|
788
803
|
switch (options.type) {
|
|
789
804
|
case types_1.OrderType.MARKET:
|
|
790
805
|
return this.market(options);
|
|
@@ -807,43 +822,49 @@ var OrderBook = /** @class */ (function () {
|
|
|
807
822
|
};
|
|
808
823
|
}
|
|
809
824
|
};
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
825
|
+
/**
|
|
826
|
+
* Create a market order. See {@link MarketOrderOptions} for details.
|
|
827
|
+
*
|
|
828
|
+
* @param options
|
|
829
|
+
* @param options.side - `sell` or `buy`
|
|
830
|
+
* @param options.size - How much of currency you want to trade in units of base currency
|
|
831
|
+
* @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
|
|
832
|
+
*/
|
|
833
|
+
OrderBook.prototype.market = function (options) {
|
|
834
|
+
var response = this._market(options);
|
|
835
|
+
if (this.enableJournaling && response.err === null) {
|
|
836
|
+
response.log = {
|
|
837
|
+
opId: ++this._lastOp,
|
|
838
|
+
ts: Date.now(),
|
|
839
|
+
op: "m",
|
|
840
|
+
o: options,
|
|
841
|
+
};
|
|
820
842
|
}
|
|
821
|
-
|
|
822
|
-
/* node:coverage enable */
|
|
843
|
+
return response;
|
|
823
844
|
};
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
845
|
+
/**
|
|
846
|
+
* Create a limit order. See {@link LimitOrderOptions} for details.
|
|
847
|
+
*
|
|
848
|
+
* @param options
|
|
849
|
+
* @param options.side - `sell` or `buy`
|
|
850
|
+
* @param options.id - Unique order ID
|
|
851
|
+
* @param options.size - How much of currency you want to trade in units of base currency
|
|
852
|
+
* @param options.price - The price at which the order is to be fullfilled, in units of the quote currency
|
|
853
|
+
* @param options.postOnly - When `true` the order will be rejected if immediately matches and trades as a taker. Default is `false`
|
|
854
|
+
* @param options.timeInForce - Time-in-force type supported are: GTC, FOK, IOC. Default is GTC
|
|
855
|
+
* @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
|
|
856
|
+
*/
|
|
857
|
+
OrderBook.prototype.limit = function (options) {
|
|
858
|
+
var response = this._limit(options);
|
|
859
|
+
if (this.enableJournaling && response.err === null) {
|
|
860
|
+
response.log = {
|
|
861
|
+
opId: ++this._lastOp,
|
|
862
|
+
ts: Date.now(),
|
|
863
|
+
op: "l",
|
|
864
|
+
o: options,
|
|
865
|
+
};
|
|
844
866
|
}
|
|
845
|
-
|
|
846
|
-
/* node:coverage enable */
|
|
867
|
+
return response;
|
|
847
868
|
};
|
|
848
869
|
return OrderBook;
|
|
849
870
|
}());
|