nodejs-order-book 8.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-2023 Andrea Fassina and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,464 @@
1
+ <p align="center">
2
+ <a href="https://www.npmjs.com/package/nodejs-order-book" target="_blank"><img src="https://img.shields.io/npm/v/nodejs-order-book?color=blue" alt="NPM Version"></a>
3
+ <a href="https://github.com/fasenderos/nodejs-order-book/blob/main/LICENSE" target="_blank"><img src="https://img.shields.io/npm/l/nodejs-order-book" alt="Package License"></a>
4
+ <a href="https://www.npmjs.com/package/nodejs-order-book" target="_blank"><img src="https://img.shields.io/npm/dm/nodejs-order-book" alt="NPM Downloads"></a>
5
+ <a href="https://circleci.com/gh/fasenderos/nodejs-order-book" target="_blank"><img src="https://img.shields.io/circleci/build/github/fasenderos/nodejs-order-book/main" alt="CircleCI" ></a>
6
+ <a href="https://codecov.io/github/fasenderos/nodejs-order-book" target="_blank"><img src="https://img.shields.io/codecov/c/github/fasenderos/nodejs-order-book" alt="Codecov"></a>
7
+ <a href="https://github.com/fasenderos/nodejs-order-book"><img src="https://badgen.net/badge/icon/typescript?icon=typescript&label" alt="Built with TypeScript"></a>
8
+ </p>
9
+
10
+ # Node.js Order Book
11
+
12
+ Ultra-fast Node.js Order Book written in TypeScript for high-frequency trading (HFT) :rocket::rocket:
13
+
14
+ :star: Star me on GitHub — it motivates me a lot!
15
+
16
+ ## Features
17
+
18
+ - Standard price-time priority
19
+ - Supports both market and limit orders
20
+ - Supports `post-only` limit order
21
+ - Supports conditional orders [**Stop Limit, Stop Market and OCO**](#conditional-orders-) <img src="https://img.shields.io/badge/Experimental-blue" alt="Experimental">
22
+ - Supports time in force GTC, FOK and IOC
23
+ - Supports order cancelling
24
+ - Supports order price and/or size updating
25
+ - Snapshot and journaling functionalities for restoring the order book during server startup
26
+ - **High performance (above 300k trades per second)**
27
+
28
+ **Machine:** ASUS ExpertBook, 11th Gen Intel(R) Core(TM) i7-1165G7, 2.80Ghz, 16GB RAM, Node.js v18.4.0.
29
+
30
+ <img src="https://user-images.githubusercontent.com/1219087/181792292-8619ee25-bf75-4871-a06c-bd6c82157f33.png" alt="nodejs-order-book-benchmark" title="nodejs-order-book benchmark" />
31
+
32
+ ## Installation
33
+
34
+ Install with npm:
35
+
36
+ ```sh
37
+ npm install nodejs-order-book
38
+ ```
39
+
40
+ Install with yarn:
41
+
42
+ ```sh
43
+ yarn add nodejs-order-book
44
+ ```
45
+
46
+ Install with pnpm:
47
+
48
+ ```sh
49
+ pnpm add nodejs-order-book
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ To start using order book you need to import `OrderBook` and create new instance:
55
+
56
+ ```js
57
+ import { OrderBook } from 'nodejs-order-book'
58
+
59
+ const ob = new OrderBook()
60
+ ```
61
+
62
+ Then you'll be able to use next primary functions:
63
+
64
+ ```js
65
+ ob.createOrder({ type: 'limit' | 'market', side: 'buy' | 'sell', size: number, price?: number, id?: string, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
66
+
67
+ ob.limit({ id: string, side: 'buy' | 'sell', size: number, price: number, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
68
+
69
+ ob.market({ side: 'buy' | 'sell', size: number })
70
+
71
+ ob.modify(orderID: string, { side: 'buy' | 'sell', size: number, price: number })
72
+
73
+ ob.cancel(orderID: string)
74
+ ```
75
+ ### Conditional Orders ![Experimental](https://img.shields.io/badge/Experimental-blue)
76
+ The version `v6.1.0` introduced support for Conditional Orders `Stop Market`, `Stop Limit` and `OCO`. Even though the test coverage for these new features is at 100%, they are not yet considered stable because they have not been tested with real-world scenarios. For this reason, if you want to use conditional orders, you need to instantiate the order book with the `experimentalConditionalOrders` option set to `true`.
77
+ ```js
78
+ import { OrderBook } from 'nodejs-order-book'
79
+
80
+ const ob = new OrderBook({ experimentalConditionalOrders: true })
81
+
82
+ ob.createOrder({ type: 'stop_limit' | 'stop_market' | 'oco', side: 'buy' | 'sell', size: number, price?: number, id?: string, stopPrice?: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })
83
+
84
+ ob.stopLimit({ id: string, side: 'buy' | 'sell', size: number, price: number, stopPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
85
+
86
+ ob.stopMarket({ side: 'buy' | 'sell', size: number, stopPrice: number })
87
+
88
+ ob.oco({ id: string, side: 'buy' | 'sell', size: number, price: number, stopPrice: number, stopLimitPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })
89
+ ```
90
+
91
+ ## About primary functions
92
+
93
+ To add an order to the order book you can call the general `createOrder()` function or calling the underlying `limit()`, `market()`, `stopLimit()`, `stopMarket()` or `oco()` functions
94
+
95
+ ### Create Order
96
+
97
+ ```js
98
+ // Create limit order
99
+ ob.createOrder({ type: 'limit', side: 'buy' | 'sell', size: number, price: number, id: string, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
100
+
101
+ // Create market order
102
+ ob.createOrder({ type: 'market', side: 'buy' | 'sell', size: number })
103
+
104
+ // Create stop limit order
105
+ ob.createOrder({ type: 'stop_limit', side: 'buy' | 'sell', size: number, price: number, id: string, stopPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
106
+
107
+ // Create stop market order
108
+ ob.createOrder({ type: 'stop_market', side: 'buy' | 'sell', size: number, stopPrice: number })
109
+
110
+ // Create OCO order
111
+ ob.createOrder({ type: 'oco', side: 'buy' | 'sell', size: number, stopPrice: number, stopLimitPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })
112
+ ```
113
+
114
+ ### Create Limit Order
115
+
116
+ ```js
117
+ /**
118
+ * Create a limit order. See {@link LimitOrderOptions} for details.
119
+ *
120
+ * @param options
121
+ * @param options.side - `sell` or `buy`
122
+ * @param options.id - Unique order ID
123
+ * @param options.size - How much of currency you want to trade in units of base currency
124
+ * @param options.price - The price at which the order is to be fullfilled, in units of the quote currency
125
+ * @param options.postOnly - When `true` the order will be rejected if immediately matches and trades as a taker. Default is `false`
126
+ * @param options.timeInForce - Time-in-force type supported are: GTC, FOK, IOC. Default is GTC
127
+ * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
128
+ */
129
+ ob.limit({ side: 'buy' | 'sell', id: string, size: number, price: number, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
130
+ ```
131
+
132
+ For example:
133
+
134
+ ```
135
+ ob.limit({ side: "sell", id: "uniqueID", size: 55, price: 100 })
136
+
137
+ asks: 110 -> 5 110 -> 5
138
+ 100 -> 1 100 -> 56
139
+ -------------- -> --------------
140
+ bids: 90 -> 5 90 -> 5
141
+ 80 -> 1 80 -> 1
142
+
143
+ done - null
144
+ partial - null
145
+ ```
146
+
147
+ ```
148
+ ob.limit({ side: "buy", id: "uniqueID", size: 7, price: 120 })
149
+
150
+ asks: 110 -> 5
151
+ 100 -> 1
152
+ -------------- -> --------------
153
+ bids: 90 -> 5 120 -> 1
154
+ 80 -> 1 90 -> 5
155
+ 80 -> 1
156
+
157
+ done - 2 (or more orders)
158
+ partial - uniqueID order
159
+ ```
160
+
161
+ ```
162
+ ob.limit({ side: "buy", id: "uniqueID", size: 3, price: 120 })
163
+
164
+ asks: 110 -> 5
165
+ 100 -> 1 110 -> 3
166
+ -------------- -> --------------
167
+ bids: 90 -> 5 90 -> 5
168
+ 80 -> 1 80 -> 1
169
+
170
+ done - 1 order with 100 price, (may be also few orders with 110 price) + uniqueID order
171
+ partial - 1 order with price 110
172
+ ```
173
+
174
+ ### Create Market Order
175
+
176
+ ```js
177
+ /**
178
+ * Create a market order. See {@link MarketOrderOptions} for details.
179
+ *
180
+ * @param options
181
+ * @param options.side - `sell` or `buy`
182
+ * @param options.size - How much of currency you want to trade in units of base currency
183
+ * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
184
+ */
185
+ ob.market({ side: 'buy' | 'sell', size: number })
186
+ ```
187
+
188
+ For example:
189
+
190
+ ```
191
+ ob.market({ side: 'sell', size: 6 })
192
+
193
+ asks: 110 -> 5 110 -> 5
194
+ 100 -> 1 100 -> 1
195
+ -------------- -> --------------
196
+ bids: 90 -> 5 80 -> 1
197
+ 80 -> 2
198
+
199
+ done - 2 (or more orders)
200
+ partial - 1 order with price 80
201
+ quantityLeft - 0
202
+ ```
203
+
204
+ ```
205
+ ob.market({ side: 'buy', size: 10 })
206
+
207
+ asks: 110 -> 5
208
+ 100 -> 1
209
+ -------------- -> --------------
210
+ bids: 90 -> 5 90 -> 5
211
+ 80 -> 1 80 -> 1
212
+
213
+ done - 2 (or more orders)
214
+ partial - null
215
+ quantityLeft - 4
216
+ ```
217
+
218
+ ### Create Stop Limit Order
219
+
220
+ ```js
221
+ /**
222
+ * Create a stop limit order. See {@link StopLimitOrderOptions} for details.
223
+ *
224
+ * @param options
225
+ * @param options.side - `sell` or `buy`
226
+ * @param options.id - Unique order ID
227
+ * @param options.size - How much of currency you want to trade in units of base currency
228
+ * @param options.price - The price at which the order is to be fullfilled, in units of the quote currency
229
+ * @param options.stopPrice - The price at which the order will be triggered.
230
+ * @param options.timeInForce - Time-in-force type supported are: GTC, FOK, IOC. Default is GTC
231
+ * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
232
+ */
233
+ ob.stopLimit({ side: 'buy' | 'sell', id: string, size: number, price: number, stopPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC' })
234
+ ```
235
+
236
+ ### Create Stop Market Order
237
+
238
+ ```js
239
+ /**
240
+ * Create a stop market order. See {@link StopMarketOrderOptions} for details.
241
+ *
242
+ * @param options
243
+ * @param options.side - `sell` or `buy`
244
+ * @param options.size - How much of currency you want to trade in units of base currency
245
+ * @param options.stopPrice - The price at which the order will be triggered.
246
+ * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
247
+ */
248
+ ob.stopMarket({ side: 'buy' | 'sell', size: number, stopPrice: number })
249
+ ```
250
+
251
+ ### Create OCO (One-Cancels-the-Other) Order
252
+
253
+ ```js
254
+ /**
255
+ * Create an OCO (One-Cancels-the-Other) order.
256
+ * OCO order combines a `stop_limit` order and a `limit` order, where if stop price
257
+ * is triggered or limit order is fully or partially fulfilled, the other is canceled.
258
+ * Both orders have the same `side` and `size`. If you cancel one of the orders, the
259
+ * entire OCO order pair will be canceled.
260
+ *
261
+ * For BUY orders the `stopPrice` must be above the current price and the `price` below the current price
262
+ * For SELL orders the `stopPrice` must be below the current price and the `price` above the current price
263
+ *
264
+ * See {@link OCOOrderOptions} for details.
265
+ *
266
+ * @param options
267
+ * @param options.side - `sell` or `buy`
268
+ * @param options.id - Unique order ID
269
+ * @param options.size - How much of currency you want to trade in units of base currency
270
+ * @param options.price - The price of the `limit` order at which the order is to be fullfilled, in units of the quote currency
271
+ * @param options.stopPrice - The price at which the `stop_limit` order will be triggered.
272
+ * @param options.stopLimitPrice - The price of the `stop_limit` order at which the order is to be fullfilled, in units of the quote currency.
273
+ * @param options.timeInForce - Time-in-force of the `limit` order. Type supported are: GTC, FOK, IOC. Default is GTC
274
+ * @param options.stopLimitTimeInForce - Time-in-force of the `stop_limit` order. Type supported are: GTC, FOK, IOC. Default is GTC
275
+ * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure
276
+ */
277
+ ob.oco({ side: 'buy' | 'sell', id: string, size: number, price: number, stopPrice: number, stopLimitPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })
278
+ ```
279
+
280
+ ### Modify an existing order
281
+
282
+ ```js
283
+ /**
284
+ * Modify an existing order with given ID. When an order is modified by price or quantity,
285
+ * it will be deemed as a new entry. Under the price-time-priority algorithm, orders are
286
+ * prioritized according to their order price and order time. Hence, the latest orders
287
+ * will be placed at the back of the matching order queue.
288
+ *
289
+ * @param orderID - The ID of the order to be modified
290
+ * @param orderUpdate - An object with the modified size and/or price of an order. The shape of the object is `{size, price}`.
291
+ * @returns An object with the result of the processed order or an error
292
+ */
293
+ ob.modify(orderID: string, { size: number, price: number })
294
+ ```
295
+
296
+ For example:
297
+
298
+ ```
299
+ ob.limit({ side: "sell", id: "uniqueID", size: 55, price: 100 })
300
+
301
+ asks: 110 -> 5 110 -> 5
302
+ 100 -> 1 100 -> 56
303
+ -------------- -> --------------
304
+ bids: 90 -> 5 90 -> 5
305
+ 80 -> 1 80 -> 1
306
+
307
+ // Modify the size from 55 to 65
308
+ ob.modify("uniqueID", { size: 65 })
309
+
310
+ asks: 110 -> 5 110 -> 5
311
+ 100 -> 56 100 -> 66
312
+ -------------- -> --------------
313
+ bids: 90 -> 5 90 -> 5
314
+ 80 -> 1 80 -> 1
315
+
316
+
317
+ // Modify the price from 100 to 110
318
+ ob.modify("uniqueID", { price: 110 })
319
+
320
+ asks: 110 -> 5 110 -> 70
321
+ 100 -> 66 100 -> 1
322
+ -------------- -> --------------
323
+ bids: 90 -> 5 90 -> 5
324
+ 80 -> 1 80 -> 1
325
+ ```
326
+
327
+ ### Cancel Order
328
+
329
+ ```js
330
+ /**
331
+ * Remove an existing order with given ID from the order book
332
+ *
333
+ * @param orderID - The ID of the order to be removed
334
+ * @returns The removed order if exists or `undefined`
335
+ */
336
+ ob.cancel(orderID: string)
337
+ ```
338
+
339
+ For example:
340
+
341
+ ```
342
+ ob.cancel("myUniqueID-Sell-1-with-100")
343
+
344
+ asks: 110 -> 5
345
+ 100 -> 1 110 -> 5
346
+ -------------- -> --------------
347
+ bids: 90 -> 5 90 -> 5
348
+ 80 -> 1 80 -> 1
349
+ ```
350
+
351
+ ## Options
352
+
353
+ The orderbook can be initialized with the following options by passing them to the constructor:
354
+
355
+ ### Snapshot
356
+ A `snapshot` represents the state of the order book at a specific point in time. It includes the following properties:
357
+
358
+ - `asks`: List of ask orders, each with a `price` and a list of associated `orders`.
359
+ - `bids`: List of bid orders, each with a `price` and a list of associated `orders`.
360
+ - `ts`: A timestamp indicating when the snapshot was taken, in Unix timestamp format.
361
+ - `lastOp`: The id of the last operation included in the snapshot
362
+
363
+ Snapshots are crucial for restoring the order book to a previous state. The orderbook can restore from a snapshot before processing any journal logs, ensuring consistency and accuracy.
364
+ After taking the snapshot, you can safely remove all logs preceding the `lastOp` id.
365
+
366
+ ```js
367
+ const ob = new OrderBook({ enableJournaling: true})
368
+
369
+ // after every order save the log to the database
370
+ const order = ob.limit({ side: "sell", id: "uniqueID", size: 55, price: 100 })
371
+ await saveLog(order.log)
372
+
373
+ // ... after some time take a snapshot of the order book and save it on the database
374
+
375
+ const snapshot = ob.snapshot()
376
+ await saveSnapshot(snapshot)
377
+
378
+ // 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
379
+ await removePreviousLogs(snapshot.lastOp)
380
+
381
+ // On server restart get the snapshot and logs from the database and initialize the order book
382
+ const logs = await getLogs()
383
+ const snapshot = await getSnapshot()
384
+
385
+ const ob = new OrderBook({ snapshot, journal: log, enableJournaling: true })
386
+ ```
387
+
388
+ ### Journal Logs
389
+ The `journal` option expects an array of journal logs that you can get by setting `enableJournaling` to true. When the journal is provided, the order book will replay all the operations, bringing the order book to the same state as the last log.
390
+ ```js
391
+ // Assuming 'logs' is an array of log entries retrieved from the database
392
+
393
+ const logs = await getLogs()
394
+ const ob = new OrderBook({ journal: logs, enableJournalLog: true })
395
+ ```
396
+ By combining snapshots with journaling, you can effectively restore and audit the state of the order book.
397
+
398
+ ### Enable Journaling
399
+ `enabledJournaling` is a configuration setting that determines whether journaling is enabled or disabled. When enabled, the property `log` will be added to the body of the response for each operation. The logs must be saved to the database and can then be used when a new instance of the order book is instantiated.
400
+ ```js
401
+ const ob = new OrderBook({ enableJournaling: true }) // false by default
402
+
403
+ // after every order save the log to the database
404
+ const order = ob.limit({ side: "sell", id: "uniqueID", size: 55, price: 100 })
405
+ await saveLog(order.log)
406
+ ```
407
+
408
+ ## Development
409
+
410
+ ### Build
411
+
412
+ Build production (distribution) files in your dist folder:
413
+
414
+ ```sh
415
+ npm run build
416
+ ```
417
+
418
+ ### Testing
419
+
420
+ To run all the unit-test
421
+
422
+ ```sh
423
+ npm run test
424
+ ```
425
+
426
+ ### Coverage
427
+
428
+ Run testing coverage
429
+
430
+ ```sh
431
+ npm run test:cov
432
+ ```
433
+
434
+ ### Benchmarking
435
+
436
+ Before running benchmark, make sure to have built the source code with `npm run build` first
437
+
438
+ ```sh
439
+ npm run bench
440
+ ```
441
+
442
+ ## Contributing
443
+
444
+ I would greatly appreciate any contributions to make this project better. Please make sure to follow the below guidelines before getting your hands dirty.
445
+
446
+ 1. Fork the repository
447
+ 2. Create your branch (git checkout -b my-branch)
448
+ 3. Commit any changes to your branch
449
+ 4. Push your changes to your remote branch
450
+ 5. Open a pull request
451
+
452
+ ## Donation
453
+
454
+ If this project help you reduce time to develop, you can give me a cup of coffee 🍵 :)
455
+
456
+ - USDT (TRC20): `TXArNxsq2Ee8Jvsk45PudVio52Joiq1yEe`
457
+ - BTC: `1GYDVSAQNgG7MFhV5bk15XJy3qoE4NFenp`
458
+ - BTC (BEP20): `0xf673ee099be8129ec05e2f549d96ebea24ac5d97`
459
+ - ETH (ERC20): `0xf673ee099be8129ec05e2f549d96ebea24ac5d97`
460
+ - BNB (BEP20): `0xf673ee099be8129ec05e2f549d96ebea24ac5d97`
461
+
462
+ ## License
463
+
464
+ Copyright [Andrea Fassina](https://github.com/fasenderos), Licensed under [MIT](LICENSE).
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var _a, _b;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.CustomError = exports.OrderBookError = exports.ErrorMessages = exports.ErrorCodes = exports.ERROR = void 0;
5
+ var ERROR;
6
+ (function (ERROR) {
7
+ ERROR["DEFAULT"] = "DEFAULT";
8
+ ERROR["INSUFFICIENT_QUANTITY"] = "INSUFFICIENT_QUANTITY";
9
+ ERROR["INVALID_CONDITIONAL_ORDER"] = "INVALID_CONDITIONAL_ORDER";
10
+ ERROR["INVALID_JOURNAL_LOG"] = "INVALID_JOURNAL_LOG";
11
+ ERROR["INVALID_ORDER_TYPE"] = "INVALID_ORDER_TYPE";
12
+ ERROR["INVALID_PRICE"] = "INVALID_PRICE";
13
+ ERROR["INVALID_PRICE_LEVEL"] = "INVALID_PRICE_LEVEL";
14
+ ERROR["INVALID_PRICE_OR_QUANTITY"] = "INVALID_PRICE_OR_QUANTITY";
15
+ ERROR["INVALID_QUANTITY"] = "INVALID_QUANTITY";
16
+ ERROR["INVALID_SIDE"] = "INVALID_SIDE";
17
+ ERROR["INVALID_TIF"] = "INVALID_TIF";
18
+ ERROR["LIMIT_ORDER_FOK_NOT_FILLABLE"] = "LIMIT_ORDER_FOK_NOT_FILLABLE";
19
+ ERROR["LIMIT_ORDER_POST_ONLY"] = "LIMIT_ORDER_POST_ONLY";
20
+ ERROR["ORDER_ALREDY_EXISTS"] = "ORDER_ALREDY_EXISTS";
21
+ ERROR["ORDER_NOT_FOUND"] = "ORDER_NOT_FOUND";
22
+ })(ERROR || (exports.ERROR = ERROR = {}));
23
+ exports.ErrorCodes = (_a = {},
24
+ // 10xx General issues
25
+ _a[ERROR.DEFAULT] = 1000,
26
+ // 11xx Request issues
27
+ _a[ERROR.INVALID_ORDER_TYPE] = 1100,
28
+ _a[ERROR.INVALID_SIDE] = 1101,
29
+ _a[ERROR.INVALID_QUANTITY] = 1102,
30
+ _a[ERROR.INVALID_PRICE] = 1103,
31
+ _a[ERROR.INVALID_PRICE_OR_QUANTITY] = 1104,
32
+ _a[ERROR.INVALID_TIF] = 1105,
33
+ _a[ERROR.LIMIT_ORDER_FOK_NOT_FILLABLE] = 1106,
34
+ _a[ERROR.LIMIT_ORDER_POST_ONLY] = 1107,
35
+ _a[ERROR.INVALID_CONDITIONAL_ORDER] = 1108,
36
+ _a[ERROR.ORDER_ALREDY_EXISTS] = 1109,
37
+ _a[ERROR.ORDER_NOT_FOUND] = 1110,
38
+ // 12xx Internal error
39
+ _a[ERROR.INSUFFICIENT_QUANTITY] = 1200,
40
+ _a[ERROR.INVALID_PRICE_LEVEL] = 1201,
41
+ _a[ERROR.INVALID_JOURNAL_LOG] = 1201,
42
+ _a);
43
+ exports.ErrorMessages = (_b = {},
44
+ _b[ERROR.DEFAULT] = "Something wrong",
45
+ _b[ERROR.INSUFFICIENT_QUANTITY] = "Insufficient quantity to calculate price",
46
+ _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)",
47
+ _b[ERROR.INVALID_ORDER_TYPE] = "Supported order type are 'limit' and 'market'",
48
+ _b[ERROR.INVALID_PRICE] = "Invalid order price",
49
+ _b[ERROR.INVALID_PRICE_LEVEL] = "Invalid order price level",
50
+ _b[ERROR.INVALID_PRICE_OR_QUANTITY] = "Invalid order price or quantity",
51
+ _b[ERROR.INVALID_QUANTITY] = "Invalid order quantity",
52
+ _b[ERROR.INVALID_SIDE] = "Invalid side: must be either 'sell' or 'buy'",
53
+ _b[ERROR.INVALID_TIF] = "Invalid TimeInForce: must be one of 'GTC', 'IOC' or 'FOK'",
54
+ _b[ERROR.LIMIT_ORDER_FOK_NOT_FILLABLE] = "Limit FOK order not fillable",
55
+ _b[ERROR.LIMIT_ORDER_POST_ONLY] = "Post-only limit order rejected because would execute immediately",
56
+ _b[ERROR.ORDER_ALREDY_EXISTS] = "Order already exists",
57
+ _b[ERROR.ORDER_NOT_FOUND] = "Order not found",
58
+ _b[ERROR.INVALID_JOURNAL_LOG] = "Invalid journal log format",
59
+ _b);
60
+ var OrderBookError = /** @class */ (function () {
61
+ function OrderBookError(error) {
62
+ var _a;
63
+ var errorMessage;
64
+ if (error != null && exports.ErrorMessages[error] != null) {
65
+ errorMessage = exports.ErrorMessages[error];
66
+ }
67
+ else {
68
+ var customMessage = error === undefined || error === "" ? "" : ": ".concat(error);
69
+ errorMessage = "".concat(exports.ErrorMessages.DEFAULT).concat(customMessage);
70
+ }
71
+ this.message = errorMessage;
72
+ this.code = (_a = exports.ErrorCodes[error]) !== null && _a !== void 0 ? _a : exports.ErrorCodes[ERROR.DEFAULT];
73
+ }
74
+ return OrderBookError;
75
+ }());
76
+ exports.OrderBookError = OrderBookError;
77
+ /* node:coverage ignore next - Don't know why this line is uncoverd */
78
+ var CustomError = function (error) {
79
+ return new OrderBookError(error);
80
+ };
81
+ exports.CustomError = CustomError;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Side = exports.OrderType = exports.OrderBook = void 0;
4
+ /* node:coverage disable */
5
+ var orderbook_1 = require("./orderbook");
6
+ Object.defineProperty(exports, "OrderBook", { enumerable: true, get: function () { return orderbook_1.OrderBook; } });
7
+ var types_1 = require("./types");
8
+ Object.defineProperty(exports, "OrderType", { enumerable: true, get: function () { return types_1.OrderType; } });
9
+ Object.defineProperty(exports, "Side", { enumerable: true, get: function () { return types_1.Side; } });
10
+ /* node:coverage enable */