@drift-labs/sdk 0.2.0-master.30 → 0.2.0-master.32
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/admin.d.ts +11 -7
- package/lib/admin.js +50 -12
- package/lib/clearingHouse.d.ts +26 -23
- package/lib/clearingHouse.js +290 -652
- package/lib/clearingHouseUser.d.ts +1 -1
- package/lib/clearingHouseUser.js +9 -12
- package/lib/config.js +1 -1
- package/lib/constants/numericConstants.d.ts +7 -0
- package/lib/constants/numericConstants.js +8 -1
- package/lib/constants/spotMarkets.js +4 -4
- package/lib/dlob/DLOB.d.ts +7 -5
- package/lib/dlob/DLOB.js +159 -88
- package/lib/dlob/DLOBNode.d.ts +2 -0
- package/lib/dlob/DLOBNode.js +3 -0
- package/lib/dlob/NodeList.d.ts +2 -1
- package/lib/dlob/NodeList.js +10 -4
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +14 -0
- package/lib/idl/clearing_house.json +1091 -611
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +31 -28
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +6 -6
- package/lib/math/spotBalance.js +7 -8
- package/lib/math/trade.js +11 -11
- package/lib/types.d.ts +118 -41
- package/lib/types.js +34 -4
- package/package.json +4 -2
- package/src/admin.ts +129 -29
- package/src/clearingHouse.ts +380 -787
- package/src/clearingHouseUser.ts +11 -14
- package/src/config.ts +1 -1
- package/src/constants/numericConstants.ts +7 -0
- package/src/constants/spotMarkets.ts +5 -4
- package/src/dlob/DLOB.ts +221 -103
- package/src/dlob/DLOBNode.ts +5 -0
- package/src/dlob/NodeList.ts +15 -5
- package/src/events/types.ts +3 -0
- package/src/factory/bigNum.ts +23 -0
- package/src/idl/clearing_house.json +1091 -611
- package/src/math/amm.ts +42 -29
- package/src/math/market.ts +9 -4
- package/src/math/spotBalance.ts +11 -8
- package/src/math/trade.ts +11 -11
- package/src/types.ts +82 -41
- package/tests/bn/test.ts +13 -8
- package/tests/dlob/helpers.ts +56 -33
- package/tests/dlob/test.ts +1397 -495
- package/src/assert/assert.js +0 -9
- package/src/events/eventList.js +0 -77
- package/src/examples/makeTradeExample.js +0 -157
- package/src/token/index.js +0 -38
- package/src/tx/types.js +0 -2
- package/src/tx/utils.js +0 -17
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
package/tests/dlob/test.ts
CHANGED
|
@@ -11,6 +11,11 @@ import {
|
|
|
11
11
|
OrderStatus,
|
|
12
12
|
OrderType,
|
|
13
13
|
OrderTriggerCondition,
|
|
14
|
+
PRICE_PRECISION,
|
|
15
|
+
DLOBNode,
|
|
16
|
+
OraclePriceData,
|
|
17
|
+
NodeToFill,
|
|
18
|
+
isOrderExpired,
|
|
14
19
|
} from '../../src';
|
|
15
20
|
|
|
16
21
|
import { mockPerpMarkets, mockSpotMarkets } from './helpers';
|
|
@@ -20,15 +25,16 @@ function insertOrderToDLOB(
|
|
|
20
25
|
userAccount: PublicKey,
|
|
21
26
|
orderType: OrderType,
|
|
22
27
|
marketType: MarketType,
|
|
23
|
-
orderId:
|
|
24
|
-
marketIndex:
|
|
28
|
+
orderId: number,
|
|
29
|
+
marketIndex: number,
|
|
25
30
|
price: BN,
|
|
26
31
|
baseAssetAmount: BN,
|
|
27
32
|
direction: PositionDirection,
|
|
28
33
|
auctionStartPrice: BN,
|
|
29
34
|
auctionEndPrice: BN,
|
|
30
35
|
slot?: BN,
|
|
31
|
-
timeInForce = 30
|
|
36
|
+
timeInForce = 30,
|
|
37
|
+
oraclePriceOffset = new BN(0)
|
|
32
38
|
) {
|
|
33
39
|
dlob.insertOrder(
|
|
34
40
|
{
|
|
@@ -54,7 +60,7 @@ function insertOrderToDLOB(
|
|
|
54
60
|
existingPositionDirection: PositionDirection.LONG,
|
|
55
61
|
postOnly: false,
|
|
56
62
|
immediateOrCancel: true,
|
|
57
|
-
oraclePriceOffset
|
|
63
|
+
oraclePriceOffset,
|
|
58
64
|
auctionDuration: 10,
|
|
59
65
|
auctionStartPrice,
|
|
60
66
|
auctionEndPrice,
|
|
@@ -69,8 +75,8 @@ function insertTriggerOrderToDLOB(
|
|
|
69
75
|
userAccount: PublicKey,
|
|
70
76
|
orderType: OrderType,
|
|
71
77
|
marketType: MarketType,
|
|
72
|
-
orderId:
|
|
73
|
-
marketIndex:
|
|
78
|
+
orderId: number,
|
|
79
|
+
marketIndex: number,
|
|
74
80
|
price: BN,
|
|
75
81
|
baseAssetAmount: BN,
|
|
76
82
|
direction: PositionDirection,
|
|
@@ -79,7 +85,8 @@ function insertTriggerOrderToDLOB(
|
|
|
79
85
|
auctionStartPrice: BN,
|
|
80
86
|
auctionEndPrice: BN,
|
|
81
87
|
slot?: BN,
|
|
82
|
-
timeInForce = 30
|
|
88
|
+
timeInForce = 30,
|
|
89
|
+
oraclePriceOffset = new BN(0)
|
|
83
90
|
) {
|
|
84
91
|
dlob.insertOrder(
|
|
85
92
|
{
|
|
@@ -105,7 +112,7 @@ function insertTriggerOrderToDLOB(
|
|
|
105
112
|
existingPositionDirection: PositionDirection.LONG,
|
|
106
113
|
postOnly: false,
|
|
107
114
|
immediateOrCancel: true,
|
|
108
|
-
oraclePriceOffset
|
|
115
|
+
oraclePriceOffset,
|
|
109
116
|
auctionDuration: 10,
|
|
110
117
|
auctionStartPrice,
|
|
111
118
|
auctionEndPrice,
|
|
@@ -115,6 +122,98 @@ function insertTriggerOrderToDLOB(
|
|
|
115
122
|
);
|
|
116
123
|
}
|
|
117
124
|
|
|
125
|
+
function printOrderNode(
|
|
126
|
+
node: DLOBNode,
|
|
127
|
+
oracle: OraclePriceData | undefined,
|
|
128
|
+
slot: number | undefined
|
|
129
|
+
) {
|
|
130
|
+
console.log(
|
|
131
|
+
` . vAMMNode? ${node.isVammNode()},\t${
|
|
132
|
+
node.order ? getVariant(node.order?.orderType) : '~'
|
|
133
|
+
} ${node.order ? getVariant(node.order?.direction) : '~'}\t, ts: ${
|
|
134
|
+
node.order?.ts.toString() || '~'
|
|
135
|
+
}, orderId: ${node.order?.orderId.toString() || '~'},\tnode.getPrice: ${
|
|
136
|
+
oracle ? node.getPrice(oracle, slot!) : '~'
|
|
137
|
+
}, node.price: ${node.order?.price.toString() || '~'}, priceOffset: ${
|
|
138
|
+
node.order?.oraclePriceOffset.toString() || '~'
|
|
139
|
+
} quantity: ${node.order?.baseAssetAmountFilled.toString() || '~'}/${
|
|
140
|
+
node.order?.baseAssetAmount.toString() || '~'
|
|
141
|
+
}`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function printBookState(
|
|
146
|
+
dlob: DLOB,
|
|
147
|
+
marketIndex: number,
|
|
148
|
+
vBid: BN | undefined,
|
|
149
|
+
vAsk: BN | undefined,
|
|
150
|
+
slot: number,
|
|
151
|
+
oracle: OraclePriceData
|
|
152
|
+
) {
|
|
153
|
+
const askNodes = dlob.getAsks(
|
|
154
|
+
marketIndex,
|
|
155
|
+
vAsk,
|
|
156
|
+
slot,
|
|
157
|
+
MarketType.PERP,
|
|
158
|
+
oracle
|
|
159
|
+
);
|
|
160
|
+
let aa = 0;
|
|
161
|
+
console.log(`Oracle price: ${oracle.price.toNumber()}`);
|
|
162
|
+
console.log(`asks:`);
|
|
163
|
+
for (const a of askNodes) {
|
|
164
|
+
printOrderNode(a, oracle, slot);
|
|
165
|
+
aa++;
|
|
166
|
+
}
|
|
167
|
+
console.log(`Total ask nodes: ${aa}`);
|
|
168
|
+
|
|
169
|
+
const bidNodes = dlob.getBids(
|
|
170
|
+
marketIndex,
|
|
171
|
+
vBid,
|
|
172
|
+
slot,
|
|
173
|
+
MarketType.PERP,
|
|
174
|
+
oracle
|
|
175
|
+
);
|
|
176
|
+
let bb = 0;
|
|
177
|
+
console.log(`bids:`);
|
|
178
|
+
for (const b of bidNodes) {
|
|
179
|
+
printOrderNode(b, oracle, slot);
|
|
180
|
+
bb++;
|
|
181
|
+
}
|
|
182
|
+
console.log(`Total bid nodes: ${bb}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function printCrossedNodes(n: NodeToFill, slot: number) {
|
|
186
|
+
console.log(
|
|
187
|
+
`Cross Found, taker: ${n.node.order !== undefined}, maker: ${
|
|
188
|
+
n.makerNode !== undefined
|
|
189
|
+
}`
|
|
190
|
+
);
|
|
191
|
+
if (n.node.order) {
|
|
192
|
+
const t = n.node.order;
|
|
193
|
+
const exp = isOrderExpired(t, slot);
|
|
194
|
+
console.log(
|
|
195
|
+
` taker orderId: ${t.orderId}, ${getVariant(t.orderType)}, ${getVariant(
|
|
196
|
+
t.direction
|
|
197
|
+
)},\texpired: ${exp}, price: ${t.price.toString()}, priceOffset: ${t.oraclePriceOffset.toString()}, baseAmtFileld: ${t.baseAssetAmountFilled.toString()}/${t.baseAssetAmount.toString()}`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (n.makerNode) {
|
|
201
|
+
if (n.makerNode.isVammNode()) {
|
|
202
|
+
console.log(` maker is vAMM node`);
|
|
203
|
+
} else {
|
|
204
|
+
const m = n.makerNode.order!;
|
|
205
|
+
const exp = isOrderExpired(m, slot);
|
|
206
|
+
console.log(
|
|
207
|
+
` maker orderId: ${m.orderId}, ${getVariant(
|
|
208
|
+
m.orderType
|
|
209
|
+
)}, ${getVariant(
|
|
210
|
+
m.direction
|
|
211
|
+
)},\texpired: ${exp}, price: ${m.price.toString()}, priceOffset: ${m.oraclePriceOffset.toString()}, baseAmtFileld: ${m.baseAssetAmountFilled.toString()}/${m.baseAssetAmount.toString()}`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
118
217
|
let mockTs = 1;
|
|
119
218
|
function getMockTimestamp(): number {
|
|
120
219
|
return mockTs++;
|
|
@@ -185,6 +284,85 @@ describe('DLOB Tests', () => {
|
|
|
185
284
|
expect(foundBids).to.equal(0);
|
|
186
285
|
}
|
|
187
286
|
});
|
|
287
|
+
|
|
288
|
+
it('Can clear DLOB', () => {
|
|
289
|
+
const vAsk = new BN(15);
|
|
290
|
+
const vBid = new BN(10);
|
|
291
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
292
|
+
const marketIndex = 0;
|
|
293
|
+
|
|
294
|
+
const slot = 12;
|
|
295
|
+
const oracle = {
|
|
296
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
297
|
+
slot: new BN(slot),
|
|
298
|
+
confidence: new BN(1),
|
|
299
|
+
hasSufficientNumberOfDataPoints: true,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
insertOrderToDLOB(
|
|
303
|
+
dlob,
|
|
304
|
+
Keypair.generate().publicKey,
|
|
305
|
+
OrderType.LIMIT,
|
|
306
|
+
MarketType.PERP,
|
|
307
|
+
0, // orderId
|
|
308
|
+
marketIndex,
|
|
309
|
+
new BN(9), // price
|
|
310
|
+
BASE_PRECISION, // quantity
|
|
311
|
+
PositionDirection.LONG,
|
|
312
|
+
vBid,
|
|
313
|
+
vAsk
|
|
314
|
+
);
|
|
315
|
+
insertOrderToDLOB(
|
|
316
|
+
dlob,
|
|
317
|
+
Keypair.generate().publicKey,
|
|
318
|
+
OrderType.LIMIT,
|
|
319
|
+
MarketType.PERP,
|
|
320
|
+
1, // orderId
|
|
321
|
+
marketIndex,
|
|
322
|
+
new BN(8), // price
|
|
323
|
+
BASE_PRECISION, // quantity
|
|
324
|
+
PositionDirection.LONG,
|
|
325
|
+
vBid,
|
|
326
|
+
vAsk
|
|
327
|
+
);
|
|
328
|
+
insertOrderToDLOB(
|
|
329
|
+
dlob,
|
|
330
|
+
Keypair.generate().publicKey,
|
|
331
|
+
OrderType.LIMIT,
|
|
332
|
+
MarketType.PERP,
|
|
333
|
+
2, // orderId
|
|
334
|
+
marketIndex,
|
|
335
|
+
new BN(8), // price
|
|
336
|
+
BASE_PRECISION, // quantity
|
|
337
|
+
PositionDirection.LONG,
|
|
338
|
+
vBid,
|
|
339
|
+
vAsk
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const bids = dlob.getBids(
|
|
343
|
+
marketIndex,
|
|
344
|
+
undefined,
|
|
345
|
+
0,
|
|
346
|
+
MarketType.PERP,
|
|
347
|
+
oracle
|
|
348
|
+
);
|
|
349
|
+
let b = 0;
|
|
350
|
+
for (const _bid of bids) {
|
|
351
|
+
b++;
|
|
352
|
+
}
|
|
353
|
+
expect(b).to.equal(3);
|
|
354
|
+
|
|
355
|
+
dlob.clear();
|
|
356
|
+
let thrown = false;
|
|
357
|
+
try {
|
|
358
|
+
const bids1 = dlob.getBids(marketIndex, vBid, 0, MarketType.PERP, oracle);
|
|
359
|
+
bids1.next();
|
|
360
|
+
} catch (e) {
|
|
361
|
+
console.error(e);
|
|
362
|
+
thrown = true;
|
|
363
|
+
}
|
|
364
|
+
expect(thrown, 'should throw after clearing').to.equal(true);
|
|
365
|
+
});
|
|
188
366
|
});
|
|
189
367
|
|
|
190
368
|
describe('DLOB Perp Tests', () => {
|
|
@@ -192,7 +370,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
192
370
|
const vAsk = new BN(15);
|
|
193
371
|
const vBid = new BN(10);
|
|
194
372
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
195
|
-
const marketIndex =
|
|
373
|
+
const marketIndex = 0;
|
|
196
374
|
|
|
197
375
|
const slot = 12;
|
|
198
376
|
const oracle = {
|
|
@@ -203,41 +381,41 @@ describe('DLOB Perp Tests', () => {
|
|
|
203
381
|
};
|
|
204
382
|
const testCases = [
|
|
205
383
|
{
|
|
206
|
-
expectedIdx:
|
|
384
|
+
expectedIdx: 0,
|
|
207
385
|
isVamm: false,
|
|
208
|
-
orderId:
|
|
386
|
+
orderId: 5,
|
|
209
387
|
price: new BN(0),
|
|
210
388
|
direction: PositionDirection.LONG,
|
|
211
389
|
orderType: OrderType.MARKET,
|
|
212
390
|
},
|
|
213
391
|
{
|
|
214
|
-
expectedIdx:
|
|
392
|
+
expectedIdx: 1,
|
|
215
393
|
isVamm: false,
|
|
216
|
-
orderId:
|
|
394
|
+
orderId: 6,
|
|
217
395
|
price: new BN(0),
|
|
218
396
|
direction: PositionDirection.LONG,
|
|
219
397
|
orderType: OrderType.MARKET,
|
|
220
398
|
},
|
|
221
399
|
{
|
|
222
|
-
expectedIdx:
|
|
400
|
+
expectedIdx: 2,
|
|
223
401
|
isVamm: false,
|
|
224
|
-
orderId:
|
|
402
|
+
orderId: 7,
|
|
225
403
|
price: new BN(0),
|
|
226
404
|
direction: PositionDirection.LONG,
|
|
227
405
|
orderType: OrderType.MARKET,
|
|
228
406
|
},
|
|
229
407
|
{
|
|
230
|
-
expectedIdx:
|
|
408
|
+
expectedIdx: 3,
|
|
231
409
|
isVamm: false,
|
|
232
|
-
orderId:
|
|
410
|
+
orderId: 1,
|
|
233
411
|
price: new BN(12),
|
|
234
412
|
direction: PositionDirection.LONG,
|
|
235
413
|
orderType: OrderType.LIMIT,
|
|
236
414
|
},
|
|
237
415
|
{
|
|
238
|
-
expectedIdx:
|
|
416
|
+
expectedIdx: 4,
|
|
239
417
|
isVamm: false,
|
|
240
|
-
orderId:
|
|
418
|
+
orderId: 2,
|
|
241
419
|
price: new BN(11),
|
|
242
420
|
direction: PositionDirection.LONG,
|
|
243
421
|
orderType: OrderType.LIMIT,
|
|
@@ -245,13 +423,13 @@ describe('DLOB Perp Tests', () => {
|
|
|
245
423
|
{
|
|
246
424
|
expectedIdx: 7,
|
|
247
425
|
isVamm: false,
|
|
248
|
-
orderId:
|
|
426
|
+
orderId: 3,
|
|
249
427
|
price: new BN(8),
|
|
250
428
|
direction: PositionDirection.LONG,
|
|
251
429
|
orderType: OrderType.LIMIT,
|
|
252
430
|
},
|
|
253
431
|
{
|
|
254
|
-
expectedIdx:
|
|
432
|
+
expectedIdx: 5,
|
|
255
433
|
isVamm: true,
|
|
256
434
|
orderId: undefined,
|
|
257
435
|
price: undefined,
|
|
@@ -261,7 +439,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
261
439
|
{
|
|
262
440
|
expectedIdx: 6,
|
|
263
441
|
isVamm: false,
|
|
264
|
-
orderId:
|
|
442
|
+
orderId: 4,
|
|
265
443
|
price: new BN(9),
|
|
266
444
|
direction: PositionDirection.LONG,
|
|
267
445
|
orderType: OrderType.LIMIT,
|
|
@@ -277,7 +455,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
277
455
|
Keypair.generate().publicKey,
|
|
278
456
|
t.orderType || OrderType.LIMIT,
|
|
279
457
|
MarketType.PERP,
|
|
280
|
-
t.orderId ||
|
|
458
|
+
t.orderId || 0, // orderId
|
|
281
459
|
marketIndex,
|
|
282
460
|
t.price || new BN(0), // price
|
|
283
461
|
BASE_PRECISION, // quantity
|
|
@@ -294,28 +472,26 @@ describe('DLOB Perp Tests', () => {
|
|
|
294
472
|
const bids = dlob.getBids(marketIndex, vBid, slot, MarketType.PERP, oracle);
|
|
295
473
|
|
|
296
474
|
console.log('The Book Bids:');
|
|
475
|
+
const gotBids: Array<DLOBNode> = [];
|
|
297
476
|
let countBids = 0;
|
|
298
477
|
for (const bid of bids) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
)}, price: ${bid.order?.price.toString()}, quantity: ${bid.order?.baseAssetAmountFilled.toString()}/${bid.order?.baseAssetAmount.toString()}`
|
|
478
|
+
gotBids.push(bid);
|
|
479
|
+
printOrderNode(bid, oracle, slot);
|
|
480
|
+
}
|
|
481
|
+
for (const bid of gotBids) {
|
|
482
|
+
expect(bid.isVammNode(), `expected vAMM node`).to.be.eq(
|
|
483
|
+
expectedTestCase[countBids].isVamm
|
|
306
484
|
);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
expect(bid.order?.orderId.toNumber()).to.equal(
|
|
310
|
-
expectedTestCase[countBids].orderId?.toNumber()
|
|
485
|
+
expect(bid.order?.orderId, `expected orderId`).to.equal(
|
|
486
|
+
expectedTestCase[countBids].orderId
|
|
311
487
|
);
|
|
312
|
-
expect(bid.order?.price.toNumber()).to.equal(
|
|
488
|
+
expect(bid.order?.price.toNumber(), `expected price`).to.equal(
|
|
313
489
|
expectedTestCase[countBids].price?.toNumber()
|
|
314
490
|
);
|
|
315
|
-
expect(bid.order?.direction).to.equal(
|
|
491
|
+
expect(bid.order?.direction, `expected order direction`).to.equal(
|
|
316
492
|
expectedTestCase[countBids].direction
|
|
317
493
|
);
|
|
318
|
-
expect(bid.order?.orderType).to.equal(
|
|
494
|
+
expect(bid.order?.orderType, `expected order type`).to.equal(
|
|
319
495
|
expectedTestCase[countBids].orderType
|
|
320
496
|
);
|
|
321
497
|
countBids++;
|
|
@@ -328,8 +504,8 @@ describe('DLOB Perp Tests', () => {
|
|
|
328
504
|
const vAsk = new BN(15);
|
|
329
505
|
const vBid = new BN(10);
|
|
330
506
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
331
|
-
const marketIndex0 =
|
|
332
|
-
const marketIndex1 =
|
|
507
|
+
const marketIndex0 = 0;
|
|
508
|
+
const marketIndex1 = 1;
|
|
333
509
|
|
|
334
510
|
const slot = 12;
|
|
335
511
|
const oracle = {
|
|
@@ -342,7 +518,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
342
518
|
{
|
|
343
519
|
expectedIdx: 3,
|
|
344
520
|
isVamm: false,
|
|
345
|
-
orderId:
|
|
521
|
+
orderId: 5,
|
|
346
522
|
price: new BN(0),
|
|
347
523
|
direction: PositionDirection.LONG,
|
|
348
524
|
orderType: OrderType.MARKET,
|
|
@@ -351,7 +527,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
351
527
|
{
|
|
352
528
|
expectedIdx: 4,
|
|
353
529
|
isVamm: false,
|
|
354
|
-
orderId:
|
|
530
|
+
orderId: 6,
|
|
355
531
|
price: new BN(0),
|
|
356
532
|
direction: PositionDirection.LONG,
|
|
357
533
|
orderType: OrderType.MARKET,
|
|
@@ -360,7 +536,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
360
536
|
{
|
|
361
537
|
expectedIdx: 5,
|
|
362
538
|
isVamm: false,
|
|
363
|
-
orderId:
|
|
539
|
+
orderId: 7,
|
|
364
540
|
price: new BN(0),
|
|
365
541
|
direction: PositionDirection.LONG,
|
|
366
542
|
orderType: OrderType.MARKET,
|
|
@@ -369,7 +545,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
369
545
|
{
|
|
370
546
|
expectedIdx: 0,
|
|
371
547
|
isVamm: false,
|
|
372
|
-
orderId:
|
|
548
|
+
orderId: 1,
|
|
373
549
|
price: new BN(12),
|
|
374
550
|
direction: PositionDirection.LONG,
|
|
375
551
|
orderType: OrderType.LIMIT,
|
|
@@ -378,7 +554,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
378
554
|
{
|
|
379
555
|
expectedIdx: 1,
|
|
380
556
|
isVamm: false,
|
|
381
|
-
orderId:
|
|
557
|
+
orderId: 2,
|
|
382
558
|
price: new BN(11),
|
|
383
559
|
direction: PositionDirection.LONG,
|
|
384
560
|
orderType: OrderType.LIMIT,
|
|
@@ -387,7 +563,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
387
563
|
{
|
|
388
564
|
expectedIdx: 7,
|
|
389
565
|
isVamm: false,
|
|
390
|
-
orderId:
|
|
566
|
+
orderId: 3,
|
|
391
567
|
price: new BN(8),
|
|
392
568
|
direction: PositionDirection.LONG,
|
|
393
569
|
orderType: OrderType.LIMIT,
|
|
@@ -396,7 +572,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
396
572
|
{
|
|
397
573
|
expectedIdx: 6,
|
|
398
574
|
isVamm: false,
|
|
399
|
-
orderId:
|
|
575
|
+
orderId: 4,
|
|
400
576
|
price: new BN(9),
|
|
401
577
|
direction: PositionDirection.LONG,
|
|
402
578
|
orderType: OrderType.LIMIT,
|
|
@@ -413,7 +589,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
413
589
|
Keypair.generate().publicKey,
|
|
414
590
|
t.orderType || OrderType.LIMIT,
|
|
415
591
|
MarketType.PERP,
|
|
416
|
-
t.orderId ||
|
|
592
|
+
t.orderId || 0, // orderId
|
|
417
593
|
t.marketIndex,
|
|
418
594
|
t.price || new BN(0), // price
|
|
419
595
|
BASE_PRECISION, // quantity
|
|
@@ -471,7 +647,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
471
647
|
const vAsk = new BN(15);
|
|
472
648
|
const vBid = new BN(10);
|
|
473
649
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
474
|
-
const marketIndex =
|
|
650
|
+
const marketIndex = 0;
|
|
475
651
|
|
|
476
652
|
const slot = 12;
|
|
477
653
|
const oracle = {
|
|
@@ -484,7 +660,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
484
660
|
{
|
|
485
661
|
expectedIdx: 0,
|
|
486
662
|
isVamm: false,
|
|
487
|
-
orderId:
|
|
663
|
+
orderId: 3,
|
|
488
664
|
price: new BN(0),
|
|
489
665
|
direction: PositionDirection.SHORT,
|
|
490
666
|
orderType: OrderType.MARKET,
|
|
@@ -492,7 +668,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
492
668
|
{
|
|
493
669
|
expectedIdx: 1,
|
|
494
670
|
isVamm: false,
|
|
495
|
-
orderId:
|
|
671
|
+
orderId: 4,
|
|
496
672
|
price: new BN(0),
|
|
497
673
|
direction: PositionDirection.SHORT,
|
|
498
674
|
orderType: OrderType.MARKET,
|
|
@@ -500,7 +676,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
500
676
|
{
|
|
501
677
|
expectedIdx: 2,
|
|
502
678
|
isVamm: false,
|
|
503
|
-
orderId:
|
|
679
|
+
orderId: 5,
|
|
504
680
|
price: new BN(0),
|
|
505
681
|
direction: PositionDirection.SHORT,
|
|
506
682
|
orderType: OrderType.MARKET,
|
|
@@ -508,7 +684,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
508
684
|
{
|
|
509
685
|
expectedIdx: 3,
|
|
510
686
|
isVamm: false,
|
|
511
|
-
orderId:
|
|
687
|
+
orderId: 1,
|
|
512
688
|
price: new BN(13),
|
|
513
689
|
direction: PositionDirection.SHORT,
|
|
514
690
|
orderType: OrderType.LIMIT,
|
|
@@ -516,7 +692,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
516
692
|
{
|
|
517
693
|
expectedIdx: 6,
|
|
518
694
|
isVamm: false,
|
|
519
|
-
orderId:
|
|
695
|
+
orderId: 6,
|
|
520
696
|
price: new BN(16),
|
|
521
697
|
direction: PositionDirection.SHORT,
|
|
522
698
|
orderType: OrderType.LIMIT,
|
|
@@ -532,7 +708,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
532
708
|
{
|
|
533
709
|
expectedIdx: 7,
|
|
534
710
|
isVamm: false,
|
|
535
|
-
orderId:
|
|
711
|
+
orderId: 7,
|
|
536
712
|
price: new BN(17),
|
|
537
713
|
direction: PositionDirection.SHORT,
|
|
538
714
|
orderType: OrderType.LIMIT,
|
|
@@ -540,7 +716,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
540
716
|
{
|
|
541
717
|
expectedIdx: 4,
|
|
542
718
|
isVamm: false,
|
|
543
|
-
orderId:
|
|
719
|
+
orderId: 2,
|
|
544
720
|
price: new BN(14),
|
|
545
721
|
direction: PositionDirection.SHORT,
|
|
546
722
|
orderType: OrderType.LIMIT,
|
|
@@ -556,7 +732,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
556
732
|
Keypair.generate().publicKey,
|
|
557
733
|
t.orderType || OrderType.LIMIT,
|
|
558
734
|
MarketType.PERP,
|
|
559
|
-
t.orderId ||
|
|
735
|
+
t.orderId || 0, // orderId
|
|
560
736
|
marketIndex,
|
|
561
737
|
t.price || new BN(0), // price
|
|
562
738
|
BASE_PRECISION, // quantity
|
|
@@ -585,9 +761,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
585
761
|
);
|
|
586
762
|
|
|
587
763
|
expect(ask.isVammNode()).to.be.eq(expectedTestCase[countAsks].isVamm);
|
|
588
|
-
expect(ask.order?.orderId
|
|
589
|
-
expectedTestCase[countAsks].orderId?.toNumber()
|
|
590
|
-
);
|
|
764
|
+
expect(ask.order?.orderId).to.equal(expectedTestCase[countAsks].orderId);
|
|
591
765
|
expect(ask.order?.price.toNumber()).to.equal(
|
|
592
766
|
expectedTestCase[countAsks].price?.toNumber()
|
|
593
767
|
);
|
|
@@ -607,7 +781,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
607
781
|
const vAsk = new BN(11);
|
|
608
782
|
const vBid = new BN(10);
|
|
609
783
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
610
|
-
const marketIndex =
|
|
784
|
+
const marketIndex = 0;
|
|
611
785
|
const oracle = {
|
|
612
786
|
price: vBid.add(vAsk).div(new BN(2)),
|
|
613
787
|
slot: new BN(12),
|
|
@@ -622,7 +796,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
622
796
|
Keypair.generate().publicKey,
|
|
623
797
|
OrderType.MARKET,
|
|
624
798
|
MarketType.PERP,
|
|
625
|
-
|
|
799
|
+
i + 1,
|
|
626
800
|
marketIndex,
|
|
627
801
|
new BN(0),
|
|
628
802
|
BASE_PRECISION,
|
|
@@ -639,7 +813,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
639
813
|
Keypair.generate().publicKey,
|
|
640
814
|
OrderType.MARKET,
|
|
641
815
|
MarketType.PERP,
|
|
642
|
-
|
|
816
|
+
i + 1,
|
|
643
817
|
marketIndex,
|
|
644
818
|
new BN(0),
|
|
645
819
|
BASE_PRECISION,
|
|
@@ -665,7 +839,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
665
839
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
666
840
|
expect(getVariant(ask.order?.orderType)).to.equal('market');
|
|
667
841
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
668
|
-
expect(ask.order?.orderId
|
|
842
|
+
expect(ask.order?.orderId).to.equal(asks);
|
|
669
843
|
}
|
|
670
844
|
}
|
|
671
845
|
expect(asks).to.equal(4); // vamm ask + 3 orders
|
|
@@ -686,7 +860,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
686
860
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
687
861
|
expect(getVariant(bid.order?.orderType)).to.equal('market');
|
|
688
862
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
689
|
-
expect(bid.order?.orderId
|
|
863
|
+
expect(bid.order?.orderId).to.equal(bids);
|
|
690
864
|
}
|
|
691
865
|
bids++;
|
|
692
866
|
}
|
|
@@ -704,13 +878,13 @@ describe('DLOB Perp Tests', () => {
|
|
|
704
878
|
hasSufficientNumberOfDataPoints: true,
|
|
705
879
|
};
|
|
706
880
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
707
|
-
const marketIndex =
|
|
881
|
+
const marketIndex = 0;
|
|
708
882
|
insertOrderToDLOB(
|
|
709
883
|
dlob,
|
|
710
884
|
Keypair.generate().publicKey,
|
|
711
885
|
OrderType.LIMIT,
|
|
712
886
|
MarketType.PERP,
|
|
713
|
-
|
|
887
|
+
3, // orderId
|
|
714
888
|
marketIndex,
|
|
715
889
|
new BN(5),
|
|
716
890
|
BASE_PRECISION,
|
|
@@ -724,7 +898,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
724
898
|
Keypair.generate().publicKey,
|
|
725
899
|
OrderType.LIMIT,
|
|
726
900
|
MarketType.PERP,
|
|
727
|
-
|
|
901
|
+
2,
|
|
728
902
|
marketIndex,
|
|
729
903
|
new BN(6),
|
|
730
904
|
BASE_PRECISION,
|
|
@@ -738,7 +912,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
738
912
|
Keypair.generate().publicKey,
|
|
739
913
|
OrderType.LIMIT,
|
|
740
914
|
MarketType.PERP,
|
|
741
|
-
|
|
915
|
+
1, // orderId
|
|
742
916
|
marketIndex,
|
|
743
917
|
new BN(7),
|
|
744
918
|
BASE_PRECISION,
|
|
@@ -752,7 +926,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
752
926
|
Keypair.generate().publicKey,
|
|
753
927
|
OrderType.LIMIT,
|
|
754
928
|
MarketType.PERP,
|
|
755
|
-
|
|
929
|
+
1, // orderId
|
|
756
930
|
marketIndex,
|
|
757
931
|
new BN(12),
|
|
758
932
|
BASE_PRECISION,
|
|
@@ -766,7 +940,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
766
940
|
Keypair.generate().publicKey,
|
|
767
941
|
OrderType.LIMIT,
|
|
768
942
|
MarketType.PERP,
|
|
769
|
-
|
|
943
|
+
2, // orderId
|
|
770
944
|
marketIndex,
|
|
771
945
|
new BN(13),
|
|
772
946
|
BASE_PRECISION,
|
|
@@ -780,7 +954,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
780
954
|
Keypair.generate().publicKey,
|
|
781
955
|
OrderType.LIMIT,
|
|
782
956
|
MarketType.PERP,
|
|
783
|
-
|
|
957
|
+
3, // orderId
|
|
784
958
|
marketIndex,
|
|
785
959
|
new BN(14),
|
|
786
960
|
BASE_PRECISION,
|
|
@@ -803,7 +977,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
803
977
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
804
978
|
expect(getVariant(ask.order?.orderType)).to.equal('limit');
|
|
805
979
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
806
|
-
expect(ask.order?.orderId
|
|
980
|
+
expect(ask.order?.orderId).to.equal(asks);
|
|
807
981
|
expect(ask.order?.price.gt(vAsk)).to.equal(true);
|
|
808
982
|
}
|
|
809
983
|
|
|
@@ -829,7 +1003,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
829
1003
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
830
1004
|
expect(getVariant(bid.order?.orderType)).to.equal('limit');
|
|
831
1005
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
832
|
-
expect(bid.order?.orderId
|
|
1006
|
+
expect(bid.order?.orderId).to.equal(bids);
|
|
833
1007
|
expect(bid.order?.price.lt(vBid)).to.equal(true);
|
|
834
1008
|
}
|
|
835
1009
|
bids++;
|
|
@@ -837,11 +1011,182 @@ describe('DLOB Perp Tests', () => {
|
|
|
837
1011
|
expect(bids).to.equal(4); // vamm bid + 3 orders
|
|
838
1012
|
});
|
|
839
1013
|
|
|
1014
|
+
it('Test insert floatinglimit orders', () => {
|
|
1015
|
+
const slot = 12;
|
|
1016
|
+
const vAsk = new BN(11).mul(PRICE_PRECISION);
|
|
1017
|
+
const vBid = new BN(10).mul(PRICE_PRECISION);
|
|
1018
|
+
const oracle = {
|
|
1019
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1020
|
+
slot: new BN(slot),
|
|
1021
|
+
confidence: new BN(1),
|
|
1022
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1023
|
+
};
|
|
1024
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1025
|
+
const marketIndex = 0;
|
|
1026
|
+
|
|
1027
|
+
// insert floating bids
|
|
1028
|
+
insertOrderToDLOB(
|
|
1029
|
+
dlob,
|
|
1030
|
+
Keypair.generate().publicKey,
|
|
1031
|
+
OrderType.LIMIT,
|
|
1032
|
+
MarketType.PERP,
|
|
1033
|
+
1, // orderId
|
|
1034
|
+
marketIndex,
|
|
1035
|
+
new BN(0), // price
|
|
1036
|
+
BASE_PRECISION, // quantity
|
|
1037
|
+
PositionDirection.LONG,
|
|
1038
|
+
vBid,
|
|
1039
|
+
vAsk,
|
|
1040
|
+
new BN(slot),
|
|
1041
|
+
30, // TiF
|
|
1042
|
+
new BN(-1).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1043
|
+
);
|
|
1044
|
+
insertOrderToDLOB(
|
|
1045
|
+
dlob,
|
|
1046
|
+
Keypair.generate().publicKey,
|
|
1047
|
+
OrderType.LIMIT,
|
|
1048
|
+
MarketType.PERP,
|
|
1049
|
+
3, // orderId
|
|
1050
|
+
marketIndex,
|
|
1051
|
+
new BN(0), // price
|
|
1052
|
+
BASE_PRECISION, // quantity
|
|
1053
|
+
PositionDirection.LONG,
|
|
1054
|
+
vBid,
|
|
1055
|
+
vAsk,
|
|
1056
|
+
new BN(slot),
|
|
1057
|
+
30, // TiF
|
|
1058
|
+
new BN(-3).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1059
|
+
);
|
|
1060
|
+
insertOrderToDLOB(
|
|
1061
|
+
dlob,
|
|
1062
|
+
Keypair.generate().publicKey,
|
|
1063
|
+
OrderType.LIMIT,
|
|
1064
|
+
MarketType.PERP,
|
|
1065
|
+
2, // orderId
|
|
1066
|
+
marketIndex,
|
|
1067
|
+
new BN(0), // price
|
|
1068
|
+
BASE_PRECISION, // quantity
|
|
1069
|
+
PositionDirection.LONG,
|
|
1070
|
+
vBid,
|
|
1071
|
+
vAsk,
|
|
1072
|
+
new BN(slot),
|
|
1073
|
+
30, // TiF
|
|
1074
|
+
new BN(-2).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1075
|
+
);
|
|
1076
|
+
|
|
1077
|
+
// insert floating asks
|
|
1078
|
+
insertOrderToDLOB(
|
|
1079
|
+
dlob,
|
|
1080
|
+
Keypair.generate().publicKey,
|
|
1081
|
+
OrderType.LIMIT,
|
|
1082
|
+
MarketType.PERP,
|
|
1083
|
+
5, // orderId
|
|
1084
|
+
marketIndex,
|
|
1085
|
+
new BN(0), // price
|
|
1086
|
+
BASE_PRECISION, // quantity
|
|
1087
|
+
PositionDirection.SHORT,
|
|
1088
|
+
vAsk,
|
|
1089
|
+
vBid,
|
|
1090
|
+
new BN(slot),
|
|
1091
|
+
30, // TiF
|
|
1092
|
+
new BN(2).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1093
|
+
);
|
|
1094
|
+
insertOrderToDLOB(
|
|
1095
|
+
dlob,
|
|
1096
|
+
Keypair.generate().publicKey,
|
|
1097
|
+
OrderType.LIMIT,
|
|
1098
|
+
MarketType.PERP,
|
|
1099
|
+
6, // orderId
|
|
1100
|
+
marketIndex,
|
|
1101
|
+
new BN(0), // price
|
|
1102
|
+
BASE_PRECISION, // quantity
|
|
1103
|
+
PositionDirection.SHORT,
|
|
1104
|
+
vAsk,
|
|
1105
|
+
vBid,
|
|
1106
|
+
new BN(slot),
|
|
1107
|
+
30, // TiF
|
|
1108
|
+
new BN(3).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1109
|
+
);
|
|
1110
|
+
insertOrderToDLOB(
|
|
1111
|
+
dlob,
|
|
1112
|
+
Keypair.generate().publicKey,
|
|
1113
|
+
OrderType.LIMIT,
|
|
1114
|
+
MarketType.PERP,
|
|
1115
|
+
4, // orderId
|
|
1116
|
+
marketIndex,
|
|
1117
|
+
new BN(0), // price
|
|
1118
|
+
BASE_PRECISION, // quantity
|
|
1119
|
+
PositionDirection.SHORT,
|
|
1120
|
+
vAsk,
|
|
1121
|
+
vBid,
|
|
1122
|
+
new BN(slot),
|
|
1123
|
+
30, // TiF
|
|
1124
|
+
new BN(1).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1125
|
+
);
|
|
1126
|
+
|
|
1127
|
+
// check floating bids
|
|
1128
|
+
console.log(`bids:`);
|
|
1129
|
+
let lastBidPrice = new BN(9999999999999); // very big
|
|
1130
|
+
let bids = 0;
|
|
1131
|
+
for (const bid of dlob.getBids(
|
|
1132
|
+
marketIndex,
|
|
1133
|
+
vBid,
|
|
1134
|
+
slot,
|
|
1135
|
+
MarketType.PERP,
|
|
1136
|
+
oracle
|
|
1137
|
+
)) {
|
|
1138
|
+
printOrderNode(bid, oracle, slot);
|
|
1139
|
+
|
|
1140
|
+
if (!bid.isVammNode()) {
|
|
1141
|
+
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
1142
|
+
expect(getVariant(bid.order?.orderType)).to.equal('limit');
|
|
1143
|
+
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
1144
|
+
|
|
1145
|
+
// price should be getting worse (getting lower) as we iterate
|
|
1146
|
+
const currentPrice = bid.getPrice(oracle, slot);
|
|
1147
|
+
expect(
|
|
1148
|
+
currentPrice.lte(lastBidPrice),
|
|
1149
|
+
`each bid should be lte the last. current: ${currentPrice.toString()}, last: ${lastBidPrice.toString()}`
|
|
1150
|
+
).to.be.true;
|
|
1151
|
+
}
|
|
1152
|
+
lastBidPrice = bid.getPrice(oracle, slot);
|
|
1153
|
+
bids++;
|
|
1154
|
+
}
|
|
1155
|
+
expect(bids).to.equal(4); // vamm bid + 3 orders
|
|
1156
|
+
|
|
1157
|
+
// check floating asks
|
|
1158
|
+
console.log(`asks:`);
|
|
1159
|
+
let asks = 0;
|
|
1160
|
+
for (const ask of dlob.getAsks(
|
|
1161
|
+
marketIndex,
|
|
1162
|
+
vAsk,
|
|
1163
|
+
slot,
|
|
1164
|
+
MarketType.PERP,
|
|
1165
|
+
oracle
|
|
1166
|
+
)) {
|
|
1167
|
+
printOrderNode(ask, oracle, slot);
|
|
1168
|
+
if (!ask.isVammNode()) {
|
|
1169
|
+
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
1170
|
+
expect(getVariant(ask.order?.orderType)).to.equal('limit');
|
|
1171
|
+
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
1172
|
+
|
|
1173
|
+
// price should be getting worse (getting higher) as we iterate
|
|
1174
|
+
const currentPrice = ask.getPrice(oracle, slot);
|
|
1175
|
+
expect(
|
|
1176
|
+
currentPrice.gte(lastBidPrice),
|
|
1177
|
+
`each ask should be gte the last. current: ${currentPrice.toString()}, last: ${lastBidPrice.toString()}`
|
|
1178
|
+
).to.be.true;
|
|
1179
|
+
}
|
|
1180
|
+
asks++;
|
|
1181
|
+
}
|
|
1182
|
+
expect(asks).to.equal(4); // vamm ask + 3 orders
|
|
1183
|
+
});
|
|
1184
|
+
|
|
840
1185
|
it('Test multiple market orders fill with multiple limit orders', () => {
|
|
841
1186
|
const vAsk = new BN(15);
|
|
842
1187
|
const vBid = new BN(10);
|
|
843
1188
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
844
|
-
const marketIndex =
|
|
1189
|
+
const marketIndex = 0;
|
|
845
1190
|
|
|
846
1191
|
// insert some limit buys above vamm bid, below ask
|
|
847
1192
|
insertOrderToDLOB(
|
|
@@ -849,7 +1194,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
849
1194
|
Keypair.generate().publicKey,
|
|
850
1195
|
OrderType.LIMIT,
|
|
851
1196
|
MarketType.PERP,
|
|
852
|
-
|
|
1197
|
+
1, // orderId
|
|
853
1198
|
marketIndex,
|
|
854
1199
|
new BN(11), // price
|
|
855
1200
|
BASE_PRECISION, // quantity
|
|
@@ -862,7 +1207,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
862
1207
|
Keypair.generate().publicKey,
|
|
863
1208
|
OrderType.LIMIT,
|
|
864
1209
|
MarketType.PERP,
|
|
865
|
-
|
|
1210
|
+
2, // orderId
|
|
866
1211
|
marketIndex,
|
|
867
1212
|
new BN(12), // price
|
|
868
1213
|
BASE_PRECISION, // quantity
|
|
@@ -875,7 +1220,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
875
1220
|
Keypair.generate().publicKey,
|
|
876
1221
|
OrderType.LIMIT,
|
|
877
1222
|
MarketType.PERP,
|
|
878
|
-
|
|
1223
|
+
3, // orderId
|
|
879
1224
|
marketIndex,
|
|
880
1225
|
new BN(13), // price
|
|
881
1226
|
BASE_PRECISION, // quantity
|
|
@@ -887,8 +1232,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
887
1232
|
// should have no crossing orders
|
|
888
1233
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
889
1234
|
marketIndex,
|
|
890
|
-
vBid,
|
|
891
|
-
vAsk,
|
|
892
1235
|
12, // auction over
|
|
893
1236
|
MarketType.PERP,
|
|
894
1237
|
{
|
|
@@ -906,7 +1249,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
906
1249
|
Keypair.generate().publicKey,
|
|
907
1250
|
OrderType.MARKET,
|
|
908
1251
|
MarketType.PERP,
|
|
909
|
-
|
|
1252
|
+
4, // orderId
|
|
910
1253
|
marketIndex,
|
|
911
1254
|
new BN(12), // price
|
|
912
1255
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -919,7 +1262,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
919
1262
|
Keypair.generate().publicKey,
|
|
920
1263
|
OrderType.MARKET,
|
|
921
1264
|
MarketType.PERP,
|
|
922
|
-
|
|
1265
|
+
5, // orderId
|
|
923
1266
|
marketIndex,
|
|
924
1267
|
new BN(12), // price
|
|
925
1268
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -930,8 +1273,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
930
1273
|
|
|
931
1274
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
932
1275
|
marketIndex,
|
|
933
|
-
vBid,
|
|
934
|
-
vAsk,
|
|
935
1276
|
12, // auction over
|
|
936
1277
|
MarketType.PERP,
|
|
937
1278
|
{
|
|
@@ -941,31 +1282,26 @@ describe('DLOB Perp Tests', () => {
|
|
|
941
1282
|
hasSufficientNumberOfDataPoints: true,
|
|
942
1283
|
}
|
|
943
1284
|
);
|
|
1285
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
944
1286
|
for (const n of nodesToFillAfter) {
|
|
945
|
-
|
|
946
|
-
`cross found: taker orderId: ${n.node.order?.orderId.toString()}: BAA: ${n.node.order?.baseAssetAmount.toString()}, maker orderId: ${n.makerNode?.order?.orderId.toString()}: BAA: ${n.makerNode?.order?.baseAssetAmount.toString()}`
|
|
947
|
-
);
|
|
1287
|
+
printCrossedNodes(n, 12);
|
|
948
1288
|
}
|
|
949
1289
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
950
1290
|
|
|
951
1291
|
// first taker should fill with best maker
|
|
952
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
953
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
954
|
-
3
|
|
955
|
-
);
|
|
1292
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1293
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
956
1294
|
|
|
957
1295
|
// second taker should fill with second best maker
|
|
958
|
-
expect(nodesToFillAfter[1].node.order?.orderId
|
|
959
|
-
expect(nodesToFillAfter[1].makerNode?.order?.orderId
|
|
960
|
-
2
|
|
961
|
-
);
|
|
1296
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
1297
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
962
1298
|
});
|
|
963
1299
|
|
|
964
1300
|
it('Test one market orders fills two limit orders', () => {
|
|
965
1301
|
const vAsk = new BN(15);
|
|
966
1302
|
const vBid = new BN(10);
|
|
967
1303
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
968
|
-
const marketIndex =
|
|
1304
|
+
const marketIndex = 0;
|
|
969
1305
|
|
|
970
1306
|
// insert some limit sells below vAMM ask, above bid
|
|
971
1307
|
insertOrderToDLOB(
|
|
@@ -973,7 +1309,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
973
1309
|
Keypair.generate().publicKey,
|
|
974
1310
|
OrderType.LIMIT,
|
|
975
1311
|
MarketType.PERP,
|
|
976
|
-
|
|
1312
|
+
1, // orderId
|
|
977
1313
|
marketIndex,
|
|
978
1314
|
new BN(14), // price
|
|
979
1315
|
BASE_PRECISION, // quantity
|
|
@@ -986,7 +1322,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
986
1322
|
Keypair.generate().publicKey,
|
|
987
1323
|
OrderType.LIMIT,
|
|
988
1324
|
MarketType.PERP,
|
|
989
|
-
|
|
1325
|
+
2, // orderId
|
|
990
1326
|
marketIndex,
|
|
991
1327
|
new BN(13), // price
|
|
992
1328
|
BASE_PRECISION, // quantity
|
|
@@ -999,7 +1335,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
999
1335
|
Keypair.generate().publicKey,
|
|
1000
1336
|
OrderType.LIMIT,
|
|
1001
1337
|
MarketType.PERP,
|
|
1002
|
-
|
|
1338
|
+
3, // orderId
|
|
1003
1339
|
marketIndex,
|
|
1004
1340
|
new BN(12), // price
|
|
1005
1341
|
BASE_PRECISION, // quantity
|
|
@@ -1011,8 +1347,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
1011
1347
|
// should have no crossing orders
|
|
1012
1348
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
1013
1349
|
marketIndex,
|
|
1014
|
-
vBid,
|
|
1015
|
-
vAsk,
|
|
1016
1350
|
12, // auction over
|
|
1017
1351
|
MarketType.PERP,
|
|
1018
1352
|
{
|
|
@@ -1030,7 +1364,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1030
1364
|
Keypair.generate().publicKey,
|
|
1031
1365
|
OrderType.MARKET,
|
|
1032
1366
|
MarketType.PERP,
|
|
1033
|
-
|
|
1367
|
+
4, // orderId
|
|
1034
1368
|
marketIndex,
|
|
1035
1369
|
new BN(13), // price
|
|
1036
1370
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -1041,8 +1375,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
1041
1375
|
|
|
1042
1376
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
1043
1377
|
marketIndex,
|
|
1044
|
-
vBid,
|
|
1045
|
-
vAsk,
|
|
1046
1378
|
12, // auction over
|
|
1047
1379
|
MarketType.PERP,
|
|
1048
1380
|
{
|
|
@@ -1052,31 +1384,26 @@ describe('DLOB Perp Tests', () => {
|
|
|
1052
1384
|
hasSufficientNumberOfDataPoints: true,
|
|
1053
1385
|
}
|
|
1054
1386
|
);
|
|
1387
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1055
1388
|
for (const n of nodesToFillAfter) {
|
|
1056
|
-
|
|
1057
|
-
`cross found: taker orderId: ${n.node.order?.orderId.toString()}: BAA: ${n.node.order?.baseAssetAmountFilled.toString()}/${n.node.order?.baseAssetAmount.toString()}, maker orderId: ${n.makerNode?.order?.orderId.toString()}: BAA: ${n.makerNode?.order?.baseAssetAmountFilled.toString()}/${n.makerNode?.order?.baseAssetAmount.toString()}`
|
|
1058
|
-
);
|
|
1389
|
+
printCrossedNodes(n, 12);
|
|
1059
1390
|
}
|
|
1060
1391
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
1061
1392
|
|
|
1062
1393
|
// taker should fill completely with best maker
|
|
1063
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
1064
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
1065
|
-
3
|
|
1066
|
-
);
|
|
1394
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1395
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
1067
1396
|
|
|
1068
1397
|
// taker should fill completely with second best maker
|
|
1069
|
-
expect(nodesToFillAfter[1].node.order?.orderId
|
|
1070
|
-
expect(nodesToFillAfter[1].makerNode?.order?.orderId
|
|
1071
|
-
2
|
|
1072
|
-
);
|
|
1398
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(4);
|
|
1399
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
1073
1400
|
});
|
|
1074
1401
|
|
|
1075
1402
|
it('Test two market orders to fill one limit order', () => {
|
|
1076
1403
|
const vAsk = new BN(15);
|
|
1077
1404
|
const vBid = new BN(8);
|
|
1078
1405
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1079
|
-
const marketIndex =
|
|
1406
|
+
const marketIndex = 0;
|
|
1080
1407
|
|
|
1081
1408
|
const slot = 12;
|
|
1082
1409
|
const oracle = {
|
|
@@ -1092,7 +1419,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1092
1419
|
Keypair.generate().publicKey,
|
|
1093
1420
|
OrderType.LIMIT,
|
|
1094
1421
|
MarketType.PERP,
|
|
1095
|
-
|
|
1422
|
+
1, // orderId
|
|
1096
1423
|
marketIndex,
|
|
1097
1424
|
new BN(14), // price
|
|
1098
1425
|
BASE_PRECISION, // quantity
|
|
@@ -1105,7 +1432,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1105
1432
|
Keypair.generate().publicKey,
|
|
1106
1433
|
OrderType.LIMIT,
|
|
1107
1434
|
MarketType.PERP,
|
|
1108
|
-
|
|
1435
|
+
2, // orderId
|
|
1109
1436
|
marketIndex,
|
|
1110
1437
|
new BN(13), // price
|
|
1111
1438
|
BASE_PRECISION, // quantity
|
|
@@ -1118,7 +1445,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1118
1445
|
Keypair.generate().publicKey,
|
|
1119
1446
|
OrderType.LIMIT,
|
|
1120
1447
|
MarketType.PERP,
|
|
1121
|
-
|
|
1448
|
+
3, // orderId
|
|
1122
1449
|
marketIndex,
|
|
1123
1450
|
new BN(9), // price <-- best price
|
|
1124
1451
|
new BN(3).mul(BASE_PRECISION), // quantity
|
|
@@ -1130,8 +1457,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
1130
1457
|
// should have no crossing orders
|
|
1131
1458
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
1132
1459
|
marketIndex,
|
|
1133
|
-
vBid,
|
|
1134
|
-
vAsk,
|
|
1135
1460
|
12, // auction over
|
|
1136
1461
|
MarketType.PERP,
|
|
1137
1462
|
oracle
|
|
@@ -1144,7 +1469,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1144
1469
|
Keypair.generate().publicKey,
|
|
1145
1470
|
OrderType.MARKET,
|
|
1146
1471
|
MarketType.PERP,
|
|
1147
|
-
|
|
1472
|
+
4, // orderId
|
|
1148
1473
|
marketIndex,
|
|
1149
1474
|
new BN(0), // price
|
|
1150
1475
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -1157,7 +1482,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1157
1482
|
Keypair.generate().publicKey,
|
|
1158
1483
|
OrderType.MARKET,
|
|
1159
1484
|
MarketType.PERP,
|
|
1160
|
-
|
|
1485
|
+
5, // orderId
|
|
1161
1486
|
marketIndex,
|
|
1162
1487
|
new BN(0), // price
|
|
1163
1488
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -1168,87 +1493,39 @@ describe('DLOB Perp Tests', () => {
|
|
|
1168
1493
|
|
|
1169
1494
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
1170
1495
|
marketIndex,
|
|
1171
|
-
vBid,
|
|
1172
|
-
vAsk,
|
|
1173
1496
|
slot, // auction over
|
|
1174
1497
|
MarketType.PERP,
|
|
1175
1498
|
oracle
|
|
1176
1499
|
);
|
|
1177
|
-
const mktNodes = dlob.
|
|
1500
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
1178
1501
|
marketIndex,
|
|
1179
1502
|
slot,
|
|
1180
1503
|
MarketType.PERP
|
|
1181
1504
|
);
|
|
1182
1505
|
console.log(`market nodes: ${mktNodes.length}`);
|
|
1183
1506
|
|
|
1184
|
-
|
|
1185
|
-
marketIndex,
|
|
1186
|
-
vAsk,
|
|
1187
|
-
slot,
|
|
1188
|
-
MarketType.PERP,
|
|
1189
|
-
oracle
|
|
1190
|
-
);
|
|
1191
|
-
let aa = 0;
|
|
1192
|
-
for (const b of askNodes) {
|
|
1193
|
-
console.log(
|
|
1194
|
-
` . ask: ${b.order?.orderId.toString()}: p1: ${b.order?.price.toString()} p2: ${b.getPrice(
|
|
1195
|
-
oracle,
|
|
1196
|
-
slot
|
|
1197
|
-
)}, ${JSON.stringify(
|
|
1198
|
-
b.order?.orderType
|
|
1199
|
-
)} BAA: ${b.order?.baseAssetAmountFilled.toString()}/${b.order?.baseAssetAmount.toString()}`
|
|
1200
|
-
);
|
|
1201
|
-
aa++;
|
|
1202
|
-
}
|
|
1203
|
-
expect(aa).to.equal(4);
|
|
1507
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
1204
1508
|
|
|
1205
|
-
|
|
1206
|
-
marketIndex,
|
|
1207
|
-
vBid,
|
|
1208
|
-
slot,
|
|
1209
|
-
MarketType.PERP,
|
|
1210
|
-
oracle
|
|
1211
|
-
);
|
|
1212
|
-
let bb = 0;
|
|
1213
|
-
for (const b of bidNodes) {
|
|
1214
|
-
console.log(
|
|
1215
|
-
` . bid: ${b.order?.orderId.toString()}: p1: ${b.order?.price.toString()} p2: ${b.getPrice(
|
|
1216
|
-
oracle,
|
|
1217
|
-
slot
|
|
1218
|
-
)}, ${JSON.stringify(
|
|
1219
|
-
b.order?.orderType
|
|
1220
|
-
)} BAA: ${b.order?.baseAssetAmountFilled.toString()}/${b.order?.baseAssetAmount.toString()}`
|
|
1221
|
-
);
|
|
1222
|
-
bb++;
|
|
1223
|
-
}
|
|
1224
|
-
expect(bb).to.equal(3);
|
|
1225
|
-
|
|
1226
|
-
console.log(`bids nodes: ${bb}`);
|
|
1509
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1227
1510
|
for (const n of nodesToFillAfter) {
|
|
1228
|
-
|
|
1229
|
-
`cross found: taker orderId: ${n.node.order?.orderId.toString()}: BAA: ${n.node.order?.baseAssetAmountFilled.toString()}/${n.node.order?.baseAssetAmount.toString()}, maker orderId: ${n.makerNode?.order?.orderId.toString()}: BAA: ${n.makerNode?.order?.baseAssetAmountFilled.toString()}/${n.makerNode?.order?.baseAssetAmount.toString()}`
|
|
1230
|
-
);
|
|
1511
|
+
printCrossedNodes(n, slot);
|
|
1231
1512
|
}
|
|
1232
1513
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
1233
1514
|
|
|
1234
1515
|
// taker should fill completely with best maker
|
|
1235
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
1236
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
1237
|
-
3
|
|
1238
|
-
);
|
|
1516
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1517
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
1239
1518
|
|
|
1240
1519
|
// taker should fill completely with second best maker
|
|
1241
|
-
expect(nodesToFillAfter[1].node.order?.orderId
|
|
1242
|
-
expect(nodesToFillAfter[1].makerNode?.order?.orderId
|
|
1243
|
-
3
|
|
1244
|
-
);
|
|
1520
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
1521
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
|
|
1245
1522
|
});
|
|
1246
1523
|
|
|
1247
1524
|
it('Test trigger orders', () => {
|
|
1248
1525
|
const vAsk = new BN(15);
|
|
1249
1526
|
const vBid = new BN(8);
|
|
1250
1527
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1251
|
-
const marketIndex =
|
|
1528
|
+
const marketIndex = 0;
|
|
1252
1529
|
|
|
1253
1530
|
const slot = 20;
|
|
1254
1531
|
const oracle = {
|
|
@@ -1267,7 +1544,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1267
1544
|
Keypair.generate().publicKey,
|
|
1268
1545
|
OrderType.TRIGGER_LIMIT,
|
|
1269
1546
|
MarketType.PERP,
|
|
1270
|
-
|
|
1547
|
+
1, //orderId
|
|
1271
1548
|
marketIndex, // marketIndex
|
|
1272
1549
|
vBid, // price
|
|
1273
1550
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1283,7 +1560,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1283
1560
|
Keypair.generate().publicKey,
|
|
1284
1561
|
OrderType.TRIGGER_LIMIT,
|
|
1285
1562
|
MarketType.PERP,
|
|
1286
|
-
|
|
1563
|
+
2, //orderId
|
|
1287
1564
|
marketIndex, // marketIndex
|
|
1288
1565
|
vBid, // price
|
|
1289
1566
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1299,7 +1576,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1299
1576
|
Keypair.generate().publicKey,
|
|
1300
1577
|
OrderType.TRIGGER_MARKET,
|
|
1301
1578
|
MarketType.PERP,
|
|
1302
|
-
|
|
1579
|
+
3, //orderId
|
|
1303
1580
|
marketIndex, // marketIndex
|
|
1304
1581
|
vAsk, // price
|
|
1305
1582
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1315,7 +1592,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1315
1592
|
Keypair.generate().publicKey,
|
|
1316
1593
|
OrderType.TRIGGER_MARKET,
|
|
1317
1594
|
MarketType.PERP,
|
|
1318
|
-
|
|
1595
|
+
4, //orderId
|
|
1319
1596
|
marketIndex, // marketIndex
|
|
1320
1597
|
vBid, // price
|
|
1321
1598
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1329,223 +1606,924 @@ describe('DLOB Perp Tests', () => {
|
|
|
1329
1606
|
insertTriggerOrderToDLOB(
|
|
1330
1607
|
dlob,
|
|
1331
1608
|
Keypair.generate().publicKey,
|
|
1332
|
-
OrderType.TRIGGER_LIMIT,
|
|
1609
|
+
OrderType.TRIGGER_LIMIT,
|
|
1610
|
+
MarketType.PERP,
|
|
1611
|
+
5, //orderId
|
|
1612
|
+
marketIndex, // marketIndex
|
|
1613
|
+
vBid, // price
|
|
1614
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1615
|
+
PositionDirection.LONG,
|
|
1616
|
+
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1617
|
+
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1618
|
+
vBid,
|
|
1619
|
+
vAsk
|
|
1620
|
+
);
|
|
1621
|
+
// should trigger limit sell with below condition
|
|
1622
|
+
insertTriggerOrderToDLOB(
|
|
1623
|
+
dlob,
|
|
1624
|
+
Keypair.generate().publicKey,
|
|
1625
|
+
OrderType.TRIGGER_LIMIT,
|
|
1626
|
+
MarketType.PERP,
|
|
1627
|
+
6, //orderId
|
|
1628
|
+
marketIndex, // marketIndex
|
|
1629
|
+
vBid, // price
|
|
1630
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1631
|
+
PositionDirection.SHORT,
|
|
1632
|
+
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1633
|
+
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1634
|
+
vBid,
|
|
1635
|
+
vAsk
|
|
1636
|
+
);
|
|
1637
|
+
// should trigger market buy with below condition
|
|
1638
|
+
insertTriggerOrderToDLOB(
|
|
1639
|
+
dlob,
|
|
1640
|
+
Keypair.generate().publicKey,
|
|
1641
|
+
OrderType.TRIGGER_MARKET,
|
|
1642
|
+
MarketType.PERP,
|
|
1643
|
+
7, //orderId
|
|
1644
|
+
marketIndex, // marketIndex
|
|
1645
|
+
vBid, // price
|
|
1646
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1647
|
+
PositionDirection.LONG,
|
|
1648
|
+
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1649
|
+
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1650
|
+
vBid,
|
|
1651
|
+
vAsk
|
|
1652
|
+
);
|
|
1653
|
+
// should trigger market sell with below condition
|
|
1654
|
+
insertTriggerOrderToDLOB(
|
|
1655
|
+
dlob,
|
|
1656
|
+
Keypair.generate().publicKey,
|
|
1657
|
+
OrderType.TRIGGER_MARKET,
|
|
1658
|
+
MarketType.PERP,
|
|
1659
|
+
8, //orderId
|
|
1660
|
+
marketIndex, // marketIndex
|
|
1661
|
+
vBid, // price
|
|
1662
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1663
|
+
PositionDirection.LONG,
|
|
1664
|
+
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1665
|
+
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1666
|
+
vBid,
|
|
1667
|
+
vAsk
|
|
1668
|
+
);
|
|
1669
|
+
|
|
1670
|
+
// should NOT trigger market sell with above condition
|
|
1671
|
+
insertTriggerOrderToDLOB(
|
|
1672
|
+
dlob,
|
|
1673
|
+
Keypair.generate().publicKey,
|
|
1674
|
+
OrderType.TRIGGER_MARKET,
|
|
1675
|
+
MarketType.PERP,
|
|
1676
|
+
9, //orderId
|
|
1677
|
+
marketIndex, // marketIndex
|
|
1678
|
+
vBid, // price
|
|
1679
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1680
|
+
PositionDirection.SHORT,
|
|
1681
|
+
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1682
|
+
OrderTriggerCondition.ABOVE, // triggerCondition: OrderTriggerCondition,
|
|
1683
|
+
vBid,
|
|
1684
|
+
vAsk
|
|
1685
|
+
);
|
|
1686
|
+
// should NOT trigger market sell with below condition
|
|
1687
|
+
insertTriggerOrderToDLOB(
|
|
1688
|
+
dlob,
|
|
1689
|
+
Keypair.generate().publicKey,
|
|
1690
|
+
OrderType.TRIGGER_MARKET,
|
|
1691
|
+
MarketType.PERP,
|
|
1692
|
+
10, //orderId
|
|
1693
|
+
marketIndex, // marketIndex
|
|
1694
|
+
vBid, // price
|
|
1695
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1696
|
+
PositionDirection.SHORT,
|
|
1697
|
+
oracle.price.sub(new BN(1)), // triggerPrice: BN,
|
|
1698
|
+
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1699
|
+
vBid,
|
|
1700
|
+
vAsk
|
|
1701
|
+
);
|
|
1702
|
+
// should NOT trigger market buy with above condition
|
|
1703
|
+
insertTriggerOrderToDLOB(
|
|
1704
|
+
dlob,
|
|
1705
|
+
Keypair.generate().publicKey,
|
|
1706
|
+
OrderType.TRIGGER_MARKET,
|
|
1707
|
+
MarketType.PERP,
|
|
1708
|
+
11, //orderId
|
|
1709
|
+
marketIndex, // marketIndex
|
|
1710
|
+
vBid, // price
|
|
1711
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1712
|
+
PositionDirection.LONG,
|
|
1713
|
+
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1714
|
+
OrderTriggerCondition.ABOVE, // triggerCondition: OrderTriggerCondition,
|
|
1715
|
+
vBid,
|
|
1716
|
+
vAsk
|
|
1717
|
+
);
|
|
1718
|
+
// should NOT trigger market buy with below condition
|
|
1719
|
+
insertTriggerOrderToDLOB(
|
|
1720
|
+
dlob,
|
|
1721
|
+
Keypair.generate().publicKey,
|
|
1722
|
+
OrderType.TRIGGER_MARKET,
|
|
1723
|
+
MarketType.PERP,
|
|
1724
|
+
12, //orderId
|
|
1725
|
+
marketIndex, // marketIndex
|
|
1726
|
+
vBid, // price
|
|
1727
|
+
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1728
|
+
PositionDirection.LONG,
|
|
1729
|
+
oracle.price.sub(new BN(1)), // triggerPrice: BN,
|
|
1730
|
+
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1731
|
+
vBid,
|
|
1732
|
+
vAsk
|
|
1733
|
+
);
|
|
1734
|
+
|
|
1735
|
+
const nodesToTrigger = dlob.findNodesToTrigger(
|
|
1736
|
+
marketIndex,
|
|
1737
|
+
slot,
|
|
1738
|
+
oracle.price,
|
|
1739
|
+
MarketType.PERP
|
|
1740
|
+
);
|
|
1741
|
+
console.log(`nodesToTriggeR: ${nodesToTrigger.length}`);
|
|
1742
|
+
for (const [idx, n] of nodesToTrigger.entries()) {
|
|
1743
|
+
expect(n.node.order?.orderId).to.equal(orderIdsToTrigger[idx]);
|
|
1744
|
+
console.log(`nodeToTrigger: ${n.node.order?.orderId.toString()}`);
|
|
1745
|
+
}
|
|
1746
|
+
});
|
|
1747
|
+
|
|
1748
|
+
it('Test will return expired market orders to fill', () => {
|
|
1749
|
+
const vAsk = new BN(15);
|
|
1750
|
+
const vBid = new BN(8);
|
|
1751
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1752
|
+
const marketIndex = 0;
|
|
1753
|
+
|
|
1754
|
+
const slot = 20;
|
|
1755
|
+
const timeInForce = 30;
|
|
1756
|
+
|
|
1757
|
+
// non crossing bid
|
|
1758
|
+
insertOrderToDLOB(
|
|
1759
|
+
dlob,
|
|
1760
|
+
Keypair.generate().publicKey,
|
|
1761
|
+
OrderType.MARKET,
|
|
1762
|
+
MarketType.PERP,
|
|
1763
|
+
255, // orderId
|
|
1764
|
+
marketIndex,
|
|
1765
|
+
new BN(2), // price, very low, don't cross vamm
|
|
1766
|
+
BASE_PRECISION, // quantity
|
|
1767
|
+
PositionDirection.LONG,
|
|
1768
|
+
vBid,
|
|
1769
|
+
vAsk,
|
|
1770
|
+
new BN(slot),
|
|
1771
|
+
timeInForce
|
|
1772
|
+
);
|
|
1773
|
+
insertOrderToDLOB(
|
|
1774
|
+
dlob,
|
|
1775
|
+
Keypair.generate().publicKey,
|
|
1776
|
+
OrderType.MARKET,
|
|
1777
|
+
MarketType.PERP,
|
|
1778
|
+
2, // orderId
|
|
1779
|
+
marketIndex,
|
|
1780
|
+
new BN(30), // price, very high, don't cross vamm
|
|
1781
|
+
BASE_PRECISION, // quantity
|
|
1782
|
+
PositionDirection.SHORT,
|
|
1783
|
+
vAsk,
|
|
1784
|
+
vBid,
|
|
1785
|
+
new BN(slot),
|
|
1786
|
+
timeInForce
|
|
1787
|
+
);
|
|
1788
|
+
|
|
1789
|
+
// order auction is not yet complete, and order is not expired.
|
|
1790
|
+
const slot0 = slot;
|
|
1791
|
+
const nodesToFillBefore = dlob.findNodesToFill(
|
|
1792
|
+
marketIndex,
|
|
1793
|
+
vBid,
|
|
1794
|
+
vAsk,
|
|
1795
|
+
slot0,
|
|
1796
|
+
MarketType.PERP,
|
|
1797
|
+
{
|
|
1798
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1799
|
+
slot: new BN(slot0),
|
|
1800
|
+
confidence: new BN(1),
|
|
1801
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1802
|
+
}
|
|
1803
|
+
);
|
|
1804
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
1805
|
+
|
|
1806
|
+
// should get order to fill after timeInForce
|
|
1807
|
+
const slot1 = slot0 + timeInForce * 2; // overshoots expiry
|
|
1808
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
1809
|
+
marketIndex,
|
|
1810
|
+
vBid,
|
|
1811
|
+
vAsk,
|
|
1812
|
+
slot1, // auction is over, and order ix expired
|
|
1813
|
+
MarketType.PERP,
|
|
1814
|
+
{
|
|
1815
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1816
|
+
slot: new BN(slot1),
|
|
1817
|
+
confidence: new BN(1),
|
|
1818
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1819
|
+
}
|
|
1820
|
+
);
|
|
1821
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1822
|
+
for (const n of nodesToFillAfter) {
|
|
1823
|
+
printCrossedNodes(n, slot1);
|
|
1824
|
+
}
|
|
1825
|
+
expect(nodesToFillAfter.length).to.equal(2);
|
|
1826
|
+
|
|
1827
|
+
// check that the nodes have no makers
|
|
1828
|
+
expect(nodesToFillAfter[0].makerNode).to.equal(undefined);
|
|
1829
|
+
expect(nodesToFillAfter[1].makerNode).to.equal(undefined);
|
|
1830
|
+
});
|
|
1831
|
+
|
|
1832
|
+
it('Test skips vAMM and fills market buy order with floating limit order during auction', () => {
|
|
1833
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
1834
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
1835
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1836
|
+
const marketIndex = 0;
|
|
1837
|
+
|
|
1838
|
+
const slot = 12;
|
|
1839
|
+
const oracle = {
|
|
1840
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1841
|
+
slot: new BN(slot),
|
|
1842
|
+
confidence: new BN(1),
|
|
1843
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1844
|
+
};
|
|
1845
|
+
|
|
1846
|
+
// insert some floating limit sells above vAMM ask
|
|
1847
|
+
insertOrderToDLOB(
|
|
1848
|
+
dlob,
|
|
1849
|
+
Keypair.generate().publicKey,
|
|
1850
|
+
OrderType.LIMIT,
|
|
1851
|
+
MarketType.PERP,
|
|
1852
|
+
1, // orderId
|
|
1853
|
+
marketIndex,
|
|
1854
|
+
new BN(14).mul(PRICE_PRECISION), // price
|
|
1855
|
+
BASE_PRECISION, // quantity
|
|
1856
|
+
PositionDirection.SHORT,
|
|
1857
|
+
vBid,
|
|
1858
|
+
vAsk,
|
|
1859
|
+
new BN(slot),
|
|
1860
|
+
30,
|
|
1861
|
+
new BN(1).mul(PRICE_PRECISION)
|
|
1862
|
+
);
|
|
1863
|
+
insertOrderToDLOB(
|
|
1864
|
+
dlob,
|
|
1865
|
+
Keypair.generate().publicKey,
|
|
1866
|
+
OrderType.LIMIT,
|
|
1867
|
+
MarketType.PERP,
|
|
1868
|
+
2, // orderId
|
|
1869
|
+
marketIndex,
|
|
1870
|
+
new BN(13).mul(PRICE_PRECISION), // price
|
|
1871
|
+
BASE_PRECISION, // quantity
|
|
1872
|
+
PositionDirection.SHORT,
|
|
1873
|
+
vBid,
|
|
1874
|
+
vAsk,
|
|
1875
|
+
new BN(slot),
|
|
1876
|
+
30,
|
|
1877
|
+
new BN(1).mul(PRICE_PRECISION)
|
|
1878
|
+
);
|
|
1879
|
+
insertOrderToDLOB(
|
|
1880
|
+
dlob,
|
|
1881
|
+
Keypair.generate().publicKey,
|
|
1882
|
+
OrderType.LIMIT,
|
|
1883
|
+
MarketType.PERP,
|
|
1884
|
+
3, // orderId
|
|
1885
|
+
marketIndex,
|
|
1886
|
+
new BN(9).mul(PRICE_PRECISION), // price <-- best price
|
|
1887
|
+
new BN(3).mul(BASE_PRECISION), // quantity
|
|
1888
|
+
PositionDirection.SHORT,
|
|
1889
|
+
vBid,
|
|
1890
|
+
vAsk,
|
|
1891
|
+
new BN(slot),
|
|
1892
|
+
30,
|
|
1893
|
+
new BN(1).mul(PRICE_PRECISION)
|
|
1894
|
+
);
|
|
1895
|
+
|
|
1896
|
+
// should have no crossing orders
|
|
1897
|
+
const nodesToFillBefore = dlob.findNodesToFill(
|
|
1898
|
+
marketIndex,
|
|
1899
|
+
vBid,
|
|
1900
|
+
vAsk,
|
|
1901
|
+
slot,
|
|
1902
|
+
MarketType.PERP,
|
|
1903
|
+
{
|
|
1904
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1905
|
+
slot: new BN(slot),
|
|
1906
|
+
confidence: new BN(1),
|
|
1907
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1908
|
+
}
|
|
1909
|
+
);
|
|
1910
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
1911
|
+
|
|
1912
|
+
// place two market buy orders to eat the best ask
|
|
1913
|
+
insertOrderToDLOB(
|
|
1914
|
+
dlob,
|
|
1915
|
+
Keypair.generate().publicKey,
|
|
1916
|
+
OrderType.MARKET,
|
|
1917
|
+
MarketType.PERP,
|
|
1918
|
+
4, // orderId
|
|
1919
|
+
marketIndex,
|
|
1920
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
1921
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
1922
|
+
PositionDirection.LONG,
|
|
1923
|
+
vBid,
|
|
1924
|
+
vAsk
|
|
1925
|
+
);
|
|
1926
|
+
insertOrderToDLOB(
|
|
1927
|
+
dlob,
|
|
1928
|
+
Keypair.generate().publicKey,
|
|
1929
|
+
OrderType.MARKET,
|
|
1930
|
+
MarketType.PERP,
|
|
1931
|
+
5, // orderId
|
|
1932
|
+
marketIndex,
|
|
1933
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
1934
|
+
new BN(2).mul(BASE_PRECISION), // quantity
|
|
1935
|
+
PositionDirection.LONG,
|
|
1936
|
+
vBid,
|
|
1937
|
+
vAsk
|
|
1938
|
+
);
|
|
1939
|
+
|
|
1940
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
1941
|
+
marketIndex,
|
|
1942
|
+
vBid,
|
|
1943
|
+
vAsk,
|
|
1944
|
+
slot,
|
|
1945
|
+
MarketType.PERP,
|
|
1946
|
+
{
|
|
1947
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1948
|
+
slot: new BN(slot),
|
|
1949
|
+
confidence: new BN(1),
|
|
1950
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1951
|
+
}
|
|
1952
|
+
);
|
|
1953
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
1954
|
+
marketIndex,
|
|
1955
|
+
slot,
|
|
1956
|
+
MarketType.PERP
|
|
1957
|
+
);
|
|
1958
|
+
console.log(`market nodes: ${mktNodes.length}`);
|
|
1959
|
+
|
|
1960
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
1961
|
+
|
|
1962
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1963
|
+
for (const n of nodesToFillAfter) {
|
|
1964
|
+
printCrossedNodes(n, slot);
|
|
1965
|
+
}
|
|
1966
|
+
expect(nodesToFillAfter.length).to.equal(3);
|
|
1967
|
+
|
|
1968
|
+
// taker should fill first order completely with best maker (1/1)
|
|
1969
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1970
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(1);
|
|
1971
|
+
|
|
1972
|
+
// taker should fill partially with second best maker (1/2)
|
|
1973
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
1974
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
1975
|
+
|
|
1976
|
+
// taker should fill completely with third best maker (2/2)
|
|
1977
|
+
expect(nodesToFillAfter[2].node.order?.orderId).to.equal(5);
|
|
1978
|
+
expect(nodesToFillAfter[2].makerNode?.order?.orderId).to.equal(3);
|
|
1979
|
+
});
|
|
1980
|
+
|
|
1981
|
+
it('Test fills market buy order with better priced vAMM after auction', () => {
|
|
1982
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
1983
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
1984
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1985
|
+
const marketIndex = 0;
|
|
1986
|
+
|
|
1987
|
+
const slot = 12;
|
|
1988
|
+
const oracle = {
|
|
1989
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1990
|
+
slot: new BN(slot),
|
|
1991
|
+
confidence: new BN(1),
|
|
1992
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1993
|
+
};
|
|
1994
|
+
|
|
1995
|
+
// insert some floating limit sells above vAMM ask
|
|
1996
|
+
insertOrderToDLOB(
|
|
1997
|
+
dlob,
|
|
1998
|
+
Keypair.generate().publicKey,
|
|
1999
|
+
OrderType.LIMIT,
|
|
2000
|
+
MarketType.PERP,
|
|
2001
|
+
1, // orderId
|
|
2002
|
+
marketIndex,
|
|
2003
|
+
new BN(14).mul(PRICE_PRECISION), // price
|
|
2004
|
+
BASE_PRECISION, // quantity
|
|
2005
|
+
PositionDirection.SHORT,
|
|
2006
|
+
vBid,
|
|
2007
|
+
vAsk,
|
|
2008
|
+
new BN(slot),
|
|
2009
|
+
0,
|
|
2010
|
+
new BN(3).mul(PRICE_PRECISION)
|
|
2011
|
+
);
|
|
2012
|
+
insertOrderToDLOB(
|
|
2013
|
+
dlob,
|
|
2014
|
+
Keypair.generate().publicKey,
|
|
2015
|
+
OrderType.LIMIT,
|
|
2016
|
+
MarketType.PERP,
|
|
2017
|
+
2, // orderId
|
|
2018
|
+
marketIndex,
|
|
2019
|
+
new BN(13).mul(PRICE_PRECISION), // price
|
|
2020
|
+
BASE_PRECISION, // quantity
|
|
2021
|
+
PositionDirection.SHORT,
|
|
2022
|
+
vBid,
|
|
2023
|
+
vAsk,
|
|
2024
|
+
new BN(slot),
|
|
2025
|
+
0,
|
|
2026
|
+
new BN(4).mul(PRICE_PRECISION)
|
|
2027
|
+
);
|
|
2028
|
+
insertOrderToDLOB(
|
|
2029
|
+
dlob,
|
|
2030
|
+
Keypair.generate().publicKey,
|
|
2031
|
+
OrderType.LIMIT,
|
|
2032
|
+
MarketType.PERP,
|
|
2033
|
+
3, // orderId
|
|
2034
|
+
marketIndex,
|
|
2035
|
+
new BN(9).mul(PRICE_PRECISION), // price <-- best price
|
|
2036
|
+
new BN(3).mul(BASE_PRECISION), // quantity
|
|
2037
|
+
PositionDirection.SHORT,
|
|
2038
|
+
vBid,
|
|
2039
|
+
vAsk,
|
|
2040
|
+
new BN(slot),
|
|
2041
|
+
0,
|
|
2042
|
+
new BN(5).mul(PRICE_PRECISION)
|
|
2043
|
+
);
|
|
2044
|
+
|
|
2045
|
+
// should have no crossing orders
|
|
2046
|
+
const auctionOverSlot = slot * 10;
|
|
2047
|
+
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2048
|
+
marketIndex,
|
|
2049
|
+
auctionOverSlot, // auction over
|
|
2050
|
+
MarketType.PERP,
|
|
2051
|
+
oracle
|
|
2052
|
+
);
|
|
2053
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2054
|
+
|
|
2055
|
+
// place two market buy orders
|
|
2056
|
+
insertOrderToDLOB(
|
|
2057
|
+
dlob,
|
|
2058
|
+
Keypair.generate().publicKey,
|
|
2059
|
+
OrderType.MARKET,
|
|
2060
|
+
MarketType.PERP,
|
|
2061
|
+
4, // orderId
|
|
2062
|
+
marketIndex,
|
|
2063
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
2064
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2065
|
+
PositionDirection.LONG,
|
|
2066
|
+
vBid,
|
|
2067
|
+
vAsk,
|
|
2068
|
+
new BN(slot),
|
|
2069
|
+
0
|
|
2070
|
+
);
|
|
2071
|
+
insertOrderToDLOB(
|
|
2072
|
+
dlob,
|
|
2073
|
+
Keypair.generate().publicKey,
|
|
2074
|
+
OrderType.MARKET,
|
|
2075
|
+
MarketType.PERP,
|
|
2076
|
+
5, // orderId
|
|
2077
|
+
marketIndex,
|
|
2078
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
2079
|
+
new BN(2).mul(BASE_PRECISION), // quantity
|
|
2080
|
+
PositionDirection.LONG,
|
|
2081
|
+
vBid,
|
|
2082
|
+
vAsk,
|
|
2083
|
+
new BN(slot),
|
|
2084
|
+
0
|
|
2085
|
+
);
|
|
2086
|
+
|
|
2087
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2088
|
+
marketIndex,
|
|
2089
|
+
vBid,
|
|
2090
|
+
vAsk,
|
|
2091
|
+
auctionOverSlot, // auction in progress
|
|
2092
|
+
MarketType.PERP,
|
|
2093
|
+
oracle
|
|
2094
|
+
);
|
|
2095
|
+
|
|
2096
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2097
|
+
for (const n of nodesToFillAfter) {
|
|
2098
|
+
printCrossedNodes(n, auctionOverSlot);
|
|
2099
|
+
}
|
|
2100
|
+
expect(nodesToFillAfter.length).to.equal(2);
|
|
2101
|
+
|
|
2102
|
+
// taker should fill completely with best maker
|
|
2103
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
2104
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(1);
|
|
2105
|
+
|
|
2106
|
+
// taker should fill the rest with the vAMM
|
|
2107
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
2108
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(undefined);
|
|
2109
|
+
});
|
|
2110
|
+
|
|
2111
|
+
it('Test skips vAMM and fills market sell order with floating limit buys during auction', () => {
|
|
2112
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
2113
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
2114
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2115
|
+
const marketIndex = 0;
|
|
2116
|
+
|
|
2117
|
+
const slot = 12;
|
|
2118
|
+
const oracle = {
|
|
2119
|
+
price: vBid.add(vAsk).div(new BN(2)), // 11.5
|
|
2120
|
+
slot: new BN(slot),
|
|
2121
|
+
confidence: new BN(1),
|
|
2122
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2123
|
+
};
|
|
2124
|
+
|
|
2125
|
+
// insert some floating limit buy below vAMM bid
|
|
2126
|
+
insertOrderToDLOB(
|
|
2127
|
+
dlob,
|
|
2128
|
+
Keypair.generate().publicKey,
|
|
2129
|
+
OrderType.LIMIT,
|
|
2130
|
+
MarketType.PERP,
|
|
2131
|
+
2, // orderId
|
|
2132
|
+
marketIndex,
|
|
2133
|
+
new BN(0).mul(PRICE_PRECISION), // price, ignored since it's a floating limit
|
|
2134
|
+
BASE_PRECISION, // quantity
|
|
2135
|
+
PositionDirection.LONG,
|
|
2136
|
+
vBid,
|
|
2137
|
+
vAsk,
|
|
2138
|
+
new BN(slot),
|
|
2139
|
+
30,
|
|
2140
|
+
new BN(-4).mul(PRICE_PRECISION) // second best bid, but worse than vBid (8): 7.5
|
|
2141
|
+
);
|
|
2142
|
+
insertOrderToDLOB(
|
|
2143
|
+
dlob,
|
|
2144
|
+
Keypair.generate().publicKey,
|
|
2145
|
+
OrderType.LIMIT,
|
|
2146
|
+
MarketType.PERP,
|
|
2147
|
+
3, // orderId
|
|
2148
|
+
marketIndex,
|
|
2149
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2150
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2151
|
+
PositionDirection.LONG,
|
|
2152
|
+
vBid,
|
|
2153
|
+
vAsk,
|
|
2154
|
+
new BN(slot),
|
|
2155
|
+
30,
|
|
2156
|
+
new BN(-1).mul(PRICE_PRECISION) // best price: 10.5
|
|
2157
|
+
);
|
|
2158
|
+
insertOrderToDLOB(
|
|
2159
|
+
dlob,
|
|
2160
|
+
Keypair.generate().publicKey,
|
|
2161
|
+
OrderType.LIMIT,
|
|
2162
|
+
MarketType.PERP,
|
|
2163
|
+
1, // orderId
|
|
2164
|
+
marketIndex,
|
|
2165
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2166
|
+
BASE_PRECISION, // quantity
|
|
2167
|
+
PositionDirection.LONG,
|
|
2168
|
+
vBid,
|
|
2169
|
+
vAsk,
|
|
2170
|
+
new BN(slot),
|
|
2171
|
+
30,
|
|
2172
|
+
new BN(-5).mul(PRICE_PRECISION) // third best bid, worse than vBid (8): 6.5
|
|
2173
|
+
);
|
|
2174
|
+
|
|
2175
|
+
// should have no crossing orders
|
|
2176
|
+
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2177
|
+
marketIndex,
|
|
2178
|
+
slot,
|
|
2179
|
+
MarketType.PERP,
|
|
2180
|
+
oracle
|
|
2181
|
+
);
|
|
2182
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2183
|
+
|
|
2184
|
+
// place two market sell orders to eat the best bid
|
|
2185
|
+
insertOrderToDLOB(
|
|
2186
|
+
dlob,
|
|
2187
|
+
Keypair.generate().publicKey,
|
|
2188
|
+
OrderType.MARKET,
|
|
2189
|
+
MarketType.PERP,
|
|
2190
|
+
4, // orderId
|
|
2191
|
+
marketIndex,
|
|
2192
|
+
new BN(5).mul(PRICE_PRECISION), // price
|
|
2193
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2194
|
+
PositionDirection.SHORT,
|
|
2195
|
+
vBid,
|
|
2196
|
+
vAsk
|
|
2197
|
+
);
|
|
2198
|
+
insertOrderToDLOB(
|
|
2199
|
+
dlob,
|
|
2200
|
+
Keypair.generate().publicKey,
|
|
2201
|
+
OrderType.MARKET,
|
|
2202
|
+
MarketType.PERP,
|
|
2203
|
+
5, // orderId
|
|
2204
|
+
marketIndex,
|
|
2205
|
+
new BN(4).mul(PRICE_PRECISION), // price
|
|
2206
|
+
new BN(2).mul(BASE_PRECISION), // quantity
|
|
2207
|
+
PositionDirection.SHORT,
|
|
2208
|
+
vBid,
|
|
2209
|
+
vAsk
|
|
2210
|
+
);
|
|
2211
|
+
|
|
2212
|
+
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2213
|
+
marketIndex,
|
|
2214
|
+
slot, // auction in progress
|
|
2215
|
+
MarketType.PERP,
|
|
2216
|
+
oracle
|
|
2217
|
+
);
|
|
2218
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
2219
|
+
marketIndex,
|
|
2220
|
+
slot,
|
|
2221
|
+
MarketType.PERP
|
|
2222
|
+
);
|
|
2223
|
+
console.log(`market nodes: ${mktNodes.length}`);
|
|
2224
|
+
|
|
2225
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2226
|
+
|
|
2227
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2228
|
+
for (const n of nodesToFillAfter) {
|
|
2229
|
+
printCrossedNodes(n, slot);
|
|
2230
|
+
}
|
|
2231
|
+
expect(nodesToFillAfter.length).to.equal(3);
|
|
2232
|
+
|
|
2233
|
+
// taker should fill first order completely with best maker (1/1)
|
|
2234
|
+
expect(
|
|
2235
|
+
nodesToFillAfter[0].node.order?.orderId,
|
|
2236
|
+
'wrong taker orderId'
|
|
2237
|
+
).to.equal(4);
|
|
2238
|
+
expect(
|
|
2239
|
+
nodesToFillAfter[0].makerNode?.order?.orderId,
|
|
2240
|
+
'wrong maker orderId'
|
|
2241
|
+
).to.equal(3);
|
|
2242
|
+
|
|
2243
|
+
// taker should fill partially with second best maker (1/2)
|
|
2244
|
+
expect(
|
|
2245
|
+
nodesToFillAfter[1].node.order?.orderId,
|
|
2246
|
+
'wrong maker orderId'
|
|
2247
|
+
).to.equal(5);
|
|
2248
|
+
expect(
|
|
2249
|
+
nodesToFillAfter[1].makerNode?.order?.orderId,
|
|
2250
|
+
'wrong maker orderId'
|
|
2251
|
+
).to.equal(2);
|
|
2252
|
+
|
|
2253
|
+
// taker should fill completely with third best maker (2/2)
|
|
2254
|
+
expect(
|
|
2255
|
+
nodesToFillAfter[2].node.order?.orderId,
|
|
2256
|
+
'wrong taker orderId'
|
|
2257
|
+
).to.equal(5);
|
|
2258
|
+
expect(
|
|
2259
|
+
nodesToFillAfter[2].makerNode?.order?.orderId,
|
|
2260
|
+
'wrong maker orderId'
|
|
2261
|
+
).to.equal(1);
|
|
2262
|
+
});
|
|
2263
|
+
|
|
2264
|
+
it('Test fills market sell order with better priced vAMM after auction', () => {
|
|
2265
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
2266
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
2267
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2268
|
+
const marketIndex = 0;
|
|
2269
|
+
|
|
2270
|
+
const slot = 12;
|
|
2271
|
+
const oracle = {
|
|
2272
|
+
price: vBid.add(vAsk).div(new BN(2)), // 11.5
|
|
2273
|
+
slot: new BN(slot),
|
|
2274
|
+
confidence: new BN(1),
|
|
2275
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2276
|
+
};
|
|
2277
|
+
|
|
2278
|
+
// insert some floating limit buy below vAMM bid
|
|
2279
|
+
insertOrderToDLOB(
|
|
2280
|
+
dlob,
|
|
2281
|
+
Keypair.generate().publicKey,
|
|
2282
|
+
OrderType.LIMIT,
|
|
1333
2283
|
MarketType.PERP,
|
|
1334
|
-
|
|
1335
|
-
marketIndex,
|
|
1336
|
-
|
|
1337
|
-
BASE_PRECISION, //
|
|
2284
|
+
2, // orderId
|
|
2285
|
+
marketIndex,
|
|
2286
|
+
new BN(0).mul(PRICE_PRECISION), // price, ignored since it's a floating limit
|
|
2287
|
+
BASE_PRECISION, // quantity
|
|
1338
2288
|
PositionDirection.LONG,
|
|
1339
|
-
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1340
|
-
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1341
2289
|
vBid,
|
|
1342
|
-
vAsk
|
|
2290
|
+
vAsk,
|
|
2291
|
+
new BN(slot),
|
|
2292
|
+
30,
|
|
2293
|
+
new BN(-4).mul(PRICE_PRECISION) // second best bid, but worse than vBid (8): 7.5
|
|
1343
2294
|
);
|
|
1344
|
-
|
|
1345
|
-
insertTriggerOrderToDLOB(
|
|
2295
|
+
insertOrderToDLOB(
|
|
1346
2296
|
dlob,
|
|
1347
2297
|
Keypair.generate().publicKey,
|
|
1348
|
-
OrderType.
|
|
2298
|
+
OrderType.LIMIT,
|
|
1349
2299
|
MarketType.PERP,
|
|
1350
|
-
|
|
1351
|
-
marketIndex,
|
|
1352
|
-
|
|
1353
|
-
BASE_PRECISION, //
|
|
1354
|
-
PositionDirection.
|
|
1355
|
-
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1356
|
-
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
2300
|
+
3, // orderId
|
|
2301
|
+
marketIndex,
|
|
2302
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2303
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2304
|
+
PositionDirection.LONG,
|
|
1357
2305
|
vBid,
|
|
1358
|
-
vAsk
|
|
2306
|
+
vAsk,
|
|
2307
|
+
new BN(slot),
|
|
2308
|
+
30,
|
|
2309
|
+
new BN(-1).mul(PRICE_PRECISION) // best price: 10.5
|
|
1359
2310
|
);
|
|
1360
|
-
|
|
1361
|
-
insertTriggerOrderToDLOB(
|
|
2311
|
+
insertOrderToDLOB(
|
|
1362
2312
|
dlob,
|
|
1363
2313
|
Keypair.generate().publicKey,
|
|
1364
|
-
OrderType.
|
|
2314
|
+
OrderType.LIMIT,
|
|
1365
2315
|
MarketType.PERP,
|
|
1366
|
-
|
|
1367
|
-
marketIndex,
|
|
1368
|
-
|
|
1369
|
-
BASE_PRECISION, //
|
|
2316
|
+
1, // orderId
|
|
2317
|
+
marketIndex,
|
|
2318
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2319
|
+
BASE_PRECISION, // quantity
|
|
1370
2320
|
PositionDirection.LONG,
|
|
1371
|
-
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1372
|
-
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1373
2321
|
vBid,
|
|
1374
|
-
vAsk
|
|
2322
|
+
vAsk,
|
|
2323
|
+
new BN(slot),
|
|
2324
|
+
30,
|
|
2325
|
+
new BN(-5).mul(PRICE_PRECISION) // third best bid, worse than vBid (8): 6.5
|
|
1375
2326
|
);
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
new BN(8), //orderId
|
|
1383
|
-
marketIndex, // marketIndex
|
|
1384
|
-
vBid, // price
|
|
1385
|
-
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1386
|
-
PositionDirection.LONG,
|
|
1387
|
-
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1388
|
-
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
2327
|
+
|
|
2328
|
+
console.log('DLOB state before fill:');
|
|
2329
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2330
|
+
|
|
2331
|
+
const nodesToFillBefore = dlob.findNodesToFill(
|
|
2332
|
+
marketIndex,
|
|
1389
2333
|
vBid,
|
|
1390
|
-
vAsk
|
|
2334
|
+
vAsk,
|
|
2335
|
+
slot,
|
|
2336
|
+
MarketType.PERP,
|
|
2337
|
+
oracle
|
|
1391
2338
|
);
|
|
2339
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
1392
2340
|
|
|
1393
|
-
//
|
|
1394
|
-
|
|
2341
|
+
// place two market sell orders to eat the best bid
|
|
2342
|
+
insertOrderToDLOB(
|
|
1395
2343
|
dlob,
|
|
1396
2344
|
Keypair.generate().publicKey,
|
|
1397
|
-
OrderType.
|
|
2345
|
+
OrderType.MARKET,
|
|
1398
2346
|
MarketType.PERP,
|
|
1399
|
-
|
|
1400
|
-
marketIndex,
|
|
1401
|
-
|
|
1402
|
-
BASE_PRECISION, //
|
|
2347
|
+
4, // orderId
|
|
2348
|
+
marketIndex,
|
|
2349
|
+
new BN(5).mul(PRICE_PRECISION), // price
|
|
2350
|
+
new BN(1).mul(BASE_PRECISION), // quantity, should consume best bid floating limit
|
|
1403
2351
|
PositionDirection.SHORT,
|
|
1404
|
-
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1405
|
-
OrderTriggerCondition.ABOVE, // triggerCondition: OrderTriggerCondition,
|
|
1406
2352
|
vBid,
|
|
1407
|
-
vAsk
|
|
2353
|
+
vAsk,
|
|
2354
|
+
new BN(slot)
|
|
1408
2355
|
);
|
|
1409
|
-
|
|
1410
|
-
insertTriggerOrderToDLOB(
|
|
2356
|
+
insertOrderToDLOB(
|
|
1411
2357
|
dlob,
|
|
1412
2358
|
Keypair.generate().publicKey,
|
|
1413
|
-
OrderType.
|
|
2359
|
+
OrderType.MARKET,
|
|
1414
2360
|
MarketType.PERP,
|
|
1415
|
-
|
|
1416
|
-
marketIndex,
|
|
1417
|
-
|
|
1418
|
-
|
|
2361
|
+
5, // orderId
|
|
2362
|
+
marketIndex,
|
|
2363
|
+
// new BN(8).mul(PRICE_PRECISION), // price, this price will fill with vamm
|
|
2364
|
+
new BN(4).mul(PRICE_PRECISION), // price, this SHOULD fill with vamm
|
|
2365
|
+
new BN(2).mul(BASE_PRECISION), // quantity, should be filled with next best bid (vAMM)
|
|
1419
2366
|
PositionDirection.SHORT,
|
|
1420
|
-
oracle.price.sub(new BN(1)), // triggerPrice: BN,
|
|
1421
|
-
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1422
2367
|
vBid,
|
|
1423
|
-
vAsk
|
|
2368
|
+
vAsk,
|
|
2369
|
+
new BN(slot)
|
|
1424
2370
|
);
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
marketIndex, // marketIndex
|
|
1433
|
-
vBid, // price
|
|
1434
|
-
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1435
|
-
PositionDirection.LONG,
|
|
1436
|
-
oracle.price.add(new BN(1)), // triggerPrice: BN,
|
|
1437
|
-
OrderTriggerCondition.ABOVE, // triggerCondition: OrderTriggerCondition,
|
|
2371
|
+
|
|
2372
|
+
// auction ends, but order not expired
|
|
2373
|
+
const afterAuctionSlot = slot + 11;
|
|
2374
|
+
printBookState(dlob, marketIndex, vBid, vAsk, afterAuctionSlot, oracle);
|
|
2375
|
+
|
|
2376
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2377
|
+
marketIndex,
|
|
1438
2378
|
vBid,
|
|
1439
|
-
vAsk
|
|
1440
|
-
|
|
1441
|
-
// should NOT trigger market buy with below condition
|
|
1442
|
-
insertTriggerOrderToDLOB(
|
|
1443
|
-
dlob,
|
|
1444
|
-
Keypair.generate().publicKey,
|
|
1445
|
-
OrderType.TRIGGER_MARKET,
|
|
2379
|
+
vAsk,
|
|
2380
|
+
afterAuctionSlot,
|
|
1446
2381
|
MarketType.PERP,
|
|
1447
|
-
|
|
1448
|
-
marketIndex, // marketIndex
|
|
1449
|
-
vBid, // price
|
|
1450
|
-
BASE_PRECISION, // baseAssetAmount: BN,
|
|
1451
|
-
PositionDirection.LONG,
|
|
1452
|
-
oracle.price.sub(new BN(1)), // triggerPrice: BN,
|
|
1453
|
-
OrderTriggerCondition.BELOW, // triggerCondition: OrderTriggerCondition,
|
|
1454
|
-
vBid,
|
|
1455
|
-
vAsk
|
|
2382
|
+
oracle
|
|
1456
2383
|
);
|
|
1457
2384
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
oracle.price,
|
|
1462
|
-
MarketType.PERP
|
|
1463
|
-
);
|
|
1464
|
-
console.log(`nodesToTriggeR: ${nodesToTrigger.length}`);
|
|
1465
|
-
for (const [idx, n] of nodesToTrigger.entries()) {
|
|
1466
|
-
expect(n.node.order?.orderId.toNumber()).to.equal(orderIdsToTrigger[idx]);
|
|
1467
|
-
console.log(`nodeToTrigger: ${n.node.order?.orderId.toString()}`);
|
|
2385
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2386
|
+
for (const n of nodesToFillAfter) {
|
|
2387
|
+
printCrossedNodes(n, afterAuctionSlot);
|
|
1468
2388
|
}
|
|
2389
|
+
|
|
2390
|
+
// taker should fill first order completely with best maker (1/1)
|
|
2391
|
+
expect(
|
|
2392
|
+
nodesToFillAfter[0].node.order?.orderId,
|
|
2393
|
+
'wrong taker orderId'
|
|
2394
|
+
).to.equal(4);
|
|
2395
|
+
expect(
|
|
2396
|
+
nodesToFillAfter[0].makerNode?.order?.orderId,
|
|
2397
|
+
'wrong maker orderId'
|
|
2398
|
+
).to.equal(3);
|
|
2399
|
+
|
|
2400
|
+
// taker should fill second order completely with vamm
|
|
2401
|
+
expect(
|
|
2402
|
+
nodesToFillAfter[1].node.order?.orderId,
|
|
2403
|
+
'wrong taker orderId'
|
|
2404
|
+
).to.equal(5);
|
|
2405
|
+
expect(
|
|
2406
|
+
nodesToFillAfter[1].makerNode?.order?.orderId,
|
|
2407
|
+
'wrong maker orderId'
|
|
2408
|
+
).to.equal(2); // filler should match the DLOB makers, protocol will fill the taker with vAMM if it offers a better price.
|
|
2409
|
+
|
|
2410
|
+
expect(nodesToFillAfter.length).to.equal(3);
|
|
1469
2411
|
});
|
|
1470
2412
|
|
|
1471
|
-
it('Test
|
|
1472
|
-
const vAsk = new BN(15);
|
|
1473
|
-
const vBid = new BN(8);
|
|
2413
|
+
it('Test fills crossing bids with vAMM after auction ends', () => {
|
|
2414
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
2415
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
1474
2416
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1475
|
-
const marketIndex =
|
|
2417
|
+
const marketIndex = 0;
|
|
1476
2418
|
|
|
1477
|
-
const slot =
|
|
1478
|
-
const
|
|
2419
|
+
const slot = 12;
|
|
2420
|
+
const oracle = {
|
|
2421
|
+
price: vBid.add(vAsk).div(new BN(2)), // 11.5
|
|
2422
|
+
slot: new BN(slot),
|
|
2423
|
+
confidence: new BN(1),
|
|
2424
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2425
|
+
};
|
|
1479
2426
|
|
|
1480
|
-
//
|
|
2427
|
+
// insert some floating limit buy below vAMM bid
|
|
1481
2428
|
insertOrderToDLOB(
|
|
1482
2429
|
dlob,
|
|
1483
2430
|
Keypair.generate().publicKey,
|
|
1484
|
-
OrderType.
|
|
2431
|
+
OrderType.LIMIT,
|
|
1485
2432
|
MarketType.PERP,
|
|
1486
|
-
|
|
2433
|
+
2, // orderId
|
|
1487
2434
|
marketIndex,
|
|
1488
|
-
new BN(
|
|
2435
|
+
new BN(17).mul(PRICE_PRECISION), // price, crosses vAsk
|
|
1489
2436
|
BASE_PRECISION, // quantity
|
|
1490
2437
|
PositionDirection.LONG,
|
|
1491
2438
|
vBid,
|
|
1492
2439
|
vAsk,
|
|
1493
2440
|
new BN(slot),
|
|
1494
|
-
|
|
2441
|
+
30
|
|
1495
2442
|
);
|
|
1496
2443
|
insertOrderToDLOB(
|
|
1497
2444
|
dlob,
|
|
1498
2445
|
Keypair.generate().publicKey,
|
|
1499
|
-
OrderType.
|
|
2446
|
+
OrderType.LIMIT,
|
|
1500
2447
|
MarketType.PERP,
|
|
1501
|
-
|
|
2448
|
+
3, // orderId
|
|
1502
2449
|
marketIndex,
|
|
1503
|
-
new BN(
|
|
1504
|
-
BASE_PRECISION, // quantity
|
|
1505
|
-
PositionDirection.
|
|
2450
|
+
new BN(19).mul(PRICE_PRECISION), // price; crosses vAsk
|
|
2451
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2452
|
+
PositionDirection.LONG,
|
|
2453
|
+
vBid,
|
|
1506
2454
|
vAsk,
|
|
2455
|
+
new BN(slot),
|
|
2456
|
+
30
|
|
2457
|
+
);
|
|
2458
|
+
insertOrderToDLOB(
|
|
2459
|
+
dlob,
|
|
2460
|
+
Keypair.generate().publicKey,
|
|
2461
|
+
OrderType.LIMIT,
|
|
2462
|
+
MarketType.PERP,
|
|
2463
|
+
1, // orderId
|
|
2464
|
+
marketIndex,
|
|
2465
|
+
new BN(5).mul(PRICE_PRECISION), // price; doens't cross
|
|
2466
|
+
BASE_PRECISION, // quantity
|
|
2467
|
+
PositionDirection.LONG,
|
|
1507
2468
|
vBid,
|
|
2469
|
+
vAsk,
|
|
1508
2470
|
new BN(slot),
|
|
1509
|
-
|
|
2471
|
+
30
|
|
1510
2472
|
);
|
|
2473
|
+
console.log(`Book state before fill:`);
|
|
2474
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
1511
2475
|
|
|
1512
|
-
// order auction is not yet complete, and order is not expired.
|
|
1513
|
-
const slot0 = slot;
|
|
1514
2476
|
const nodesToFillBefore = dlob.findNodesToFill(
|
|
1515
2477
|
marketIndex,
|
|
1516
2478
|
vBid,
|
|
1517
2479
|
vAsk,
|
|
1518
|
-
|
|
2480
|
+
slot,
|
|
1519
2481
|
MarketType.PERP,
|
|
1520
|
-
|
|
1521
|
-
price: vBid.add(vAsk).div(new BN(2)),
|
|
1522
|
-
slot: new BN(slot0),
|
|
1523
|
-
confidence: new BN(1),
|
|
1524
|
-
hasSufficientNumberOfDataPoints: true,
|
|
1525
|
-
}
|
|
2482
|
+
oracle
|
|
1526
2483
|
);
|
|
1527
2484
|
expect(nodesToFillBefore.length).to.equal(0);
|
|
1528
2485
|
|
|
1529
|
-
//
|
|
1530
|
-
const
|
|
2486
|
+
// auction ends now
|
|
2487
|
+
const afterAuctionSlot = 10 * slot;
|
|
2488
|
+
|
|
1531
2489
|
const nodesToFillAfter = dlob.findNodesToFill(
|
|
1532
2490
|
marketIndex,
|
|
1533
2491
|
vBid,
|
|
1534
2492
|
vAsk,
|
|
1535
|
-
|
|
2493
|
+
afterAuctionSlot,
|
|
1536
2494
|
MarketType.PERP,
|
|
1537
|
-
|
|
1538
|
-
price: vBid.add(vAsk).div(new BN(2)),
|
|
1539
|
-
slot: new BN(slot1),
|
|
1540
|
-
confidence: new BN(1),
|
|
1541
|
-
hasSufficientNumberOfDataPoints: true,
|
|
1542
|
-
}
|
|
2495
|
+
oracle
|
|
1543
2496
|
);
|
|
1544
|
-
expect(nodesToFillAfter.length).to.equal(2);
|
|
1545
2497
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
2498
|
+
console.log(`Book state after fill:`);
|
|
2499
|
+
printBookState(dlob, marketIndex, vBid, vAsk, afterAuctionSlot, oracle);
|
|
2500
|
+
|
|
2501
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2502
|
+
for (const n of nodesToFillAfter) {
|
|
2503
|
+
printCrossedNodes(n, afterAuctionSlot);
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
// taker should fill first order completely with best maker (1/1)
|
|
2507
|
+
expect(
|
|
2508
|
+
nodesToFillAfter[0].node.order?.orderId,
|
|
2509
|
+
'wrong taker orderId'
|
|
2510
|
+
).to.equal(3);
|
|
2511
|
+
expect(
|
|
2512
|
+
nodesToFillAfter[0].makerNode?.order?.orderId,
|
|
2513
|
+
'wrong maker orderId'
|
|
2514
|
+
).to.equal(undefined);
|
|
2515
|
+
|
|
2516
|
+
// taker should fill second order completely with vamm
|
|
2517
|
+
expect(
|
|
2518
|
+
nodesToFillAfter[1].node.order?.orderId,
|
|
2519
|
+
'wrong taker orderId'
|
|
2520
|
+
).to.equal(2);
|
|
2521
|
+
expect(
|
|
2522
|
+
nodesToFillAfter[1].makerNode?.order?.orderId,
|
|
2523
|
+
'wrong maker orderId'
|
|
2524
|
+
).to.equal(undefined);
|
|
2525
|
+
|
|
2526
|
+
expect(nodesToFillAfter.length).to.equal(2);
|
|
1549
2527
|
});
|
|
1550
2528
|
});
|
|
1551
2529
|
|
|
@@ -1554,7 +2532,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1554
2532
|
const vAsk = new BN(115);
|
|
1555
2533
|
const vBid = new BN(100);
|
|
1556
2534
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1557
|
-
const marketIndex =
|
|
2535
|
+
const marketIndex = 0;
|
|
1558
2536
|
|
|
1559
2537
|
const slot = 12;
|
|
1560
2538
|
const oracle = {
|
|
@@ -1566,49 +2544,49 @@ describe('DLOB Spot Tests', () => {
|
|
|
1566
2544
|
const testCases = [
|
|
1567
2545
|
{
|
|
1568
2546
|
expectedIdx: 3,
|
|
1569
|
-
orderId:
|
|
2547
|
+
orderId: 5,
|
|
1570
2548
|
price: new BN(0), // will calc 108
|
|
1571
2549
|
direction: PositionDirection.LONG,
|
|
1572
2550
|
orderType: OrderType.MARKET,
|
|
1573
2551
|
},
|
|
1574
2552
|
{
|
|
1575
2553
|
expectedIdx: 4,
|
|
1576
|
-
orderId:
|
|
2554
|
+
orderId: 6,
|
|
1577
2555
|
price: new BN(0), // will calc 108
|
|
1578
2556
|
direction: PositionDirection.LONG,
|
|
1579
2557
|
orderType: OrderType.MARKET,
|
|
1580
2558
|
},
|
|
1581
2559
|
{
|
|
1582
2560
|
expectedIdx: 5,
|
|
1583
|
-
orderId:
|
|
2561
|
+
orderId: 7,
|
|
1584
2562
|
price: new BN(0), // will calc 108
|
|
1585
2563
|
direction: PositionDirection.LONG,
|
|
1586
2564
|
orderType: OrderType.MARKET,
|
|
1587
2565
|
},
|
|
1588
2566
|
{
|
|
1589
2567
|
expectedIdx: 0,
|
|
1590
|
-
orderId:
|
|
2568
|
+
orderId: 1,
|
|
1591
2569
|
price: new BN(110),
|
|
1592
2570
|
direction: PositionDirection.LONG,
|
|
1593
2571
|
orderType: OrderType.LIMIT,
|
|
1594
2572
|
},
|
|
1595
2573
|
{
|
|
1596
2574
|
expectedIdx: 1,
|
|
1597
|
-
orderId:
|
|
2575
|
+
orderId: 2,
|
|
1598
2576
|
price: new BN(109),
|
|
1599
2577
|
direction: PositionDirection.LONG,
|
|
1600
2578
|
orderType: OrderType.LIMIT,
|
|
1601
2579
|
},
|
|
1602
2580
|
{
|
|
1603
2581
|
expectedIdx: 6,
|
|
1604
|
-
orderId:
|
|
2582
|
+
orderId: 3,
|
|
1605
2583
|
price: new BN(107),
|
|
1606
2584
|
direction: PositionDirection.LONG,
|
|
1607
2585
|
orderType: OrderType.LIMIT,
|
|
1608
2586
|
},
|
|
1609
2587
|
{
|
|
1610
2588
|
expectedIdx: 7,
|
|
1611
|
-
orderId:
|
|
2589
|
+
orderId: 4,
|
|
1612
2590
|
price: new BN(106),
|
|
1613
2591
|
direction: PositionDirection.LONG,
|
|
1614
2592
|
orderType: OrderType.LIMIT,
|
|
@@ -1621,7 +2599,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1621
2599
|
Keypair.generate().publicKey,
|
|
1622
2600
|
t.orderType || OrderType.LIMIT,
|
|
1623
2601
|
MarketType.SPOT,
|
|
1624
|
-
t.orderId ||
|
|
2602
|
+
t.orderId || 0, // orderId
|
|
1625
2603
|
marketIndex,
|
|
1626
2604
|
t.price || new BN(0), // price
|
|
1627
2605
|
BASE_PRECISION, // quantity
|
|
@@ -1646,18 +2624,9 @@ describe('DLOB Spot Tests', () => {
|
|
|
1646
2624
|
console.log('The Book Bids:');
|
|
1647
2625
|
let countBids = 0;
|
|
1648
2626
|
for (const bid of bids) {
|
|
1649
|
-
|
|
1650
|
-
` . vAMMNode? ${bid.isVammNode()}, ${JSON.stringify(
|
|
1651
|
-
bid.order?.orderType
|
|
1652
|
-
)} , ${bid.order?.orderId.toString()} , vammTestgetPRice: ${bid.getPrice(
|
|
1653
|
-
oracle,
|
|
1654
|
-
slot
|
|
1655
|
-
)}, price: ${bid.order?.price.toString()}, quantity: ${bid.order?.baseAssetAmountFilled.toString()}/${bid.order?.baseAssetAmount.toString()}`
|
|
1656
|
-
);
|
|
2627
|
+
printOrderNode(bid, oracle, slot);
|
|
1657
2628
|
|
|
1658
|
-
expect(bid.order?.orderId
|
|
1659
|
-
expectedTestCase[countBids].orderId?.toNumber()
|
|
1660
|
-
);
|
|
2629
|
+
expect(bid.order?.orderId).to.equal(expectedTestCase[countBids].orderId);
|
|
1661
2630
|
expect(bid.order?.price.toNumber()).to.equal(
|
|
1662
2631
|
expectedTestCase[countBids].price?.toNumber()
|
|
1663
2632
|
);
|
|
@@ -1677,8 +2646,8 @@ describe('DLOB Spot Tests', () => {
|
|
|
1677
2646
|
const vAsk = new BN(15);
|
|
1678
2647
|
const vBid = new BN(10);
|
|
1679
2648
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1680
|
-
const marketIndex0 =
|
|
1681
|
-
const marketIndex1 =
|
|
2649
|
+
const marketIndex0 = 0;
|
|
2650
|
+
const marketIndex1 = 1;
|
|
1682
2651
|
|
|
1683
2652
|
const slot = 12;
|
|
1684
2653
|
const oracle = {
|
|
@@ -1690,7 +2659,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1690
2659
|
const testCases = [
|
|
1691
2660
|
{
|
|
1692
2661
|
expectedIdx: 3,
|
|
1693
|
-
orderId:
|
|
2662
|
+
orderId: 5,
|
|
1694
2663
|
price: new BN(0),
|
|
1695
2664
|
direction: PositionDirection.LONG,
|
|
1696
2665
|
orderType: OrderType.MARKET,
|
|
@@ -1698,7 +2667,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1698
2667
|
},
|
|
1699
2668
|
{
|
|
1700
2669
|
expectedIdx: 4,
|
|
1701
|
-
orderId:
|
|
2670
|
+
orderId: 6,
|
|
1702
2671
|
price: new BN(0),
|
|
1703
2672
|
direction: PositionDirection.LONG,
|
|
1704
2673
|
orderType: OrderType.MARKET,
|
|
@@ -1706,7 +2675,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1706
2675
|
},
|
|
1707
2676
|
{
|
|
1708
2677
|
expectedIdx: 5,
|
|
1709
|
-
orderId:
|
|
2678
|
+
orderId: 7,
|
|
1710
2679
|
price: new BN(0),
|
|
1711
2680
|
direction: PositionDirection.LONG,
|
|
1712
2681
|
orderType: OrderType.MARKET,
|
|
@@ -1714,7 +2683,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1714
2683
|
},
|
|
1715
2684
|
{
|
|
1716
2685
|
expectedIdx: 0,
|
|
1717
|
-
orderId:
|
|
2686
|
+
orderId: 1,
|
|
1718
2687
|
price: new BN(12),
|
|
1719
2688
|
direction: PositionDirection.LONG,
|
|
1720
2689
|
orderType: OrderType.LIMIT,
|
|
@@ -1722,7 +2691,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1722
2691
|
},
|
|
1723
2692
|
{
|
|
1724
2693
|
expectedIdx: 1,
|
|
1725
|
-
orderId:
|
|
2694
|
+
orderId: 2,
|
|
1726
2695
|
price: new BN(11),
|
|
1727
2696
|
direction: PositionDirection.LONG,
|
|
1728
2697
|
orderType: OrderType.LIMIT,
|
|
@@ -1730,7 +2699,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1730
2699
|
},
|
|
1731
2700
|
{
|
|
1732
2701
|
expectedIdx: 7,
|
|
1733
|
-
orderId:
|
|
2702
|
+
orderId: 3,
|
|
1734
2703
|
price: new BN(8),
|
|
1735
2704
|
direction: PositionDirection.LONG,
|
|
1736
2705
|
orderType: OrderType.LIMIT,
|
|
@@ -1738,7 +2707,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1738
2707
|
},
|
|
1739
2708
|
{
|
|
1740
2709
|
expectedIdx: 6,
|
|
1741
|
-
orderId:
|
|
2710
|
+
orderId: 4,
|
|
1742
2711
|
price: new BN(9),
|
|
1743
2712
|
direction: PositionDirection.LONG,
|
|
1744
2713
|
orderType: OrderType.LIMIT,
|
|
@@ -1752,7 +2721,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1752
2721
|
Keypair.generate().publicKey,
|
|
1753
2722
|
t.orderType || OrderType.LIMIT,
|
|
1754
2723
|
MarketType.SPOT,
|
|
1755
|
-
t.orderId ||
|
|
2724
|
+
t.orderId || 0, // orderId
|
|
1756
2725
|
t.marketIndex,
|
|
1757
2726
|
t.price || new BN(0), // price
|
|
1758
2727
|
BASE_PRECISION, // quantity
|
|
@@ -1810,7 +2779,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1810
2779
|
const vAsk = new BN(15);
|
|
1811
2780
|
const vBid = new BN(10);
|
|
1812
2781
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1813
|
-
const marketIndex =
|
|
2782
|
+
const marketIndex = 0;
|
|
1814
2783
|
|
|
1815
2784
|
const slot = 12;
|
|
1816
2785
|
const oracle = {
|
|
@@ -1822,49 +2791,49 @@ describe('DLOB Spot Tests', () => {
|
|
|
1822
2791
|
const testCases = [
|
|
1823
2792
|
{
|
|
1824
2793
|
expectedIdx: 0,
|
|
1825
|
-
orderId:
|
|
2794
|
+
orderId: 3,
|
|
1826
2795
|
price: new BN(0),
|
|
1827
2796
|
direction: PositionDirection.SHORT,
|
|
1828
2797
|
orderType: OrderType.MARKET,
|
|
1829
2798
|
},
|
|
1830
2799
|
{
|
|
1831
2800
|
expectedIdx: 1,
|
|
1832
|
-
orderId:
|
|
2801
|
+
orderId: 4,
|
|
1833
2802
|
price: new BN(0),
|
|
1834
2803
|
direction: PositionDirection.SHORT,
|
|
1835
2804
|
orderType: OrderType.MARKET,
|
|
1836
2805
|
},
|
|
1837
2806
|
{
|
|
1838
2807
|
expectedIdx: 2,
|
|
1839
|
-
orderId:
|
|
2808
|
+
orderId: 5,
|
|
1840
2809
|
price: new BN(0),
|
|
1841
2810
|
direction: PositionDirection.SHORT,
|
|
1842
2811
|
orderType: OrderType.MARKET,
|
|
1843
2812
|
},
|
|
1844
2813
|
{
|
|
1845
2814
|
expectedIdx: 3,
|
|
1846
|
-
orderId:
|
|
2815
|
+
orderId: 1,
|
|
1847
2816
|
price: new BN(13),
|
|
1848
2817
|
direction: PositionDirection.SHORT,
|
|
1849
2818
|
orderType: OrderType.LIMIT,
|
|
1850
2819
|
},
|
|
1851
2820
|
{
|
|
1852
2821
|
expectedIdx: 6,
|
|
1853
|
-
orderId:
|
|
2822
|
+
orderId: 6,
|
|
1854
2823
|
price: new BN(16),
|
|
1855
2824
|
direction: PositionDirection.SHORT,
|
|
1856
2825
|
orderType: OrderType.LIMIT,
|
|
1857
2826
|
},
|
|
1858
2827
|
{
|
|
1859
2828
|
expectedIdx: 7,
|
|
1860
|
-
orderId:
|
|
2829
|
+
orderId: 7,
|
|
1861
2830
|
price: new BN(17),
|
|
1862
2831
|
direction: PositionDirection.SHORT,
|
|
1863
2832
|
orderType: OrderType.LIMIT,
|
|
1864
2833
|
},
|
|
1865
2834
|
{
|
|
1866
2835
|
expectedIdx: 4,
|
|
1867
|
-
orderId:
|
|
2836
|
+
orderId: 2,
|
|
1868
2837
|
price: new BN(14),
|
|
1869
2838
|
direction: PositionDirection.SHORT,
|
|
1870
2839
|
orderType: OrderType.LIMIT,
|
|
@@ -1877,7 +2846,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1877
2846
|
Keypair.generate().publicKey,
|
|
1878
2847
|
t.orderType || OrderType.LIMIT,
|
|
1879
2848
|
MarketType.SPOT,
|
|
1880
|
-
t.orderId ||
|
|
2849
|
+
t.orderId || 0, // orderId
|
|
1881
2850
|
marketIndex,
|
|
1882
2851
|
t.price || new BN(0), // price
|
|
1883
2852
|
BASE_PRECISION, // quantity
|
|
@@ -1905,9 +2874,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1905
2874
|
)}, price: ${ask.order?.price.toString()}, quantity: ${ask.order?.baseAssetAmountFilled.toString()}/${ask.order?.baseAssetAmount.toString()}`
|
|
1906
2875
|
);
|
|
1907
2876
|
|
|
1908
|
-
expect(ask.order?.orderId
|
|
1909
|
-
expectedTestCase[countAsks].orderId?.toNumber()
|
|
1910
|
-
);
|
|
2877
|
+
expect(ask.order?.orderId).to.equal(expectedTestCase[countAsks].orderId);
|
|
1911
2878
|
expect(ask.order?.price.toNumber()).to.equal(
|
|
1912
2879
|
expectedTestCase[countAsks].price?.toNumber()
|
|
1913
2880
|
);
|
|
@@ -1934,7 +2901,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1934
2901
|
hasSufficientNumberOfDataPoints: true,
|
|
1935
2902
|
};
|
|
1936
2903
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1937
|
-
const marketIndex =
|
|
2904
|
+
const marketIndex = 0;
|
|
1938
2905
|
|
|
1939
2906
|
// 3 mkt buys
|
|
1940
2907
|
for (let i = 0; i < 3; i++) {
|
|
@@ -1943,7 +2910,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1943
2910
|
Keypair.generate().publicKey,
|
|
1944
2911
|
OrderType.MARKET,
|
|
1945
2912
|
MarketType.SPOT,
|
|
1946
|
-
|
|
2913
|
+
i + 1,
|
|
1947
2914
|
marketIndex,
|
|
1948
2915
|
new BN(0),
|
|
1949
2916
|
BASE_PRECISION,
|
|
@@ -1960,7 +2927,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1960
2927
|
Keypair.generate().publicKey,
|
|
1961
2928
|
OrderType.MARKET,
|
|
1962
2929
|
MarketType.SPOT,
|
|
1963
|
-
|
|
2930
|
+
i + 1,
|
|
1964
2931
|
marketIndex,
|
|
1965
2932
|
new BN(0),
|
|
1966
2933
|
BASE_PRECISION,
|
|
@@ -1986,7 +2953,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1986
2953
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
1987
2954
|
expect(getVariant(ask.order?.orderType)).to.equal('market');
|
|
1988
2955
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
1989
|
-
expect(ask.order?.orderId
|
|
2956
|
+
expect(ask.order?.orderId).to.equal(asks);
|
|
1990
2957
|
}
|
|
1991
2958
|
}
|
|
1992
2959
|
expect(asks).to.equal(3);
|
|
@@ -2003,7 +2970,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2003
2970
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
2004
2971
|
expect(getVariant(bid.order?.orderType)).to.equal('market');
|
|
2005
2972
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
2006
|
-
expect(bid.order?.orderId
|
|
2973
|
+
expect(bid.order?.orderId).to.equal(bids + 1);
|
|
2007
2974
|
bids++;
|
|
2008
2975
|
}
|
|
2009
2976
|
expect(bids).to.equal(3); // 3 orders
|
|
@@ -2020,13 +2987,13 @@ describe('DLOB Spot Tests', () => {
|
|
|
2020
2987
|
hasSufficientNumberOfDataPoints: true,
|
|
2021
2988
|
};
|
|
2022
2989
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2023
|
-
const marketIndex =
|
|
2990
|
+
const marketIndex = 0;
|
|
2024
2991
|
insertOrderToDLOB(
|
|
2025
2992
|
dlob,
|
|
2026
2993
|
Keypair.generate().publicKey,
|
|
2027
2994
|
OrderType.LIMIT,
|
|
2028
2995
|
MarketType.SPOT,
|
|
2029
|
-
|
|
2996
|
+
3, // orderId
|
|
2030
2997
|
marketIndex,
|
|
2031
2998
|
new BN(50),
|
|
2032
2999
|
BASE_PRECISION,
|
|
@@ -2040,7 +3007,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2040
3007
|
Keypair.generate().publicKey,
|
|
2041
3008
|
OrderType.LIMIT,
|
|
2042
3009
|
MarketType.SPOT,
|
|
2043
|
-
|
|
3010
|
+
2, // orderId
|
|
2044
3011
|
marketIndex,
|
|
2045
3012
|
new BN(60),
|
|
2046
3013
|
BASE_PRECISION,
|
|
@@ -2054,7 +3021,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2054
3021
|
Keypair.generate().publicKey,
|
|
2055
3022
|
OrderType.LIMIT,
|
|
2056
3023
|
MarketType.SPOT,
|
|
2057
|
-
|
|
3024
|
+
1, // orderId
|
|
2058
3025
|
marketIndex,
|
|
2059
3026
|
new BN(70),
|
|
2060
3027
|
BASE_PRECISION,
|
|
@@ -2068,7 +3035,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2068
3035
|
Keypair.generate().publicKey,
|
|
2069
3036
|
OrderType.LIMIT,
|
|
2070
3037
|
MarketType.SPOT,
|
|
2071
|
-
|
|
3038
|
+
1, // orderId
|
|
2072
3039
|
marketIndex,
|
|
2073
3040
|
new BN(120),
|
|
2074
3041
|
BASE_PRECISION,
|
|
@@ -2082,7 +3049,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2082
3049
|
Keypair.generate().publicKey,
|
|
2083
3050
|
OrderType.LIMIT,
|
|
2084
3051
|
MarketType.SPOT,
|
|
2085
|
-
|
|
3052
|
+
2, // orderId
|
|
2086
3053
|
marketIndex,
|
|
2087
3054
|
new BN(130),
|
|
2088
3055
|
BASE_PRECISION,
|
|
@@ -2096,7 +3063,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2096
3063
|
Keypair.generate().publicKey,
|
|
2097
3064
|
OrderType.LIMIT,
|
|
2098
3065
|
MarketType.SPOT,
|
|
2099
|
-
|
|
3066
|
+
3, // orderId
|
|
2100
3067
|
marketIndex,
|
|
2101
3068
|
new BN(140),
|
|
2102
3069
|
BASE_PRECISION,
|
|
@@ -2122,7 +3089,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2122
3089
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
2123
3090
|
expect(getVariant(ask.order?.orderType)).to.equal('limit');
|
|
2124
3091
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
2125
|
-
expect(ask.order?.orderId
|
|
3092
|
+
expect(ask.order?.orderId).to.equal(asks + 1);
|
|
2126
3093
|
expect(ask.order?.price.gt(vAsk)).to.equal(true);
|
|
2127
3094
|
asks++;
|
|
2128
3095
|
}
|
|
@@ -2145,7 +3112,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2145
3112
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
2146
3113
|
expect(getVariant(bid.order?.orderType)).to.equal('limit');
|
|
2147
3114
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
2148
|
-
expect(bid.order?.orderId
|
|
3115
|
+
expect(bid.order?.orderId).to.equal(bids + 1);
|
|
2149
3116
|
expect(bid.order?.price.lt(vBid)).to.equal(true);
|
|
2150
3117
|
bids++;
|
|
2151
3118
|
}
|
|
@@ -2156,7 +3123,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2156
3123
|
const vAsk = new BN(15);
|
|
2157
3124
|
const vBid = new BN(10);
|
|
2158
3125
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2159
|
-
const marketIndex =
|
|
3126
|
+
const marketIndex = 0;
|
|
2160
3127
|
|
|
2161
3128
|
// insert some limit buys above vamm bid, below ask
|
|
2162
3129
|
insertOrderToDLOB(
|
|
@@ -2164,7 +3131,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2164
3131
|
Keypair.generate().publicKey,
|
|
2165
3132
|
OrderType.LIMIT,
|
|
2166
3133
|
MarketType.SPOT,
|
|
2167
|
-
|
|
3134
|
+
1, // orderId
|
|
2168
3135
|
marketIndex,
|
|
2169
3136
|
new BN(11), // price
|
|
2170
3137
|
BASE_PRECISION, // quantity
|
|
@@ -2177,7 +3144,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2177
3144
|
Keypair.generate().publicKey,
|
|
2178
3145
|
OrderType.LIMIT,
|
|
2179
3146
|
MarketType.SPOT,
|
|
2180
|
-
|
|
3147
|
+
2, // orderId
|
|
2181
3148
|
marketIndex,
|
|
2182
3149
|
new BN(12), // price
|
|
2183
3150
|
BASE_PRECISION, // quantity
|
|
@@ -2190,7 +3157,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2190
3157
|
Keypair.generate().publicKey,
|
|
2191
3158
|
OrderType.LIMIT,
|
|
2192
3159
|
MarketType.SPOT,
|
|
2193
|
-
|
|
3160
|
+
3, // orderId
|
|
2194
3161
|
marketIndex,
|
|
2195
3162
|
new BN(13), // price
|
|
2196
3163
|
BASE_PRECISION, // quantity
|
|
@@ -2202,8 +3169,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2202
3169
|
// should have no crossing orders
|
|
2203
3170
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2204
3171
|
marketIndex,
|
|
2205
|
-
vBid,
|
|
2206
|
-
vAsk,
|
|
2207
3172
|
12, // auction over
|
|
2208
3173
|
MarketType.SPOT,
|
|
2209
3174
|
{
|
|
@@ -2221,7 +3186,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2221
3186
|
Keypair.generate().publicKey,
|
|
2222
3187
|
OrderType.MARKET,
|
|
2223
3188
|
MarketType.SPOT,
|
|
2224
|
-
|
|
3189
|
+
4, // orderId
|
|
2225
3190
|
marketIndex,
|
|
2226
3191
|
new BN(12), // price
|
|
2227
3192
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -2234,7 +3199,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2234
3199
|
Keypair.generate().publicKey,
|
|
2235
3200
|
OrderType.MARKET,
|
|
2236
3201
|
MarketType.SPOT,
|
|
2237
|
-
|
|
3202
|
+
5, // orderId
|
|
2238
3203
|
marketIndex,
|
|
2239
3204
|
new BN(12), // price
|
|
2240
3205
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -2245,8 +3210,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2245
3210
|
|
|
2246
3211
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2247
3212
|
marketIndex,
|
|
2248
|
-
vBid,
|
|
2249
|
-
vAsk,
|
|
2250
3213
|
12, // auction over
|
|
2251
3214
|
MarketType.SPOT,
|
|
2252
3215
|
{
|
|
@@ -2264,23 +3227,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2264
3227
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
2265
3228
|
|
|
2266
3229
|
// first taker should fill with best maker
|
|
2267
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
2268
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
2269
|
-
3
|
|
2270
|
-
);
|
|
3230
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
3231
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
2271
3232
|
|
|
2272
3233
|
// second taker should fill with second best maker
|
|
2273
|
-
expect(nodesToFillAfter[1].node.order?.orderId
|
|
2274
|
-
expect(nodesToFillAfter[1].makerNode?.order?.orderId
|
|
2275
|
-
2
|
|
2276
|
-
);
|
|
3234
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
3235
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
2277
3236
|
});
|
|
2278
3237
|
|
|
2279
3238
|
it('Test one market order fills two limit orders', () => {
|
|
2280
3239
|
const vAsk = new BN(15);
|
|
2281
3240
|
const vBid = new BN(10);
|
|
2282
3241
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2283
|
-
const marketIndex =
|
|
3242
|
+
const marketIndex = 0;
|
|
2284
3243
|
|
|
2285
3244
|
// insert some limit sells below vAMM ask, above bid
|
|
2286
3245
|
insertOrderToDLOB(
|
|
@@ -2288,7 +3247,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2288
3247
|
Keypair.generate().publicKey,
|
|
2289
3248
|
OrderType.LIMIT,
|
|
2290
3249
|
MarketType.SPOT,
|
|
2291
|
-
|
|
3250
|
+
1, // orderId
|
|
2292
3251
|
marketIndex,
|
|
2293
3252
|
new BN(14), // price
|
|
2294
3253
|
BASE_PRECISION, // quantity
|
|
@@ -2301,7 +3260,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2301
3260
|
Keypair.generate().publicKey,
|
|
2302
3261
|
OrderType.LIMIT,
|
|
2303
3262
|
MarketType.SPOT,
|
|
2304
|
-
|
|
3263
|
+
2, // orderId
|
|
2305
3264
|
marketIndex,
|
|
2306
3265
|
new BN(12), // price
|
|
2307
3266
|
BASE_PRECISION, // quantity
|
|
@@ -2314,7 +3273,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2314
3273
|
Keypair.generate().publicKey,
|
|
2315
3274
|
OrderType.LIMIT,
|
|
2316
3275
|
MarketType.SPOT,
|
|
2317
|
-
|
|
3276
|
+
3, // orderId
|
|
2318
3277
|
marketIndex,
|
|
2319
3278
|
new BN(11), // price
|
|
2320
3279
|
BASE_PRECISION, // quantity
|
|
@@ -2326,8 +3285,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2326
3285
|
// should have no crossing orders
|
|
2327
3286
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2328
3287
|
marketIndex,
|
|
2329
|
-
vBid,
|
|
2330
|
-
vAsk,
|
|
2331
3288
|
12, // auction over
|
|
2332
3289
|
MarketType.SPOT,
|
|
2333
3290
|
{
|
|
@@ -2345,7 +3302,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2345
3302
|
Keypair.generate().publicKey,
|
|
2346
3303
|
OrderType.MARKET,
|
|
2347
3304
|
MarketType.SPOT,
|
|
2348
|
-
|
|
3305
|
+
4, // orderId
|
|
2349
3306
|
marketIndex,
|
|
2350
3307
|
new BN(12), // price
|
|
2351
3308
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -2356,8 +3313,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2356
3313
|
|
|
2357
3314
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2358
3315
|
marketIndex,
|
|
2359
|
-
vBid,
|
|
2360
|
-
vAsk,
|
|
2361
3316
|
12, // auction over
|
|
2362
3317
|
MarketType.SPOT,
|
|
2363
3318
|
{
|
|
@@ -2375,23 +3330,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2375
3330
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
2376
3331
|
|
|
2377
3332
|
// taker should fill completely with best maker
|
|
2378
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
2379
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
2380
|
-
3
|
|
2381
|
-
);
|
|
3333
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
3334
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
2382
3335
|
|
|
2383
3336
|
// taker should fill completely with second best maker
|
|
2384
|
-
expect(nodesToFillAfter[1].node.order?.orderId
|
|
2385
|
-
expect(nodesToFillAfter[1].makerNode?.order?.orderId
|
|
2386
|
-
2
|
|
2387
|
-
);
|
|
3337
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(4);
|
|
3338
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
2388
3339
|
});
|
|
2389
3340
|
|
|
2390
3341
|
it('Test two market orders to fill one limit order', () => {
|
|
2391
3342
|
const vAsk = new BN(15);
|
|
2392
3343
|
const vBid = new BN(8);
|
|
2393
3344
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2394
|
-
const marketIndex =
|
|
3345
|
+
const marketIndex = 0;
|
|
2395
3346
|
|
|
2396
3347
|
const slot = 12;
|
|
2397
3348
|
const oracle = {
|
|
@@ -2407,7 +3358,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2407
3358
|
Keypair.generate().publicKey,
|
|
2408
3359
|
OrderType.LIMIT,
|
|
2409
3360
|
MarketType.SPOT,
|
|
2410
|
-
|
|
3361
|
+
1, // orderId
|
|
2411
3362
|
marketIndex,
|
|
2412
3363
|
new BN(14), // price
|
|
2413
3364
|
BASE_PRECISION, // quantity
|
|
@@ -2420,7 +3371,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2420
3371
|
Keypair.generate().publicKey,
|
|
2421
3372
|
OrderType.LIMIT,
|
|
2422
3373
|
MarketType.SPOT,
|
|
2423
|
-
|
|
3374
|
+
2, // orderId
|
|
2424
3375
|
marketIndex,
|
|
2425
3376
|
new BN(13), // price
|
|
2426
3377
|
BASE_PRECISION, // quantity
|
|
@@ -2433,7 +3384,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2433
3384
|
Keypair.generate().publicKey,
|
|
2434
3385
|
OrderType.LIMIT,
|
|
2435
3386
|
MarketType.SPOT,
|
|
2436
|
-
|
|
3387
|
+
3, // orderId
|
|
2437
3388
|
marketIndex,
|
|
2438
3389
|
new BN(8), // price <-- best price
|
|
2439
3390
|
new BN(3).mul(BASE_PRECISION), // quantity
|
|
@@ -2445,8 +3396,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2445
3396
|
// should have no crossing orders
|
|
2446
3397
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2447
3398
|
marketIndex,
|
|
2448
|
-
vBid,
|
|
2449
|
-
vAsk,
|
|
2450
3399
|
12, // auction over
|
|
2451
3400
|
MarketType.SPOT,
|
|
2452
3401
|
oracle
|
|
@@ -2459,7 +3408,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2459
3408
|
Keypair.generate().publicKey,
|
|
2460
3409
|
OrderType.MARKET,
|
|
2461
3410
|
MarketType.SPOT,
|
|
2462
|
-
|
|
3411
|
+
4, // orderId
|
|
2463
3412
|
marketIndex,
|
|
2464
3413
|
new BN(0), // price
|
|
2465
3414
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -2472,7 +3421,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2472
3421
|
Keypair.generate().publicKey,
|
|
2473
3422
|
OrderType.MARKET,
|
|
2474
3423
|
MarketType.SPOT,
|
|
2475
|
-
|
|
3424
|
+
5, // orderId
|
|
2476
3425
|
marketIndex,
|
|
2477
3426
|
new BN(0), // price
|
|
2478
3427
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -2483,62 +3432,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2483
3432
|
|
|
2484
3433
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2485
3434
|
marketIndex,
|
|
2486
|
-
vBid,
|
|
2487
|
-
vAsk,
|
|
2488
3435
|
slot, // auction over
|
|
2489
3436
|
MarketType.SPOT,
|
|
2490
3437
|
oracle
|
|
2491
3438
|
);
|
|
2492
|
-
const mktNodes = dlob.
|
|
3439
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
2493
3440
|
marketIndex,
|
|
2494
3441
|
slot,
|
|
2495
3442
|
MarketType.SPOT
|
|
2496
3443
|
);
|
|
2497
3444
|
console.log(`market nodes: ${mktNodes.length}`);
|
|
2498
3445
|
|
|
2499
|
-
|
|
2500
|
-
marketIndex,
|
|
2501
|
-
vAsk,
|
|
2502
|
-
slot,
|
|
2503
|
-
MarketType.SPOT,
|
|
2504
|
-
oracle
|
|
2505
|
-
);
|
|
2506
|
-
let aa = 0;
|
|
2507
|
-
for (const b of askNodes) {
|
|
2508
|
-
console.log(
|
|
2509
|
-
` . ask: ${b.order?.orderId.toString()}: p1: ${b.order?.price.toString()} p2: ${b.getPrice(
|
|
2510
|
-
oracle,
|
|
2511
|
-
slot
|
|
2512
|
-
)}, ${JSON.stringify(
|
|
2513
|
-
b.order?.orderType
|
|
2514
|
-
)} BAA: ${b.order?.baseAssetAmountFilled.toString()}/${b.order?.baseAssetAmount.toString()}`
|
|
2515
|
-
);
|
|
2516
|
-
aa++;
|
|
2517
|
-
}
|
|
2518
|
-
expect(aa).to.equal(3);
|
|
2519
|
-
|
|
2520
|
-
const bidNodes = dlob.getBids(
|
|
2521
|
-
marketIndex,
|
|
2522
|
-
vBid,
|
|
2523
|
-
slot,
|
|
2524
|
-
MarketType.SPOT,
|
|
2525
|
-
oracle
|
|
2526
|
-
);
|
|
2527
|
-
let bb = 0;
|
|
2528
|
-
for (const b of bidNodes) {
|
|
2529
|
-
console.log(
|
|
2530
|
-
` . bid: ${b.order?.orderId.toString()}: p1: ${b.order?.price.toString()} p2: ${b.getPrice(
|
|
2531
|
-
oracle,
|
|
2532
|
-
slot
|
|
2533
|
-
)}, ${JSON.stringify(
|
|
2534
|
-
b.order?.orderType
|
|
2535
|
-
)} BAA: ${b.order?.baseAssetAmountFilled.toString()}/${b.order?.baseAssetAmount.toString()}`
|
|
2536
|
-
);
|
|
2537
|
-
bb++;
|
|
2538
|
-
}
|
|
2539
|
-
expect(bb).to.equal(2);
|
|
3446
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2540
3447
|
|
|
2541
|
-
console.log(`bids nodes: ${bb}`);
|
|
2542
3448
|
for (const n of nodesToFillAfter) {
|
|
2543
3449
|
console.log(
|
|
2544
3450
|
`cross found: taker orderId: ${n.node.order?.orderId.toString()}: BAA: ${n.node.order?.baseAssetAmountFilled.toString()}/${n.node.order?.baseAssetAmount.toString()}, maker orderId: ${n.makerNode?.order?.orderId.toString()}: BAA: ${n.makerNode?.order?.baseAssetAmountFilled.toString()}/${n.makerNode?.order?.baseAssetAmount.toString()}`
|
|
@@ -2547,23 +3453,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2547
3453
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
2548
3454
|
|
|
2549
3455
|
// taker should fill completely with best maker
|
|
2550
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
2551
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
2552
|
-
3
|
|
2553
|
-
);
|
|
3456
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
3457
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
2554
3458
|
|
|
2555
3459
|
// taker should fill completely with second best maker
|
|
2556
|
-
expect(nodesToFillAfter[1].node.order?.orderId
|
|
2557
|
-
expect(nodesToFillAfter[1].makerNode?.order?.orderId
|
|
2558
|
-
3
|
|
2559
|
-
);
|
|
3460
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
3461
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
|
|
2560
3462
|
});
|
|
2561
3463
|
|
|
2562
3464
|
it('Test trigger orders', () => {
|
|
2563
3465
|
const vAsk = new BN(15);
|
|
2564
3466
|
const vBid = new BN(8);
|
|
2565
3467
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2566
|
-
const marketIndex =
|
|
3468
|
+
const marketIndex = 0;
|
|
2567
3469
|
|
|
2568
3470
|
const slot = 20;
|
|
2569
3471
|
const oracle = {
|
|
@@ -2582,7 +3484,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2582
3484
|
Keypair.generate().publicKey,
|
|
2583
3485
|
OrderType.TRIGGER_LIMIT,
|
|
2584
3486
|
MarketType.SPOT,
|
|
2585
|
-
|
|
3487
|
+
1, //orderId
|
|
2586
3488
|
marketIndex, // marketIndex
|
|
2587
3489
|
vBid, // price
|
|
2588
3490
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2598,7 +3500,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2598
3500
|
Keypair.generate().publicKey,
|
|
2599
3501
|
OrderType.TRIGGER_LIMIT,
|
|
2600
3502
|
MarketType.SPOT,
|
|
2601
|
-
|
|
3503
|
+
2, //orderId
|
|
2602
3504
|
marketIndex, // marketIndex
|
|
2603
3505
|
vBid, // price
|
|
2604
3506
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2614,7 +3516,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2614
3516
|
Keypair.generate().publicKey,
|
|
2615
3517
|
OrderType.TRIGGER_MARKET,
|
|
2616
3518
|
MarketType.SPOT,
|
|
2617
|
-
|
|
3519
|
+
3, //orderId
|
|
2618
3520
|
marketIndex, // marketIndex
|
|
2619
3521
|
vAsk, // price
|
|
2620
3522
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2630,7 +3532,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2630
3532
|
Keypair.generate().publicKey,
|
|
2631
3533
|
OrderType.TRIGGER_MARKET,
|
|
2632
3534
|
MarketType.SPOT,
|
|
2633
|
-
|
|
3535
|
+
4, //orderId
|
|
2634
3536
|
marketIndex, // marketIndex
|
|
2635
3537
|
vBid, // price
|
|
2636
3538
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2646,7 +3548,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2646
3548
|
Keypair.generate().publicKey,
|
|
2647
3549
|
OrderType.TRIGGER_LIMIT,
|
|
2648
3550
|
MarketType.SPOT,
|
|
2649
|
-
|
|
3551
|
+
5, //orderId
|
|
2650
3552
|
marketIndex, // marketIndex
|
|
2651
3553
|
vBid, // price
|
|
2652
3554
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2662,7 +3564,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2662
3564
|
Keypair.generate().publicKey,
|
|
2663
3565
|
OrderType.TRIGGER_LIMIT,
|
|
2664
3566
|
MarketType.SPOT,
|
|
2665
|
-
|
|
3567
|
+
6, //orderId
|
|
2666
3568
|
marketIndex, // marketIndex
|
|
2667
3569
|
vBid, // price
|
|
2668
3570
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2678,7 +3580,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2678
3580
|
Keypair.generate().publicKey,
|
|
2679
3581
|
OrderType.TRIGGER_MARKET,
|
|
2680
3582
|
MarketType.SPOT,
|
|
2681
|
-
|
|
3583
|
+
7, //orderId
|
|
2682
3584
|
marketIndex, // marketIndex
|
|
2683
3585
|
vBid, // price
|
|
2684
3586
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2694,7 +3596,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2694
3596
|
Keypair.generate().publicKey,
|
|
2695
3597
|
OrderType.TRIGGER_MARKET,
|
|
2696
3598
|
MarketType.SPOT,
|
|
2697
|
-
|
|
3599
|
+
8, //orderId
|
|
2698
3600
|
marketIndex, // marketIndex
|
|
2699
3601
|
vBid, // price
|
|
2700
3602
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2711,7 +3613,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2711
3613
|
Keypair.generate().publicKey,
|
|
2712
3614
|
OrderType.TRIGGER_MARKET,
|
|
2713
3615
|
MarketType.SPOT,
|
|
2714
|
-
|
|
3616
|
+
9, //orderId
|
|
2715
3617
|
marketIndex, // marketIndex
|
|
2716
3618
|
vBid, // price
|
|
2717
3619
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2727,7 +3629,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2727
3629
|
Keypair.generate().publicKey,
|
|
2728
3630
|
OrderType.TRIGGER_MARKET,
|
|
2729
3631
|
MarketType.SPOT,
|
|
2730
|
-
|
|
3632
|
+
10, //orderId
|
|
2731
3633
|
marketIndex, // marketIndex
|
|
2732
3634
|
vBid, // price
|
|
2733
3635
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2743,7 +3645,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2743
3645
|
Keypair.generate().publicKey,
|
|
2744
3646
|
OrderType.TRIGGER_MARKET,
|
|
2745
3647
|
MarketType.SPOT,
|
|
2746
|
-
|
|
3648
|
+
11, //orderId
|
|
2747
3649
|
marketIndex, // marketIndex
|
|
2748
3650
|
vBid, // price
|
|
2749
3651
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2759,7 +3661,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2759
3661
|
Keypair.generate().publicKey,
|
|
2760
3662
|
OrderType.TRIGGER_MARKET,
|
|
2761
3663
|
MarketType.SPOT,
|
|
2762
|
-
|
|
3664
|
+
12, //orderId
|
|
2763
3665
|
marketIndex, // marketIndex
|
|
2764
3666
|
vBid, // price
|
|
2765
3667
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2778,8 +3680,8 @@ describe('DLOB Spot Tests', () => {
|
|
|
2778
3680
|
);
|
|
2779
3681
|
console.log(`nodesToTriggeR: ${nodesToTrigger.length}`);
|
|
2780
3682
|
for (const [idx, n] of nodesToTrigger.entries()) {
|
|
2781
|
-
expect(n.node.order?.orderId
|
|
2782
|
-
console.log(`nodeToTrigger: ${n.node.order?.orderId
|
|
3683
|
+
expect(n.node.order?.orderId).to.equal(orderIdsToTrigger[idx]);
|
|
3684
|
+
console.log(`nodeToTrigger: ${n.node.order?.orderId}`);
|
|
2783
3685
|
}
|
|
2784
3686
|
});
|
|
2785
3687
|
|
|
@@ -2787,7 +3689,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2787
3689
|
const vAsk = new BN(15);
|
|
2788
3690
|
const vBid = new BN(8);
|
|
2789
3691
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2790
|
-
const marketIndex =
|
|
3692
|
+
const marketIndex = 0;
|
|
2791
3693
|
|
|
2792
3694
|
const slot = 20;
|
|
2793
3695
|
const timeInForce = 30;
|
|
@@ -2798,7 +3700,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2798
3700
|
Keypair.generate().publicKey,
|
|
2799
3701
|
OrderType.MARKET,
|
|
2800
3702
|
MarketType.SPOT,
|
|
2801
|
-
|
|
3703
|
+
255, // orderId
|
|
2802
3704
|
marketIndex,
|
|
2803
3705
|
new BN(2), // price, very low, don't cross vamm
|
|
2804
3706
|
BASE_PRECISION, // quantity
|
|
@@ -2813,7 +3715,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2813
3715
|
Keypair.generate().publicKey,
|
|
2814
3716
|
OrderType.MARKET,
|
|
2815
3717
|
MarketType.SPOT,
|
|
2816
|
-
|
|
3718
|
+
2, // orderId
|
|
2817
3719
|
marketIndex,
|
|
2818
3720
|
new BN(30), // price, very high, don't cross vamm
|
|
2819
3721
|
BASE_PRECISION, // quantity
|
|
@@ -2842,7 +3744,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2842
3744
|
expect(nodesToFillBefore.length).to.equal(0);
|
|
2843
3745
|
|
|
2844
3746
|
// should get order to fill after timeInForce
|
|
2845
|
-
const slot1 = slot0 + timeInForce; // overshoots expiry
|
|
3747
|
+
const slot1 = slot0 + timeInForce * 2; // overshoots expiry
|
|
2846
3748
|
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2847
3749
|
marketIndex,
|
|
2848
3750
|
vBid,
|