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 +21 -0
- package/README.md +464 -0
- package/dist/cjs/errors.js +81 -0
- package/dist/cjs/index.js +10 -0
- package/dist/cjs/order.js +303 -0
- package/dist/cjs/orderbook.js +850 -0
- package/dist/cjs/orderqueue.js +78 -0
- package/dist/cjs/orderside.js +158 -0
- package/dist/cjs/stopbook.js +65 -0
- package/dist/cjs/stopqueue.js +59 -0
- package/dist/cjs/stopside.js +76 -0
- package/dist/cjs/types.js +23 -0
- package/dist/esm/errors.js +77 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/order.js +300 -0
- package/dist/esm/orderbook.js +847 -0
- package/dist/esm/orderqueue.js +72 -0
- package/dist/esm/orderside.js +152 -0
- package/dist/esm/stopbook.js +62 -0
- package/dist/esm/stopqueue.js +53 -0
- package/dist/esm/stopside.js +70 -0
- package/dist/esm/types.js +20 -0
- package/dist/types/errors.d.ts +26 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/order.d.ts +71 -0
- package/dist/types/orderbook.d.ts +218 -0
- package/dist/types/orderqueue.d.ts +18 -0
- package/dist/types/orderside.d.ts +29 -0
- package/dist/types/stopbook.d.ts +20 -0
- package/dist/types/stopqueue.d.ts +12 -0
- package/dist/types/stopside.d.ts +12 -0
- package/dist/types/types.d.ts +324 -0
- package/dist/umd/index.js +2 -0
- package/dist/umd/index.js.LICENSE.txt +10 -0
- package/package.json +89 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
|
|
2
|
+
import Denque from "denque";
|
|
3
|
+
var OrderQueue = /** @class */ (function () {
|
|
4
|
+
function OrderQueue(price) {
|
|
5
|
+
var _this = this;
|
|
6
|
+
this._ordersMap = {};
|
|
7
|
+
// returns the number of orders in queue
|
|
8
|
+
this.len = function () {
|
|
9
|
+
return _this._orders.length;
|
|
10
|
+
};
|
|
11
|
+
this.toArray = function () {
|
|
12
|
+
return _this._orders.toArray();
|
|
13
|
+
};
|
|
14
|
+
// returns price level of the queue
|
|
15
|
+
this.price = function () {
|
|
16
|
+
return _this._price;
|
|
17
|
+
};
|
|
18
|
+
// returns price level of the queue
|
|
19
|
+
this.volume = function () {
|
|
20
|
+
return _this._volume;
|
|
21
|
+
};
|
|
22
|
+
// returns top order in queue
|
|
23
|
+
this.head = function () {
|
|
24
|
+
return _this._orders.peekFront();
|
|
25
|
+
};
|
|
26
|
+
// returns bottom order in queue
|
|
27
|
+
this.tail = function () {
|
|
28
|
+
return _this._orders.peekBack();
|
|
29
|
+
};
|
|
30
|
+
// adds order to tail of the queue
|
|
31
|
+
this.append = function (order) {
|
|
32
|
+
_this._volume += order.size;
|
|
33
|
+
_this._orders.push(order);
|
|
34
|
+
_this._ordersMap[order.id] = _this._orders.length - 1;
|
|
35
|
+
return order;
|
|
36
|
+
};
|
|
37
|
+
// sets up new order to list value
|
|
38
|
+
this.update = function (oldOrder, newOrder) {
|
|
39
|
+
_this._volume -= oldOrder.size;
|
|
40
|
+
_this._volume += newOrder.size;
|
|
41
|
+
// Remove old order from head
|
|
42
|
+
_this._orders.shift();
|
|
43
|
+
delete _this._ordersMap[oldOrder.id];
|
|
44
|
+
// Add new order to head
|
|
45
|
+
_this._orders.unshift(newOrder);
|
|
46
|
+
_this._ordersMap[newOrder.id] = 0;
|
|
47
|
+
};
|
|
48
|
+
// removes order from the queue
|
|
49
|
+
this.remove = function (order) {
|
|
50
|
+
_this._volume -= order.size;
|
|
51
|
+
var deletedOrderIndex = _this._ordersMap[order.id];
|
|
52
|
+
_this._orders.removeOne(deletedOrderIndex);
|
|
53
|
+
delete _this._ordersMap[order.id];
|
|
54
|
+
// Update all orders indexes where index is greater than the deleted one
|
|
55
|
+
for (var orderId in _this._ordersMap) {
|
|
56
|
+
if (_this._ordersMap[orderId] > deletedOrderIndex) {
|
|
57
|
+
_this._ordersMap[orderId] -= 1;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
this.updateOrderSize = function (order, size) {
|
|
62
|
+
_this._volume += size - order.size; // update volume
|
|
63
|
+
order.size = size;
|
|
64
|
+
order.time = Date.now();
|
|
65
|
+
};
|
|
66
|
+
this._price = price;
|
|
67
|
+
this._volume = 0;
|
|
68
|
+
this._orders = new Denque();
|
|
69
|
+
}
|
|
70
|
+
return OrderQueue;
|
|
71
|
+
}());
|
|
72
|
+
export { OrderQueue };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
/* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
|
|
13
|
+
import createRBTree from "functional-red-black-tree";
|
|
14
|
+
import { CustomError, ERROR } from "./errors";
|
|
15
|
+
import { OrderFactory } from "./order";
|
|
16
|
+
import { OrderQueue } from "./orderqueue";
|
|
17
|
+
import { Side } from "./types";
|
|
18
|
+
var OrderSide = /** @class */ (function () {
|
|
19
|
+
function OrderSide(side) {
|
|
20
|
+
var _this = this;
|
|
21
|
+
this._prices = {};
|
|
22
|
+
this._volume = 0;
|
|
23
|
+
this._total = 0;
|
|
24
|
+
this._numOrders = 0;
|
|
25
|
+
this._depthSide = 0;
|
|
26
|
+
this._side = Side.SELL;
|
|
27
|
+
// returns amount of orders
|
|
28
|
+
this.len = function () {
|
|
29
|
+
return _this._numOrders;
|
|
30
|
+
};
|
|
31
|
+
// returns depth of market
|
|
32
|
+
this.depth = function () {
|
|
33
|
+
return _this._depthSide;
|
|
34
|
+
};
|
|
35
|
+
// returns total amount of quantity in side
|
|
36
|
+
this.volume = function () {
|
|
37
|
+
return _this._volume;
|
|
38
|
+
};
|
|
39
|
+
// returns the total (size * price of each price level) in side
|
|
40
|
+
this.total = function () {
|
|
41
|
+
return _this._total;
|
|
42
|
+
};
|
|
43
|
+
// returns the price tree in side
|
|
44
|
+
this.priceTree = function () {
|
|
45
|
+
return _this._priceTree;
|
|
46
|
+
};
|
|
47
|
+
// appends order to definite price level
|
|
48
|
+
this.append = function (order) {
|
|
49
|
+
var price = order.price;
|
|
50
|
+
var strPrice = price.toString();
|
|
51
|
+
if (_this._prices[strPrice] === undefined) {
|
|
52
|
+
var priceQueue = new OrderQueue(price);
|
|
53
|
+
_this._prices[strPrice] = priceQueue;
|
|
54
|
+
_this._priceTree = _this._priceTree.insert(price, priceQueue);
|
|
55
|
+
_this._depthSide += 1;
|
|
56
|
+
}
|
|
57
|
+
_this._numOrders += 1;
|
|
58
|
+
_this._volume += order.size;
|
|
59
|
+
_this._total += order.size * order.price;
|
|
60
|
+
return _this._prices[strPrice].append(order);
|
|
61
|
+
};
|
|
62
|
+
// removes order from definite price level
|
|
63
|
+
this.remove = function (order) {
|
|
64
|
+
var price = order.price;
|
|
65
|
+
var strPrice = price.toString();
|
|
66
|
+
if (_this._prices[strPrice] === undefined) {
|
|
67
|
+
throw CustomError(ERROR.INVALID_PRICE_LEVEL);
|
|
68
|
+
}
|
|
69
|
+
_this._prices[strPrice].remove(order);
|
|
70
|
+
if (_this._prices[strPrice].len() === 0) {
|
|
71
|
+
delete _this._prices[strPrice];
|
|
72
|
+
_this._priceTree = _this._priceTree.remove(price);
|
|
73
|
+
_this._depthSide -= 1;
|
|
74
|
+
}
|
|
75
|
+
_this._numOrders -= 1;
|
|
76
|
+
_this._volume -= order.size;
|
|
77
|
+
_this._total -= order.size * order.price;
|
|
78
|
+
return order;
|
|
79
|
+
};
|
|
80
|
+
// Update the price of an order and return the order with the updated price
|
|
81
|
+
this.updateOrderPrice = function (oldOrder, orderUpdate) {
|
|
82
|
+
_this.remove(oldOrder);
|
|
83
|
+
var newOrder = OrderFactory.createOrder(__assign(__assign({}, oldOrder.toObject()), { size: orderUpdate.size !== undefined ? orderUpdate.size : oldOrder.size, price: orderUpdate.price, time: Date.now() }));
|
|
84
|
+
_this.append(newOrder);
|
|
85
|
+
return newOrder;
|
|
86
|
+
};
|
|
87
|
+
// Update the price of an order and return the order with the updated price
|
|
88
|
+
this.updateOrderSize = function (oldOrder, orderUpdate) {
|
|
89
|
+
var _a;
|
|
90
|
+
var newOrderPrice = (_a = orderUpdate.price) !== null && _a !== void 0 ? _a : oldOrder.price;
|
|
91
|
+
_this._volume += orderUpdate.size - oldOrder.size;
|
|
92
|
+
_this._total +=
|
|
93
|
+
orderUpdate.size * newOrderPrice - oldOrder.size * oldOrder.price;
|
|
94
|
+
_this._prices[oldOrder.price.toString()].updateOrderSize(oldOrder, orderUpdate.size);
|
|
95
|
+
return oldOrder;
|
|
96
|
+
};
|
|
97
|
+
// returns max level of price
|
|
98
|
+
this.maxPriceQueue = function () {
|
|
99
|
+
if (_this._depthSide > 0) {
|
|
100
|
+
var max = _this._side === Side.SELL ? _this._priceTree.end : _this._priceTree.begin;
|
|
101
|
+
return max.value;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
// returns min level of price
|
|
105
|
+
this.minPriceQueue = function () {
|
|
106
|
+
if (_this._depthSide > 0) {
|
|
107
|
+
var min = _this._side === Side.SELL ? _this._priceTree.begin : _this._priceTree.end;
|
|
108
|
+
return min.value;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
// returns nearest OrderQueue with price less than given
|
|
112
|
+
this.lowerThan = function (price) {
|
|
113
|
+
var node = _this._side === Side.SELL
|
|
114
|
+
? _this._priceTree.lt(price)
|
|
115
|
+
: _this._priceTree.gt(price);
|
|
116
|
+
return node.value;
|
|
117
|
+
};
|
|
118
|
+
// returns nearest OrderQueue with price greater than given
|
|
119
|
+
this.greaterThan = function (price) {
|
|
120
|
+
var node = _this._side === Side.SELL
|
|
121
|
+
? _this._priceTree.gt(price)
|
|
122
|
+
: _this._priceTree.lt(price);
|
|
123
|
+
return node.value;
|
|
124
|
+
};
|
|
125
|
+
// returns all orders
|
|
126
|
+
this.orders = function () {
|
|
127
|
+
var orders = [];
|
|
128
|
+
for (var price in _this._prices) {
|
|
129
|
+
var allOrders = _this._prices[price].toArray();
|
|
130
|
+
orders = orders.concat(allOrders);
|
|
131
|
+
}
|
|
132
|
+
return orders;
|
|
133
|
+
};
|
|
134
|
+
this.toString = function () {
|
|
135
|
+
var s = "";
|
|
136
|
+
var level = _this.maxPriceQueue();
|
|
137
|
+
while (level !== undefined) {
|
|
138
|
+
var volume = level.volume().toString();
|
|
139
|
+
s += "\n".concat(level.price(), " -> ").concat(volume);
|
|
140
|
+
level = _this.lowerThan(level.price());
|
|
141
|
+
}
|
|
142
|
+
return s;
|
|
143
|
+
};
|
|
144
|
+
var compare = side === Side.SELL
|
|
145
|
+
? function (a, b) { return a - b; }
|
|
146
|
+
: function (a, b) { return b - a; };
|
|
147
|
+
this._priceTree = createRBTree(compare);
|
|
148
|
+
this._side = side;
|
|
149
|
+
}
|
|
150
|
+
return OrderSide;
|
|
151
|
+
}());
|
|
152
|
+
export { OrderSide };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { StopSide } from "./stopside";
|
|
2
|
+
import { OrderType, Side } from "./types";
|
|
3
|
+
var StopBook = /** @class */ (function () {
|
|
4
|
+
function StopBook() {
|
|
5
|
+
var _this = this;
|
|
6
|
+
this.add = function (order) {
|
|
7
|
+
var stopSide = order.side === Side.BUY ? _this.bids : _this.asks;
|
|
8
|
+
stopSide.append(order);
|
|
9
|
+
};
|
|
10
|
+
this.remove = function (side, id, stopPrice) {
|
|
11
|
+
var stopSide = side === Side.BUY ? _this.bids : _this.asks;
|
|
12
|
+
return stopSide.remove(id, stopPrice);
|
|
13
|
+
};
|
|
14
|
+
this.removePriceLevel = function (side, priceLevel) {
|
|
15
|
+
var stopSide = side === Side.BUY ? _this.bids : _this.asks;
|
|
16
|
+
stopSide.removePriceLevel(priceLevel);
|
|
17
|
+
};
|
|
18
|
+
this.getConditionalOrders = function (side, priceBefore, marketPrice) {
|
|
19
|
+
var stopSide = side === Side.BUY ? _this.bids : _this.asks;
|
|
20
|
+
return stopSide.between(priceBefore, marketPrice);
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Stop-Limit Order:
|
|
24
|
+
* Buy: marketPrice < stopPrice <= price
|
|
25
|
+
* Sell: marketPrice > stopPrice >= price
|
|
26
|
+
* Stop-Market Order:
|
|
27
|
+
* Buy: marketPrice < stopPrice
|
|
28
|
+
* Sell: marketPrice > stopPrice
|
|
29
|
+
*/
|
|
30
|
+
this.validConditionalOrder = function (marketPrice, order) {
|
|
31
|
+
var response = false;
|
|
32
|
+
var type = order.type, side = order.side, stopPrice = order.stopPrice;
|
|
33
|
+
if (type === OrderType.STOP_LIMIT) {
|
|
34
|
+
// Buy: marketPrice < stopPrice <= price
|
|
35
|
+
if (side === Side.BUY &&
|
|
36
|
+
marketPrice < stopPrice &&
|
|
37
|
+
stopPrice <= order.price) {
|
|
38
|
+
response = true;
|
|
39
|
+
}
|
|
40
|
+
// Sell: marketPrice > stopPrice >= price
|
|
41
|
+
if (side === Side.SELL &&
|
|
42
|
+
marketPrice > stopPrice &&
|
|
43
|
+
stopPrice >= order.price) {
|
|
44
|
+
response = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Buy: marketPrice < stopPrice
|
|
49
|
+
if (side === Side.BUY && marketPrice < stopPrice)
|
|
50
|
+
response = true;
|
|
51
|
+
// Sell: marketPrice > stopPrice
|
|
52
|
+
if (side === Side.SELL && marketPrice > stopPrice)
|
|
53
|
+
response = true;
|
|
54
|
+
}
|
|
55
|
+
return response;
|
|
56
|
+
};
|
|
57
|
+
this.bids = new StopSide(Side.BUY);
|
|
58
|
+
this.asks = new StopSide(Side.SELL);
|
|
59
|
+
}
|
|
60
|
+
return StopBook;
|
|
61
|
+
}());
|
|
62
|
+
export { StopBook };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
|
|
2
|
+
import Denque from "denque";
|
|
3
|
+
var StopQueue = /** @class */ (function () {
|
|
4
|
+
function StopQueue(price) {
|
|
5
|
+
var _this = this;
|
|
6
|
+
this._ordersMap = {};
|
|
7
|
+
// returns the number of orders in queue
|
|
8
|
+
this.len = function () {
|
|
9
|
+
return _this._orders.length;
|
|
10
|
+
};
|
|
11
|
+
// remove order from head of queue
|
|
12
|
+
this.removeFromHead = function () {
|
|
13
|
+
// We can't use the shift method here because we need
|
|
14
|
+
// to update index in the map, so we use the remove(id) function
|
|
15
|
+
var order = _this._orders.peekFront();
|
|
16
|
+
if (order === undefined)
|
|
17
|
+
return;
|
|
18
|
+
return _this.remove(order.id);
|
|
19
|
+
};
|
|
20
|
+
// adds order to tail of the queue
|
|
21
|
+
this.append = function (order) {
|
|
22
|
+
_this._orders.push(order);
|
|
23
|
+
_this._ordersMap[order.id] = _this._orders.length - 1;
|
|
24
|
+
return order;
|
|
25
|
+
};
|
|
26
|
+
// removes order from the queue
|
|
27
|
+
this.remove = function (id) {
|
|
28
|
+
var deletedOrderIndex = _this._ordersMap[id];
|
|
29
|
+
if (deletedOrderIndex === undefined)
|
|
30
|
+
return;
|
|
31
|
+
var deletedOrder = _this._orders.removeOne(deletedOrderIndex);
|
|
32
|
+
delete _this._ordersMap[id];
|
|
33
|
+
// Update all orders indexes where index is greater than the deleted one
|
|
34
|
+
for (var orderId in _this._ordersMap) {
|
|
35
|
+
if (_this._ordersMap[orderId] > deletedOrderIndex) {
|
|
36
|
+
_this._ordersMap[orderId] -= 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return deletedOrder;
|
|
40
|
+
};
|
|
41
|
+
this._price = price;
|
|
42
|
+
this._orders = new Denque();
|
|
43
|
+
}
|
|
44
|
+
Object.defineProperty(StopQueue.prototype, "price", {
|
|
45
|
+
get: function () {
|
|
46
|
+
return this._price;
|
|
47
|
+
},
|
|
48
|
+
enumerable: false,
|
|
49
|
+
configurable: true
|
|
50
|
+
});
|
|
51
|
+
return StopQueue;
|
|
52
|
+
}());
|
|
53
|
+
export { StopQueue };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
|
|
2
|
+
import createRBTree from "functional-red-black-tree";
|
|
3
|
+
import { CustomError, ERROR } from "./errors";
|
|
4
|
+
import { StopQueue } from "./stopqueue";
|
|
5
|
+
import { Side } from "./types";
|
|
6
|
+
var StopSide = /** @class */ (function () {
|
|
7
|
+
function StopSide(side) {
|
|
8
|
+
var _this = this;
|
|
9
|
+
this._prices = {};
|
|
10
|
+
// appends order to definite price level
|
|
11
|
+
this.append = function (order) {
|
|
12
|
+
var price = order.stopPrice;
|
|
13
|
+
var strPrice = price.toString();
|
|
14
|
+
if (_this._prices[strPrice] === undefined) {
|
|
15
|
+
var priceQueue = new StopQueue(price);
|
|
16
|
+
_this._prices[strPrice] = priceQueue;
|
|
17
|
+
_this._priceTree = _this._priceTree.insert(price, priceQueue);
|
|
18
|
+
}
|
|
19
|
+
return _this._prices[strPrice].append(order);
|
|
20
|
+
};
|
|
21
|
+
// removes order from definite price level
|
|
22
|
+
this.remove = function (id, stopPrice) {
|
|
23
|
+
var strPrice = stopPrice.toString();
|
|
24
|
+
if (_this._prices[strPrice] === undefined) {
|
|
25
|
+
throw CustomError(ERROR.INVALID_PRICE_LEVEL);
|
|
26
|
+
}
|
|
27
|
+
var deletedOrder = _this._prices[strPrice].remove(id);
|
|
28
|
+
if (_this._prices[strPrice].len() === 0) {
|
|
29
|
+
delete _this._prices[strPrice];
|
|
30
|
+
_this._priceTree = _this._priceTree.remove(stopPrice);
|
|
31
|
+
}
|
|
32
|
+
return deletedOrder;
|
|
33
|
+
};
|
|
34
|
+
this.removePriceLevel = function (priceLevel) {
|
|
35
|
+
delete _this._prices[priceLevel.toString()];
|
|
36
|
+
_this._priceTree = _this._priceTree.remove(priceLevel);
|
|
37
|
+
};
|
|
38
|
+
// Get orders queue between two price levels
|
|
39
|
+
this.between = function (priceBefore, marketPrice) {
|
|
40
|
+
var queues = [];
|
|
41
|
+
var lowerBound = priceBefore;
|
|
42
|
+
var upperBound = marketPrice;
|
|
43
|
+
var highest = Math.max(priceBefore, marketPrice);
|
|
44
|
+
var lowest = Math.min(priceBefore, marketPrice);
|
|
45
|
+
if (_this._side === Side.BUY) {
|
|
46
|
+
lowerBound = highest;
|
|
47
|
+
upperBound = lowest - 1;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
lowerBound = lowest;
|
|
51
|
+
upperBound = highest + 1;
|
|
52
|
+
}
|
|
53
|
+
_this._priceTree.forEach(function (price, queue) {
|
|
54
|
+
if ((_this._side === Side.BUY && price >= lowest) ||
|
|
55
|
+
(_this._side === Side.SELL && price <= highest)) {
|
|
56
|
+
queues.push(queue);
|
|
57
|
+
}
|
|
58
|
+
}, lowerBound, // Inclusive
|
|
59
|
+
upperBound);
|
|
60
|
+
return queues;
|
|
61
|
+
};
|
|
62
|
+
var compare = side === Side.SELL
|
|
63
|
+
? function (a, b) { return a - b; }
|
|
64
|
+
: function (a, b) { return b - a; };
|
|
65
|
+
this._priceTree = createRBTree(compare);
|
|
66
|
+
this._side = side;
|
|
67
|
+
}
|
|
68
|
+
return StopSide;
|
|
69
|
+
}());
|
|
70
|
+
export { StopSide };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export var Side;
|
|
2
|
+
(function (Side) {
|
|
3
|
+
Side["BUY"] = "buy";
|
|
4
|
+
Side["SELL"] = "sell";
|
|
5
|
+
})(Side || (Side = {}));
|
|
6
|
+
export var OrderType;
|
|
7
|
+
(function (OrderType) {
|
|
8
|
+
OrderType["LIMIT"] = "limit";
|
|
9
|
+
OrderType["MARKET"] = "market";
|
|
10
|
+
OrderType["OCO"] = "oco";
|
|
11
|
+
OrderType["STOP_LIMIT"] = "stop_limit";
|
|
12
|
+
OrderType["STOP_MARKET"] = "stop_market";
|
|
13
|
+
})(OrderType || (OrderType = {}));
|
|
14
|
+
export var TimeInForce;
|
|
15
|
+
(function (TimeInForce) {
|
|
16
|
+
TimeInForce["GTC"] = "GTC";
|
|
17
|
+
TimeInForce["IOC"] = "IOC";
|
|
18
|
+
TimeInForce["FOK"] = "FOK";
|
|
19
|
+
})(TimeInForce || (TimeInForce = {}));
|
|
20
|
+
/* node:coverage enable */
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { IError } from "./types";
|
|
2
|
+
export declare enum ERROR {
|
|
3
|
+
DEFAULT = "DEFAULT",
|
|
4
|
+
INSUFFICIENT_QUANTITY = "INSUFFICIENT_QUANTITY",
|
|
5
|
+
INVALID_CONDITIONAL_ORDER = "INVALID_CONDITIONAL_ORDER",
|
|
6
|
+
INVALID_JOURNAL_LOG = "INVALID_JOURNAL_LOG",
|
|
7
|
+
INVALID_ORDER_TYPE = "INVALID_ORDER_TYPE",
|
|
8
|
+
INVALID_PRICE = "INVALID_PRICE",
|
|
9
|
+
INVALID_PRICE_LEVEL = "INVALID_PRICE_LEVEL",
|
|
10
|
+
INVALID_PRICE_OR_QUANTITY = "INVALID_PRICE_OR_QUANTITY",
|
|
11
|
+
INVALID_QUANTITY = "INVALID_QUANTITY",
|
|
12
|
+
INVALID_SIDE = "INVALID_SIDE",
|
|
13
|
+
INVALID_TIF = "INVALID_TIF",
|
|
14
|
+
LIMIT_ORDER_FOK_NOT_FILLABLE = "LIMIT_ORDER_FOK_NOT_FILLABLE",
|
|
15
|
+
LIMIT_ORDER_POST_ONLY = "LIMIT_ORDER_POST_ONLY",
|
|
16
|
+
ORDER_ALREDY_EXISTS = "ORDER_ALREDY_EXISTS",
|
|
17
|
+
ORDER_NOT_FOUND = "ORDER_NOT_FOUND"
|
|
18
|
+
}
|
|
19
|
+
export declare const ErrorCodes: Record<ERROR, number>;
|
|
20
|
+
export declare const ErrorMessages: Record<ERROR, string>;
|
|
21
|
+
export declare class OrderBookError implements IError {
|
|
22
|
+
message: string;
|
|
23
|
+
code: number;
|
|
24
|
+
constructor(error?: ERROR | string);
|
|
25
|
+
}
|
|
26
|
+
export declare const CustomError: (error?: ERROR | string) => OrderBookError;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { OrderBook } from "./orderbook";
|
|
2
|
+
import { OrderType, Side } from "./types";
|
|
3
|
+
import type { CreateOrderOptions, ICancelOrder, IProcessOrder, LimitOrderOptions, MarketOrderOptions, OCOOrderOptions, OrderBookOptions, OrderUpdatePrice, OrderUpdateSize, StopLimitOrderOptions, StopMarketOrderOptions } from "./types";
|
|
4
|
+
export { type CreateOrderOptions, type ICancelOrder, type IProcessOrder, type LimitOrderOptions, type MarketOrderOptions, type OCOOrderOptions, OrderBook, type OrderBookOptions, OrderType, type OrderUpdatePrice, type OrderUpdateSize, Side, type StopLimitOrderOptions, type StopMarketOrderOptions, };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type ILimitOrder, type IStopLimitOrder, type IStopMarketOrder, type InternalLimitOrderOptions, type InternalStopLimitOrderOptions, type InternalStopMarketOrderOptions, type OrderOptions, OrderType, type Side, type TimeInForce } from "./types";
|
|
2
|
+
declare abstract class BaseOrder {
|
|
3
|
+
readonly _id: string;
|
|
4
|
+
readonly _side: Side;
|
|
5
|
+
_size: number;
|
|
6
|
+
_time: number;
|
|
7
|
+
constructor(options: OrderOptions);
|
|
8
|
+
get id(): string;
|
|
9
|
+
get side(): Side;
|
|
10
|
+
get size(): number;
|
|
11
|
+
set size(size: number);
|
|
12
|
+
get time(): number;
|
|
13
|
+
set time(time: number);
|
|
14
|
+
abstract toString(): void;
|
|
15
|
+
abstract toJSON(): void;
|
|
16
|
+
abstract toObject(): void;
|
|
17
|
+
}
|
|
18
|
+
export declare class LimitOrder extends BaseOrder {
|
|
19
|
+
private readonly _type;
|
|
20
|
+
readonly _origSize: number;
|
|
21
|
+
private _price;
|
|
22
|
+
private readonly _timeInForce;
|
|
23
|
+
private readonly _makerQty;
|
|
24
|
+
private readonly _takerQty;
|
|
25
|
+
private readonly _postOnly;
|
|
26
|
+
private readonly _ocoStopPrice?;
|
|
27
|
+
constructor(options: InternalLimitOrderOptions);
|
|
28
|
+
get type(): OrderType.LIMIT;
|
|
29
|
+
get price(): number;
|
|
30
|
+
set price(price: number);
|
|
31
|
+
get timeInForce(): TimeInForce;
|
|
32
|
+
get postOnly(): boolean;
|
|
33
|
+
get origSize(): number;
|
|
34
|
+
get makerQty(): number;
|
|
35
|
+
get takerQty(): number;
|
|
36
|
+
get ocoStopPrice(): number | undefined;
|
|
37
|
+
toString: () => string;
|
|
38
|
+
toJSON: () => string;
|
|
39
|
+
toObject: () => ILimitOrder;
|
|
40
|
+
}
|
|
41
|
+
export declare class StopMarketOrder extends BaseOrder {
|
|
42
|
+
private readonly _type;
|
|
43
|
+
private readonly _stopPrice;
|
|
44
|
+
constructor(options: InternalStopMarketOrderOptions);
|
|
45
|
+
get type(): OrderType.STOP_MARKET;
|
|
46
|
+
get stopPrice(): number;
|
|
47
|
+
toString: () => string;
|
|
48
|
+
toJSON: () => string;
|
|
49
|
+
toObject: () => IStopMarketOrder;
|
|
50
|
+
}
|
|
51
|
+
export declare class StopLimitOrder extends BaseOrder {
|
|
52
|
+
private readonly _type;
|
|
53
|
+
private _price;
|
|
54
|
+
private readonly _stopPrice;
|
|
55
|
+
private readonly _timeInForce;
|
|
56
|
+
private readonly _isOCO;
|
|
57
|
+
constructor(options: InternalStopLimitOrderOptions);
|
|
58
|
+
get type(): OrderType.STOP_LIMIT;
|
|
59
|
+
get price(): number;
|
|
60
|
+
set price(price: number);
|
|
61
|
+
get stopPrice(): number;
|
|
62
|
+
get timeInForce(): TimeInForce;
|
|
63
|
+
get isOCO(): boolean;
|
|
64
|
+
toString: () => string;
|
|
65
|
+
toJSON: () => string;
|
|
66
|
+
toObject: () => IStopLimitOrder;
|
|
67
|
+
}
|
|
68
|
+
export declare const OrderFactory: {
|
|
69
|
+
createOrder<T extends OrderOptions>(options: T): T extends InternalLimitOrderOptions ? LimitOrder : T extends InternalStopLimitOrderOptions ? StopLimitOrder : T extends InternalStopMarketOrderOptions ? StopMarketOrder : never;
|
|
70
|
+
};
|
|
71
|
+
export {};
|