@drift-labs/sdk 2.17.0 → 2.18.0-beta.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.
- package/lib/constants/perpMarkets.js +10 -0
- package/lib/dlob/DLOB.d.ts +32 -26
- package/lib/dlob/DLOB.js +246 -173
- package/lib/dlob/DLOBNode.d.ts +11 -5
- package/lib/dlob/DLOBNode.js +13 -5
- package/lib/driftClient.js +5 -10
- package/lib/examples/loadDlob.js +1 -1
- package/lib/factory/oracleClient.js +4 -0
- package/lib/idl/drift.json +4 -1
- package/lib/math/auction.d.ts +1 -0
- package/lib/math/auction.js +9 -2
- package/lib/math/orders.d.ts +2 -0
- package/lib/math/orders.js +11 -2
- package/lib/math/spotBalance.js +1 -1
- package/lib/math/trade.d.ts +6 -0
- package/lib/math/trade.js +6 -0
- package/lib/oracles/pythClient.d.ts +4 -3
- package/lib/oracles/pythClient.js +8 -7
- package/lib/types.d.ts +4 -1
- package/lib/types.js +1 -0
- package/lib/user.js +8 -9
- package/package.json +1 -1
- package/src/constants/perpMarkets.ts +10 -0
- package/src/dlob/DLOB.ts +387 -183
- package/src/dlob/DLOBNode.ts +20 -7
- package/src/driftClient.ts +5 -10
- package/src/examples/loadDlob.ts +1 -1
- package/src/factory/oracleClient.ts +5 -0
- package/src/idl/drift.json +4 -1
- package/src/math/auction.ts +13 -1
- package/src/math/orders.ts +14 -1
- package/src/math/spotBalance.ts +1 -1
- package/src/math/trade.ts +6 -0
- package/src/oracles/pythClient.ts +27 -8
- package/src/types.ts +2 -1
- package/src/user.ts +7 -8
- package/tests/dlob/test.ts +800 -82
package/lib/dlob/DLOB.js
CHANGED
|
@@ -15,6 +15,7 @@ class DLOB {
|
|
|
15
15
|
constructor() {
|
|
16
16
|
this.openOrders = new Map();
|
|
17
17
|
this.orderLists = new Map();
|
|
18
|
+
this.maxSlotForRestingLimitOrders = 0;
|
|
18
19
|
this.initialized = false;
|
|
19
20
|
this.init();
|
|
20
21
|
}
|
|
@@ -42,6 +43,7 @@ class DLOB {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
this.orderLists.clear();
|
|
46
|
+
this.maxSlotForRestingLimitOrders = 0;
|
|
45
47
|
this.init();
|
|
46
48
|
}
|
|
47
49
|
/**
|
|
@@ -49,7 +51,7 @@ class DLOB {
|
|
|
49
51
|
*
|
|
50
52
|
* @returns a promise that resolves when the DLOB is initialized
|
|
51
53
|
*/
|
|
52
|
-
async initFromUserMap(userMap) {
|
|
54
|
+
async initFromUserMap(userMap, slot) {
|
|
53
55
|
if (this.initialized) {
|
|
54
56
|
return false;
|
|
55
57
|
}
|
|
@@ -58,26 +60,26 @@ class DLOB {
|
|
|
58
60
|
const userAccount = user.getUserAccount();
|
|
59
61
|
const userAccountPubkey = user.getUserAccountPublicKey();
|
|
60
62
|
for (const order of userAccount.orders) {
|
|
61
|
-
this.insertOrder(order, userAccountPubkey);
|
|
63
|
+
this.insertOrder(order, userAccountPubkey, slot);
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
this.initialized = true;
|
|
65
67
|
return true;
|
|
66
68
|
}
|
|
67
|
-
initFromOrders(dlobOrders) {
|
|
69
|
+
initFromOrders(dlobOrders, slot) {
|
|
68
70
|
if (this.initialized) {
|
|
69
71
|
return false;
|
|
70
72
|
}
|
|
71
73
|
for (const { user, order } of dlobOrders) {
|
|
72
|
-
this.insertOrder(order, user);
|
|
74
|
+
this.insertOrder(order, user, slot);
|
|
73
75
|
}
|
|
74
76
|
this.initialized = true;
|
|
75
77
|
return true;
|
|
76
78
|
}
|
|
77
|
-
handleOrderRecord(record) {
|
|
78
|
-
this.insertOrder(record.order, record.user);
|
|
79
|
+
handleOrderRecord(record, slot) {
|
|
80
|
+
this.insertOrder(record.order, record.user, slot);
|
|
79
81
|
}
|
|
80
|
-
handleOrderActionRecord(record) {
|
|
82
|
+
handleOrderActionRecord(record, slot) {
|
|
81
83
|
if (__1.isOneOfVariant(record.action, ['place', 'expire'])) {
|
|
82
84
|
return;
|
|
83
85
|
}
|
|
@@ -85,13 +87,13 @@ class DLOB {
|
|
|
85
87
|
if (record.taker !== null) {
|
|
86
88
|
const takerOrder = this.getOrder(record.takerOrderId, record.taker);
|
|
87
89
|
if (takerOrder) {
|
|
88
|
-
this.trigger(takerOrder, record.taker);
|
|
90
|
+
this.trigger(takerOrder, record.taker, slot);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
if (record.maker !== null) {
|
|
92
94
|
const makerOrder = this.getOrder(record.makerOrderId, record.maker);
|
|
93
95
|
if (makerOrder) {
|
|
94
|
-
this.trigger(makerOrder, record.maker);
|
|
96
|
+
this.trigger(makerOrder, record.maker, slot);
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
}
|
|
@@ -99,13 +101,13 @@ class DLOB {
|
|
|
99
101
|
if (record.taker !== null) {
|
|
100
102
|
const takerOrder = this.getOrder(record.takerOrderId, record.taker);
|
|
101
103
|
if (takerOrder) {
|
|
102
|
-
this.updateOrder(takerOrder, record.taker, record.takerOrderCumulativeBaseAssetAmountFilled);
|
|
104
|
+
this.updateOrder(takerOrder, record.taker, slot, record.takerOrderCumulativeBaseAssetAmountFilled);
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
107
|
if (record.maker !== null) {
|
|
106
108
|
const makerOrder = this.getOrder(record.makerOrderId, record.maker);
|
|
107
109
|
if (makerOrder) {
|
|
108
|
-
this.updateOrder(makerOrder, record.maker, record.makerOrderCumulativeBaseAssetAmountFilled);
|
|
110
|
+
this.updateOrder(makerOrder, record.maker, slot, record.makerOrderCumulativeBaseAssetAmountFilled);
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
}
|
|
@@ -113,18 +115,18 @@ class DLOB {
|
|
|
113
115
|
if (record.taker !== null) {
|
|
114
116
|
const takerOrder = this.getOrder(record.takerOrderId, record.taker);
|
|
115
117
|
if (takerOrder) {
|
|
116
|
-
this.delete(takerOrder, record.taker);
|
|
118
|
+
this.delete(takerOrder, record.taker, slot);
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
if (record.maker !== null) {
|
|
120
122
|
const makerOrder = this.getOrder(record.makerOrderId, record.maker);
|
|
121
123
|
if (makerOrder) {
|
|
122
|
-
this.delete(makerOrder, record.maker);
|
|
124
|
+
this.delete(makerOrder, record.maker, slot);
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
|
-
insertOrder(order, userAccount, onInsert) {
|
|
129
|
+
insertOrder(order, userAccount, slot, onInsert) {
|
|
128
130
|
var _a;
|
|
129
131
|
if (__1.isVariant(order.status, 'init')) {
|
|
130
132
|
return;
|
|
@@ -141,21 +143,25 @@ class DLOB {
|
|
|
141
143
|
.get(marketType)
|
|
142
144
|
.add(NodeList_1.getOrderSignature(order.orderId, userAccount));
|
|
143
145
|
}
|
|
144
|
-
(_a = this.getListForOrder(order)) === null || _a === void 0 ? void 0 : _a.insert(order, marketType, userAccount);
|
|
146
|
+
(_a = this.getListForOrder(order, slot)) === null || _a === void 0 ? void 0 : _a.insert(order, marketType, userAccount);
|
|
145
147
|
if (onInsert) {
|
|
146
148
|
onInsert();
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
151
|
addOrderList(marketType, marketIndex) {
|
|
150
152
|
this.orderLists.get(marketType).set(marketIndex, {
|
|
151
|
-
|
|
152
|
-
ask: new NodeList_1.NodeList('
|
|
153
|
-
bid: new NodeList_1.NodeList('
|
|
153
|
+
restingLimit: {
|
|
154
|
+
ask: new NodeList_1.NodeList('restingLimit', 'asc'),
|
|
155
|
+
bid: new NodeList_1.NodeList('restingLimit', 'desc'),
|
|
154
156
|
},
|
|
155
157
|
floatingLimit: {
|
|
156
158
|
ask: new NodeList_1.NodeList('floatingLimit', 'asc'),
|
|
157
159
|
bid: new NodeList_1.NodeList('floatingLimit', 'desc'),
|
|
158
160
|
},
|
|
161
|
+
takingLimit: {
|
|
162
|
+
ask: new NodeList_1.NodeList('takingLimit', 'asc'),
|
|
163
|
+
bid: new NodeList_1.NodeList('takingLimit', 'asc'), // always sort ascending for market orders
|
|
164
|
+
},
|
|
159
165
|
market: {
|
|
160
166
|
ask: new NodeList_1.NodeList('market', 'asc'),
|
|
161
167
|
bid: new NodeList_1.NodeList('market', 'asc'), // always sort ascending for market orders
|
|
@@ -166,10 +172,11 @@ class DLOB {
|
|
|
166
172
|
},
|
|
167
173
|
});
|
|
168
174
|
}
|
|
169
|
-
updateOrder(order, userAccount, cumulativeBaseAssetAmountFilled, onUpdate) {
|
|
175
|
+
updateOrder(order, userAccount, slot, cumulativeBaseAssetAmountFilled, onUpdate) {
|
|
170
176
|
var _a;
|
|
177
|
+
this.updateRestingLimitOrders(slot);
|
|
171
178
|
if (order.baseAssetAmount.eq(cumulativeBaseAssetAmountFilled)) {
|
|
172
|
-
this.delete(order, userAccount);
|
|
179
|
+
this.delete(order, userAccount, slot);
|
|
173
180
|
return;
|
|
174
181
|
}
|
|
175
182
|
if (order.baseAssetAmountFilled.eq(cumulativeBaseAssetAmountFilled)) {
|
|
@@ -179,16 +186,17 @@ class DLOB {
|
|
|
179
186
|
...order,
|
|
180
187
|
};
|
|
181
188
|
newOrder.baseAssetAmountFilled = cumulativeBaseAssetAmountFilled;
|
|
182
|
-
(_a = this.getListForOrder(order)) === null || _a === void 0 ? void 0 : _a.update(newOrder, userAccount);
|
|
189
|
+
(_a = this.getListForOrder(order, slot)) === null || _a === void 0 ? void 0 : _a.update(newOrder, userAccount);
|
|
183
190
|
if (onUpdate) {
|
|
184
191
|
onUpdate();
|
|
185
192
|
}
|
|
186
193
|
}
|
|
187
|
-
trigger(order, userAccount, onTrigger) {
|
|
194
|
+
trigger(order, userAccount, slot, onTrigger) {
|
|
188
195
|
var _a;
|
|
189
196
|
if (__1.isVariant(order.status, 'init')) {
|
|
190
197
|
return;
|
|
191
198
|
}
|
|
199
|
+
this.updateRestingLimitOrders(slot);
|
|
192
200
|
if (__1.isTriggered(order)) {
|
|
193
201
|
return;
|
|
194
202
|
}
|
|
@@ -196,22 +204,23 @@ class DLOB {
|
|
|
196
204
|
const triggerList = this.orderLists.get(marketType).get(order.marketIndex)
|
|
197
205
|
.trigger[__1.isVariant(order.triggerCondition, 'above') ? 'above' : 'below'];
|
|
198
206
|
triggerList.remove(order, userAccount);
|
|
199
|
-
(_a = this.getListForOrder(order)) === null || _a === void 0 ? void 0 : _a.insert(order, marketType, userAccount);
|
|
207
|
+
(_a = this.getListForOrder(order, slot)) === null || _a === void 0 ? void 0 : _a.insert(order, marketType, userAccount);
|
|
200
208
|
if (onTrigger) {
|
|
201
209
|
onTrigger();
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
|
-
delete(order, userAccount, onDelete) {
|
|
212
|
+
delete(order, userAccount, slot, onDelete) {
|
|
205
213
|
var _a;
|
|
206
214
|
if (__1.isVariant(order.status, 'init')) {
|
|
207
215
|
return;
|
|
208
216
|
}
|
|
209
|
-
|
|
217
|
+
this.updateRestingLimitOrders(slot);
|
|
218
|
+
(_a = this.getListForOrder(order, slot)) === null || _a === void 0 ? void 0 : _a.remove(order, userAccount);
|
|
210
219
|
if (onDelete) {
|
|
211
220
|
onDelete();
|
|
212
221
|
}
|
|
213
222
|
}
|
|
214
|
-
getListForOrder(order) {
|
|
223
|
+
getListForOrder(order, slot) {
|
|
215
224
|
const isInactiveTriggerOrder = __1.mustBeTriggered(order) && !__1.isTriggered(order);
|
|
216
225
|
let type;
|
|
217
226
|
if (isInactiveTriggerOrder) {
|
|
@@ -224,7 +233,8 @@ class DLOB {
|
|
|
224
233
|
type = 'floatingLimit';
|
|
225
234
|
}
|
|
226
235
|
else {
|
|
227
|
-
|
|
236
|
+
const isResting = __1.isRestingLimitOrder(order, slot);
|
|
237
|
+
type = isResting ? 'restingLimit' : 'takingLimit';
|
|
228
238
|
}
|
|
229
239
|
let subType;
|
|
230
240
|
if (isInactiveTriggerOrder) {
|
|
@@ -239,6 +249,42 @@ class DLOB {
|
|
|
239
249
|
}
|
|
240
250
|
return this.orderLists.get(marketType).get(order.marketIndex)[type][subType];
|
|
241
251
|
}
|
|
252
|
+
updateRestingLimitOrders(slot) {
|
|
253
|
+
if (slot <= this.maxSlotForRestingLimitOrders) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
this.maxSlotForRestingLimitOrders = slot;
|
|
257
|
+
this.updateRestingLimitOrdersForMarketType(slot, 'perp');
|
|
258
|
+
this.updateRestingLimitOrdersForMarketType(slot, 'spot');
|
|
259
|
+
}
|
|
260
|
+
updateRestingLimitOrdersForMarketType(slot, marketTypeStr) {
|
|
261
|
+
for (const [_, nodeLists] of this.orderLists.get(marketTypeStr)) {
|
|
262
|
+
const nodesToUpdate = [];
|
|
263
|
+
for (const node of nodeLists.takingLimit.ask.getGenerator()) {
|
|
264
|
+
if (!__1.isRestingLimitOrder(node.order, slot)) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
nodesToUpdate.push({
|
|
268
|
+
side: 'ask',
|
|
269
|
+
node,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
for (const node of nodeLists.takingLimit.bid.getGenerator()) {
|
|
273
|
+
if (!__1.isRestingLimitOrder(node.order, slot)) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
nodesToUpdate.push({
|
|
277
|
+
side: 'bid',
|
|
278
|
+
node,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
for (const nodeToUpdate of nodesToUpdate) {
|
|
282
|
+
const { side, node } = nodeToUpdate;
|
|
283
|
+
nodeLists.takingLimit[side].remove(node.order, node.userAccount);
|
|
284
|
+
nodeLists.restingLimit[side].insert(node.order, marketTypeStr, node.userAccount);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
242
288
|
getOrder(orderId, userAccount) {
|
|
243
289
|
for (const nodeList of this.getNodeLists()) {
|
|
244
290
|
const node = nodeList.get(orderId, userAccount);
|
|
@@ -253,42 +299,45 @@ class DLOB {
|
|
|
253
299
|
return [];
|
|
254
300
|
}
|
|
255
301
|
const isAmmPaused = exchangeStatus_1.ammPaused(stateAccount, marketAccount);
|
|
256
|
-
const
|
|
257
|
-
|
|
302
|
+
const minAuctionDuration = __1.isVariant(marketType, 'perp')
|
|
303
|
+
? stateAccount.minPerpAuctionDuration
|
|
304
|
+
: 0;
|
|
305
|
+
const restingLimitOrderNodesToFill = this.findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid);
|
|
306
|
+
const takingOrderNodesToFill = this.findTakingNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid);
|
|
258
307
|
// get expired market nodes
|
|
259
308
|
const expiredNodesToFill = this.findExpiredNodesToFill(marketIndex, ts, marketType);
|
|
260
|
-
return
|
|
309
|
+
return restingLimitOrderNodesToFill.concat(takingOrderNodesToFill, expiredNodesToFill);
|
|
261
310
|
}
|
|
262
|
-
|
|
311
|
+
findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid) {
|
|
263
312
|
const nodesToFill = new Array();
|
|
264
|
-
const crossingNodes = this.
|
|
313
|
+
const crossingNodes = this.findCrossingRestingLimitOrders(marketIndex, slot, marketType, oraclePriceData, minAuctionDuration, fallbackAsk, fallbackBid);
|
|
265
314
|
for (const crossingNode of crossingNodes) {
|
|
266
315
|
nodesToFill.push(crossingNode);
|
|
267
316
|
}
|
|
268
317
|
if (fallbackBid && !isAmmPaused) {
|
|
269
|
-
const askGenerator = this.
|
|
318
|
+
const askGenerator = this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData);
|
|
270
319
|
const asksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, askGenerator, fallbackBid, (askPrice, fallbackPrice) => {
|
|
271
320
|
return askPrice.lte(fallbackPrice);
|
|
272
|
-
});
|
|
321
|
+
}, minAuctionDuration);
|
|
273
322
|
for (const askCrossingFallback of asksCrossingFallback) {
|
|
274
323
|
nodesToFill.push(askCrossingFallback);
|
|
275
324
|
}
|
|
276
325
|
}
|
|
277
326
|
if (fallbackAsk && !isAmmPaused) {
|
|
278
|
-
const bidGenerator = this.
|
|
327
|
+
const bidGenerator = this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData);
|
|
279
328
|
const bidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, bidGenerator, fallbackAsk, (bidPrice, fallbackPrice) => {
|
|
280
329
|
return bidPrice.gte(fallbackPrice);
|
|
281
|
-
});
|
|
330
|
+
}, minAuctionDuration);
|
|
282
331
|
for (const bidCrossingFallback of bidsCrossingFallback) {
|
|
283
332
|
nodesToFill.push(bidCrossingFallback);
|
|
284
333
|
}
|
|
285
334
|
}
|
|
286
335
|
return nodesToFill;
|
|
287
336
|
}
|
|
288
|
-
|
|
337
|
+
findTakingNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid) {
|
|
289
338
|
const nodesToFill = new Array();
|
|
290
|
-
let
|
|
291
|
-
const
|
|
339
|
+
let takingOrderGenerator = this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData);
|
|
340
|
+
const takingAsksCrossingBids = this.findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takingOrderGenerator, this.getMakerLimitBids.bind(this), (takerPrice, makerPrice) => {
|
|
292
341
|
if (__1.isVariant(marketType, 'spot')) {
|
|
293
342
|
if (takerPrice === undefined) {
|
|
294
343
|
return false;
|
|
@@ -299,20 +348,20 @@ class DLOB {
|
|
|
299
348
|
}
|
|
300
349
|
return takerPrice === undefined || takerPrice.lte(makerPrice);
|
|
301
350
|
}, fallbackAsk);
|
|
302
|
-
for (const
|
|
303
|
-
nodesToFill.push(
|
|
351
|
+
for (const takingAskCrossingBid of takingAsksCrossingBids) {
|
|
352
|
+
nodesToFill.push(takingAskCrossingBid);
|
|
304
353
|
}
|
|
305
354
|
if (fallbackBid && !isAmmPaused) {
|
|
306
|
-
|
|
307
|
-
const
|
|
355
|
+
takingOrderGenerator = this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData);
|
|
356
|
+
const takingAsksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator, fallbackBid, (takerPrice, fallbackPrice) => {
|
|
308
357
|
return takerPrice === undefined || takerPrice.lte(fallbackPrice);
|
|
309
|
-
});
|
|
310
|
-
for (const
|
|
311
|
-
nodesToFill.push(
|
|
358
|
+
}, minAuctionDuration);
|
|
359
|
+
for (const takingAskCrossingFallback of takingAsksCrossingFallback) {
|
|
360
|
+
nodesToFill.push(takingAskCrossingFallback);
|
|
312
361
|
}
|
|
313
362
|
}
|
|
314
|
-
|
|
315
|
-
const
|
|
363
|
+
takingOrderGenerator = this.getTakingBids(marketIndex, marketType, slot, oraclePriceData);
|
|
364
|
+
const takingBidsToFill = this.findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takingOrderGenerator, this.getMakerLimitAsks.bind(this), (takerPrice, makerPrice) => {
|
|
316
365
|
if (__1.isVariant(marketType, 'spot')) {
|
|
317
366
|
if (takerPrice === undefined) {
|
|
318
367
|
return false;
|
|
@@ -323,21 +372,21 @@ class DLOB {
|
|
|
323
372
|
}
|
|
324
373
|
return takerPrice === undefined || takerPrice.gte(makerPrice);
|
|
325
374
|
}, fallbackBid);
|
|
326
|
-
for (const
|
|
327
|
-
nodesToFill.push(
|
|
375
|
+
for (const takingBidToFill of takingBidsToFill) {
|
|
376
|
+
nodesToFill.push(takingBidToFill);
|
|
328
377
|
}
|
|
329
378
|
if (fallbackAsk && !isAmmPaused) {
|
|
330
|
-
|
|
331
|
-
const
|
|
379
|
+
takingOrderGenerator = this.getTakingBids(marketIndex, marketType, slot, oraclePriceData);
|
|
380
|
+
const takingBidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator, fallbackAsk, (takerPrice, fallbackPrice) => {
|
|
332
381
|
return takerPrice === undefined || takerPrice.gte(fallbackPrice);
|
|
333
|
-
});
|
|
334
|
-
for (const marketBidCrossingFallback of
|
|
382
|
+
}, minAuctionDuration);
|
|
383
|
+
for (const marketBidCrossingFallback of takingBidsCrossingFallback) {
|
|
335
384
|
nodesToFill.push(marketBidCrossingFallback);
|
|
336
385
|
}
|
|
337
386
|
}
|
|
338
387
|
return nodesToFill;
|
|
339
388
|
}
|
|
340
|
-
|
|
389
|
+
findTakingNodesCrossingMakerNodes(marketIndex, slot, marketType, oraclePriceData, takerNodeGenerator, makerNodeGeneratorFn, doesCross, fallbackPrice) {
|
|
341
390
|
const nodesToFill = new Array();
|
|
342
391
|
for (const takerNode of takerNodeGenerator) {
|
|
343
392
|
const makerNodeGenerator = makerNodeGeneratorFn(marketIndex, slot, marketType, oraclePriceData, fallbackPrice);
|
|
@@ -367,11 +416,11 @@ class DLOB {
|
|
|
367
416
|
const newMakerOrder = { ...makerOrder };
|
|
368
417
|
newMakerOrder.baseAssetAmountFilled =
|
|
369
418
|
makerOrder.baseAssetAmountFilled.add(baseFilled);
|
|
370
|
-
this.getListForOrder(newMakerOrder).update(newMakerOrder, makerNode.userAccount);
|
|
419
|
+
this.getListForOrder(newMakerOrder, slot).update(newMakerOrder, makerNode.userAccount);
|
|
371
420
|
const newTakerOrder = { ...takerOrder };
|
|
372
421
|
newTakerOrder.baseAssetAmountFilled =
|
|
373
422
|
takerOrder.baseAssetAmountFilled.add(baseFilled);
|
|
374
|
-
this.getListForOrder(newTakerOrder).update(newTakerOrder, takerNode.userAccount);
|
|
423
|
+
this.getListForOrder(newTakerOrder, slot).update(newTakerOrder, takerNode.userAccount);
|
|
375
424
|
if (newTakerOrder.baseAssetAmountFilled.eq(takerOrder.baseAssetAmount)) {
|
|
376
425
|
break;
|
|
377
426
|
}
|
|
@@ -379,7 +428,7 @@ class DLOB {
|
|
|
379
428
|
}
|
|
380
429
|
return nodesToFill;
|
|
381
430
|
}
|
|
382
|
-
findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, nodeGenerator, fallbackPrice, doesCross) {
|
|
431
|
+
findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, nodeGenerator, fallbackPrice, doesCross, minAuctionDuration) {
|
|
383
432
|
var _a;
|
|
384
433
|
const nodesToFill = new Array();
|
|
385
434
|
let nextNode = nodeGenerator.next();
|
|
@@ -393,7 +442,8 @@ class DLOB {
|
|
|
393
442
|
// order crosses if there is no limit price or it crosses fallback price
|
|
394
443
|
const crosses = doesCross(nodePrice, fallbackPrice);
|
|
395
444
|
// fallback is available if auction is complete or it's a spot order
|
|
396
|
-
const fallbackAvailable = __1.isVariant(marketType, 'spot') ||
|
|
445
|
+
const fallbackAvailable = __1.isVariant(marketType, 'spot') ||
|
|
446
|
+
__1.isFallbackAvailableLiquiditySource(node.order, minAuctionDuration, slot);
|
|
397
447
|
if (crosses && fallbackAvailable) {
|
|
398
448
|
nodesToFill.push({
|
|
399
449
|
node: node,
|
|
@@ -413,12 +463,14 @@ class DLOB {
|
|
|
413
463
|
}
|
|
414
464
|
// All bids/asks that can expire
|
|
415
465
|
const bidGenerators = [
|
|
416
|
-
nodeLists.
|
|
466
|
+
nodeLists.takingLimit.bid.getGenerator(),
|
|
467
|
+
nodeLists.restingLimit.bid.getGenerator(),
|
|
417
468
|
nodeLists.floatingLimit.bid.getGenerator(),
|
|
418
469
|
nodeLists.market.bid.getGenerator(),
|
|
419
470
|
];
|
|
420
471
|
const askGenerators = [
|
|
421
|
-
nodeLists.
|
|
472
|
+
nodeLists.takingLimit.ask.getGenerator(),
|
|
473
|
+
nodeLists.restingLimit.ask.getGenerator(),
|
|
422
474
|
nodeLists.floatingLimit.ask.getGenerator(),
|
|
423
475
|
nodeLists.market.ask.getGenerator(),
|
|
424
476
|
];
|
|
@@ -442,52 +494,50 @@ class DLOB {
|
|
|
442
494
|
}
|
|
443
495
|
return nodesToFill;
|
|
444
496
|
}
|
|
445
|
-
findJitAuctionNodesToFill(marketIndex, slot, marketType) {
|
|
497
|
+
findJitAuctionNodesToFill(marketIndex, slot, oraclePriceData, marketType) {
|
|
446
498
|
const nodesToFill = new Array();
|
|
447
499
|
// Then see if there are orders still in JIT auction
|
|
448
|
-
for (const marketBid of this.
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
});
|
|
453
|
-
}
|
|
500
|
+
for (const marketBid of this.getTakingBids(marketIndex, marketType, slot, oraclePriceData)) {
|
|
501
|
+
nodesToFill.push({
|
|
502
|
+
node: marketBid,
|
|
503
|
+
});
|
|
454
504
|
}
|
|
455
|
-
for (const marketAsk of this.
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
});
|
|
460
|
-
}
|
|
505
|
+
for (const marketAsk of this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData)) {
|
|
506
|
+
nodesToFill.push({
|
|
507
|
+
node: marketAsk,
|
|
508
|
+
});
|
|
461
509
|
}
|
|
462
510
|
return nodesToFill;
|
|
463
511
|
}
|
|
464
|
-
*
|
|
512
|
+
*getTakingBids(marketIndex, marketType, slot, oraclePriceData) {
|
|
465
513
|
const marketTypeStr = __1.getVariant(marketType);
|
|
466
514
|
const orderLists = this.orderLists.get(marketTypeStr).get(marketIndex);
|
|
467
515
|
if (!orderLists) {
|
|
468
516
|
return;
|
|
469
517
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
518
|
+
this.updateRestingLimitOrders(slot);
|
|
519
|
+
const generatorList = [
|
|
520
|
+
orderLists.market.bid.getGenerator(),
|
|
521
|
+
orderLists.takingLimit.bid.getGenerator(),
|
|
522
|
+
];
|
|
523
|
+
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode) => {
|
|
524
|
+
return bestNode.order.slot.lt(currentNode.order.slot);
|
|
525
|
+
});
|
|
477
526
|
}
|
|
478
|
-
*
|
|
527
|
+
*getTakingAsks(marketIndex, marketType, slot, oraclePriceData) {
|
|
479
528
|
const marketTypeStr = __1.getVariant(marketType);
|
|
480
529
|
const orderLists = this.orderLists.get(marketTypeStr).get(marketIndex);
|
|
481
530
|
if (!orderLists) {
|
|
482
531
|
return;
|
|
483
532
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
533
|
+
this.updateRestingLimitOrders(slot);
|
|
534
|
+
const generatorList = [
|
|
535
|
+
orderLists.market.ask.getGenerator(),
|
|
536
|
+
orderLists.takingLimit.ask.getGenerator(),
|
|
537
|
+
];
|
|
538
|
+
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode) => {
|
|
539
|
+
return bestNode.order.slot.lt(currentNode.order.slot);
|
|
540
|
+
});
|
|
491
541
|
}
|
|
492
542
|
*getBestNode(generatorList, oraclePriceData, slot, compareFcn) {
|
|
493
543
|
const generators = generatorList.map((generator) => {
|
|
@@ -507,16 +557,7 @@ class DLOB {
|
|
|
507
557
|
}
|
|
508
558
|
const bestValue = bestGenerator.next.value;
|
|
509
559
|
const currentValue = currentGenerator.next.value;
|
|
510
|
-
|
|
511
|
-
if (bestValue.order && __1.isMarketOrder(bestValue.order)) {
|
|
512
|
-
return bestGenerator;
|
|
513
|
-
}
|
|
514
|
-
if (currentValue.order && __1.isMarketOrder(currentValue.order)) {
|
|
515
|
-
return currentGenerator;
|
|
516
|
-
}
|
|
517
|
-
const bestPrice = bestValue.getPrice(oraclePriceData, slot);
|
|
518
|
-
const currentPrice = currentValue.getPrice(oraclePriceData, slot);
|
|
519
|
-
return compareFcn(bestPrice, currentPrice)
|
|
560
|
+
return compareFcn(bestValue, currentValue, slot, oraclePriceData)
|
|
520
561
|
? bestGenerator
|
|
521
562
|
: currentGenerator;
|
|
522
563
|
});
|
|
@@ -534,58 +575,59 @@ class DLOB {
|
|
|
534
575
|
}
|
|
535
576
|
}
|
|
536
577
|
}
|
|
537
|
-
*
|
|
578
|
+
*getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData) {
|
|
538
579
|
if (__1.isVariant(marketType, 'spot') && !oraclePriceData) {
|
|
539
580
|
throw new Error('Must provide OraclePriceData to get spot asks');
|
|
540
581
|
}
|
|
582
|
+
this.updateRestingLimitOrders(slot);
|
|
541
583
|
const marketTypeStr = __1.getVariant(marketType);
|
|
542
584
|
const nodeLists = this.orderLists.get(marketTypeStr).get(marketIndex);
|
|
543
585
|
if (!nodeLists) {
|
|
544
586
|
return;
|
|
545
587
|
}
|
|
546
588
|
const generatorList = [
|
|
547
|
-
nodeLists.
|
|
589
|
+
nodeLists.restingLimit.ask.getGenerator(),
|
|
548
590
|
nodeLists.floatingLimit.ask.getGenerator(),
|
|
549
591
|
];
|
|
550
|
-
yield* this.getBestNode(generatorList, oraclePriceData, slot, (
|
|
551
|
-
return
|
|
592
|
+
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
|
|
593
|
+
return bestNode
|
|
594
|
+
.getPrice(oraclePriceData, slot)
|
|
595
|
+
.lt(currentNode.getPrice(oraclePriceData, slot));
|
|
552
596
|
});
|
|
553
597
|
}
|
|
554
598
|
/**
|
|
555
|
-
* Filters the limit asks that are
|
|
556
|
-
*
|
|
599
|
+
* Filters the limit asks that are resting and do not cross fallback bid
|
|
600
|
+
* Taking orders can only fill against orders that meet this criteria
|
|
557
601
|
*
|
|
558
602
|
* @returns
|
|
559
603
|
*/
|
|
560
604
|
*getMakerLimitAsks(marketIndex, slot, marketType, oraclePriceData, fallbackBid) {
|
|
561
|
-
for (const node of this.
|
|
562
|
-
if (
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
else if (fallbackBid &&
|
|
566
|
-
node.getPrice(oraclePriceData, slot).gt(fallbackBid)) {
|
|
567
|
-
yield node;
|
|
605
|
+
for (const node of this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData)) {
|
|
606
|
+
if (fallbackBid &&
|
|
607
|
+
node.getPrice(oraclePriceData, slot).lte(fallbackBid)) {
|
|
608
|
+
continue;
|
|
568
609
|
}
|
|
610
|
+
yield node;
|
|
569
611
|
}
|
|
570
612
|
}
|
|
571
|
-
|
|
572
|
-
return order.postOnly || new __1.BN(slot).sub(order.slot).gte(new __1.BN(45));
|
|
573
|
-
}
|
|
574
|
-
*getLimitBids(marketIndex, slot, marketType, oraclePriceData) {
|
|
613
|
+
*getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData) {
|
|
575
614
|
if (__1.isVariant(marketType, 'spot') && !oraclePriceData) {
|
|
576
615
|
throw new Error('Must provide OraclePriceData to get spot bids');
|
|
577
616
|
}
|
|
617
|
+
this.updateRestingLimitOrders(slot);
|
|
578
618
|
const marketTypeStr = __1.getVariant(marketType);
|
|
579
619
|
const nodeLists = this.orderLists.get(marketTypeStr).get(marketIndex);
|
|
580
620
|
if (!nodeLists) {
|
|
581
621
|
return;
|
|
582
622
|
}
|
|
583
623
|
const generatorList = [
|
|
584
|
-
nodeLists.
|
|
624
|
+
nodeLists.restingLimit.bid.getGenerator(),
|
|
585
625
|
nodeLists.floatingLimit.bid.getGenerator(),
|
|
586
626
|
];
|
|
587
|
-
yield* this.getBestNode(generatorList, oraclePriceData, slot, (
|
|
588
|
-
return
|
|
627
|
+
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
|
|
628
|
+
return bestNode
|
|
629
|
+
.getPrice(oraclePriceData, slot)
|
|
630
|
+
.gt(currentNode.getPrice(oraclePriceData, slot));
|
|
589
631
|
});
|
|
590
632
|
}
|
|
591
633
|
/**
|
|
@@ -595,14 +637,12 @@ class DLOB {
|
|
|
595
637
|
* @returns
|
|
596
638
|
*/
|
|
597
639
|
*getMakerLimitBids(marketIndex, slot, marketType, oraclePriceData, fallbackAsk) {
|
|
598
|
-
for (const node of this.
|
|
599
|
-
if (
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
else if (fallbackAsk &&
|
|
603
|
-
node.getPrice(oraclePriceData, slot).lt(fallbackAsk)) {
|
|
604
|
-
yield node;
|
|
640
|
+
for (const node of this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData)) {
|
|
641
|
+
if (fallbackAsk &&
|
|
642
|
+
node.getPrice(oraclePriceData, slot).gte(fallbackAsk)) {
|
|
643
|
+
continue;
|
|
605
644
|
}
|
|
645
|
+
yield node;
|
|
606
646
|
}
|
|
607
647
|
}
|
|
608
648
|
*getAsks(marketIndex, fallbackAsk, slot, marketType, oraclePriceData) {
|
|
@@ -610,15 +650,32 @@ class DLOB {
|
|
|
610
650
|
throw new Error('Must provide OraclePriceData to get spot asks');
|
|
611
651
|
}
|
|
612
652
|
const generatorList = [
|
|
613
|
-
this.
|
|
614
|
-
this.
|
|
653
|
+
this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData),
|
|
654
|
+
this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData),
|
|
615
655
|
];
|
|
616
656
|
const marketTypeStr = __1.getVariant(marketType);
|
|
617
657
|
if (marketTypeStr === 'perp' && fallbackAsk) {
|
|
618
658
|
generatorList.push(NodeList_1.getVammNodeGenerator(fallbackAsk));
|
|
619
659
|
}
|
|
620
|
-
yield* this.getBestNode(generatorList, oraclePriceData, slot, (
|
|
621
|
-
|
|
660
|
+
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
|
|
661
|
+
const bestNodeTaking = bestNode.order
|
|
662
|
+
? __1.isTakingOrder(bestNode.order, slot)
|
|
663
|
+
: false;
|
|
664
|
+
const currentNodeTaking = currentNode.order
|
|
665
|
+
? __1.isTakingOrder(currentNode.order, slot)
|
|
666
|
+
: false;
|
|
667
|
+
if (bestNodeTaking && currentNodeTaking) {
|
|
668
|
+
return bestNode.order.slot.lt(currentNode.order.slot);
|
|
669
|
+
}
|
|
670
|
+
if (bestNodeTaking) {
|
|
671
|
+
return true;
|
|
672
|
+
}
|
|
673
|
+
if (currentNodeTaking) {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
return bestNode
|
|
677
|
+
.getPrice(oraclePriceData, slot)
|
|
678
|
+
.lt(currentNode.getPrice(oraclePriceData, slot));
|
|
622
679
|
});
|
|
623
680
|
}
|
|
624
681
|
*getBids(marketIndex, fallbackBid, slot, marketType, oraclePriceData) {
|
|
@@ -626,37 +683,60 @@ class DLOB {
|
|
|
626
683
|
throw new Error('Must provide OraclePriceData to get spot bids');
|
|
627
684
|
}
|
|
628
685
|
const generatorList = [
|
|
629
|
-
this.
|
|
630
|
-
this.
|
|
686
|
+
this.getTakingBids(marketIndex, marketType, slot, oraclePriceData),
|
|
687
|
+
this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData),
|
|
631
688
|
];
|
|
632
689
|
const marketTypeStr = __1.getVariant(marketType);
|
|
633
690
|
if (marketTypeStr === 'perp' && fallbackBid) {
|
|
634
691
|
generatorList.push(NodeList_1.getVammNodeGenerator(fallbackBid));
|
|
635
692
|
}
|
|
636
|
-
yield* this.getBestNode(generatorList, oraclePriceData, slot, (
|
|
637
|
-
|
|
693
|
+
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
|
|
694
|
+
const bestNodeTaking = bestNode.order
|
|
695
|
+
? __1.isTakingOrder(bestNode.order, slot)
|
|
696
|
+
: false;
|
|
697
|
+
const currentNodeTaking = currentNode.order
|
|
698
|
+
? __1.isTakingOrder(currentNode.order, slot)
|
|
699
|
+
: false;
|
|
700
|
+
if (bestNodeTaking && currentNodeTaking) {
|
|
701
|
+
return bestNode.order.slot.lt(currentNode.order.slot);
|
|
702
|
+
}
|
|
703
|
+
if (bestNodeTaking) {
|
|
704
|
+
return true;
|
|
705
|
+
}
|
|
706
|
+
if (currentNodeTaking) {
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
return bestNode
|
|
710
|
+
.getPrice(oraclePriceData, slot)
|
|
711
|
+
.gt(currentNode.getPrice(oraclePriceData, slot));
|
|
638
712
|
});
|
|
639
713
|
}
|
|
640
|
-
|
|
714
|
+
findCrossingRestingLimitOrders(marketIndex, slot, marketType, oraclePriceData, minAuctionDuration, fallbackAsk, fallbackBid) {
|
|
641
715
|
const nodesToFill = new Array();
|
|
642
|
-
for (const askNode of this.
|
|
643
|
-
|
|
716
|
+
for (const askNode of this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData)) {
|
|
717
|
+
const bidGenerator = this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData);
|
|
718
|
+
for (const bidNode of bidGenerator) {
|
|
644
719
|
const bidPrice = bidNode.getPrice(oraclePriceData, slot);
|
|
645
720
|
const askPrice = askNode.getPrice(oraclePriceData, slot);
|
|
646
|
-
// orders don't cross
|
|
721
|
+
// orders don't cross
|
|
647
722
|
if (bidPrice.lt(askPrice)) {
|
|
648
|
-
|
|
723
|
+
break;
|
|
649
724
|
}
|
|
650
725
|
const bidOrder = bidNode.order;
|
|
651
726
|
const askOrder = askNode.order;
|
|
652
727
|
// Can't match orders from the same user
|
|
653
728
|
const sameUser = bidNode.userAccount.equals(askNode.userAccount);
|
|
654
|
-
if (sameUser
|
|
729
|
+
if (sameUser) {
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
const makerAndTaker = this.determineMakerAndTaker(askNode, bidNode);
|
|
733
|
+
// unable to match maker and taker due to post only or slot
|
|
734
|
+
if (!makerAndTaker) {
|
|
655
735
|
continue;
|
|
656
736
|
}
|
|
657
|
-
const { takerNode, makerNode } =
|
|
737
|
+
const { takerNode, makerNode } = makerAndTaker;
|
|
658
738
|
// extra guard against bad fills for limit orders where auction is incomplete
|
|
659
|
-
if (!__1.
|
|
739
|
+
if (!__1.isFallbackAvailableLiquiditySource(takerNode.order, minAuctionDuration, slot)) {
|
|
660
740
|
let bidPrice;
|
|
661
741
|
let askPrice;
|
|
662
742
|
if (__1.isVariant(takerNode.order.direction, 'long')) {
|
|
@@ -677,12 +757,12 @@ class DLOB {
|
|
|
677
757
|
const newBidOrder = { ...bidOrder };
|
|
678
758
|
newBidOrder.baseAssetAmountFilled =
|
|
679
759
|
bidOrder.baseAssetAmountFilled.add(baseFilled);
|
|
680
|
-
this.getListForOrder(newBidOrder).update(newBidOrder, bidNode.userAccount);
|
|
760
|
+
this.getListForOrder(newBidOrder, slot).update(newBidOrder, bidNode.userAccount);
|
|
681
761
|
// ask completely filled
|
|
682
762
|
const newAskOrder = { ...askOrder };
|
|
683
763
|
newAskOrder.baseAssetAmountFilled =
|
|
684
764
|
askOrder.baseAssetAmountFilled.add(baseFilled);
|
|
685
|
-
this.getListForOrder(newAskOrder).update(newAskOrder, askNode.userAccount);
|
|
765
|
+
this.getListForOrder(newAskOrder, slot).update(newAskOrder, askNode.userAccount);
|
|
686
766
|
nodesToFill.push({
|
|
687
767
|
node: takerNode,
|
|
688
768
|
makerNode: makerNode,
|
|
@@ -695,30 +775,23 @@ class DLOB {
|
|
|
695
775
|
return nodesToFill;
|
|
696
776
|
}
|
|
697
777
|
determineMakerAndTaker(askNode, bidNode) {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
makerNode: bidNode,
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
else if (askNode.order.postOnly) {
|
|
778
|
+
const askSlot = askNode.order.slot.add(new __1.BN(askNode.order.auctionDuration));
|
|
779
|
+
const bidSlot = bidNode.order.slot.add(new __1.BN(bidNode.order.auctionDuration));
|
|
780
|
+
if (askSlot.lte(bidSlot) && !bidNode.order.postOnly) {
|
|
705
781
|
return {
|
|
706
782
|
takerNode: bidNode,
|
|
707
783
|
makerNode: askNode,
|
|
708
784
|
};
|
|
709
785
|
}
|
|
710
|
-
else if (
|
|
711
|
-
return {
|
|
712
|
-
takerNode: bidNode,
|
|
713
|
-
makerNode: askNode,
|
|
714
|
-
};
|
|
715
|
-
}
|
|
716
|
-
else {
|
|
786
|
+
else if (bidSlot.lte(askSlot) && !askNode.order.postOnly) {
|
|
717
787
|
return {
|
|
718
788
|
takerNode: askNode,
|
|
719
789
|
makerNode: bidNode,
|
|
720
790
|
};
|
|
721
791
|
}
|
|
792
|
+
else {
|
|
793
|
+
return undefined;
|
|
794
|
+
}
|
|
722
795
|
}
|
|
723
796
|
getBestAsk(marketIndex, fallbackAsk, slot, marketType, oraclePriceData) {
|
|
724
797
|
return this.getAsks(marketIndex, fallbackAsk, slot, marketType, oraclePriceData)
|
|
@@ -743,11 +816,9 @@ class DLOB {
|
|
|
743
816
|
if (triggerAboveList) {
|
|
744
817
|
for (const node of triggerAboveList.getGenerator()) {
|
|
745
818
|
if (oraclePrice.gt(node.order.triggerPrice)) {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
});
|
|
750
|
-
}
|
|
819
|
+
nodesToTrigger.push({
|
|
820
|
+
node: node,
|
|
821
|
+
});
|
|
751
822
|
}
|
|
752
823
|
else {
|
|
753
824
|
break;
|
|
@@ -760,11 +831,9 @@ class DLOB {
|
|
|
760
831
|
if (triggerBelowList) {
|
|
761
832
|
for (const node of triggerBelowList.getGenerator()) {
|
|
762
833
|
if (oraclePrice.lt(node.order.triggerPrice)) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
});
|
|
767
|
-
}
|
|
834
|
+
nodesToTrigger.push({
|
|
835
|
+
node: node,
|
|
836
|
+
});
|
|
768
837
|
}
|
|
769
838
|
else {
|
|
770
839
|
break;
|
|
@@ -830,8 +899,10 @@ class DLOB {
|
|
|
830
899
|
}
|
|
831
900
|
*getNodeLists() {
|
|
832
901
|
for (const [_, nodeLists] of this.orderLists.get('perp')) {
|
|
833
|
-
yield nodeLists.
|
|
834
|
-
yield nodeLists.
|
|
902
|
+
yield nodeLists.restingLimit.bid;
|
|
903
|
+
yield nodeLists.restingLimit.ask;
|
|
904
|
+
yield nodeLists.takingLimit.bid;
|
|
905
|
+
yield nodeLists.takingLimit.ask;
|
|
835
906
|
yield nodeLists.market.bid;
|
|
836
907
|
yield nodeLists.market.ask;
|
|
837
908
|
yield nodeLists.floatingLimit.bid;
|
|
@@ -840,8 +911,10 @@ class DLOB {
|
|
|
840
911
|
yield nodeLists.trigger.below;
|
|
841
912
|
}
|
|
842
913
|
for (const [_, nodeLists] of this.orderLists.get('spot')) {
|
|
843
|
-
yield nodeLists.
|
|
844
|
-
yield nodeLists.
|
|
914
|
+
yield nodeLists.restingLimit.bid;
|
|
915
|
+
yield nodeLists.restingLimit.ask;
|
|
916
|
+
yield nodeLists.takingLimit.bid;
|
|
917
|
+
yield nodeLists.takingLimit.ask;
|
|
845
918
|
yield nodeLists.market.bid;
|
|
846
919
|
yield nodeLists.market.ask;
|
|
847
920
|
yield nodeLists.floatingLimit.bid;
|