@drift-labs/sdk 0.2.0-master.30 → 0.2.0-master.31
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 +6 -5
- package/lib/dlob/DLOB.js +130 -88
- package/lib/dlob/DLOBNode.d.ts +2 -0
- package/lib/dlob/DLOBNode.js +3 -0
- package/lib/dlob/NodeList.d.ts +1 -1
- package/lib/dlob/NodeList.js +5 -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 +117 -40
- package/lib/types.js +33 -3
- 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 +188 -103
- package/src/dlob/DLOBNode.ts +5 -0
- package/src/dlob/NodeList.ts +9 -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 +81 -40
- package/tests/bn/test.ts +12 -7
- package/tests/dlob/helpers.ts +56 -33
- package/tests/dlob/test.ts +1227 -404
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++;
|
|
@@ -192,7 +291,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
192
291
|
const vAsk = new BN(15);
|
|
193
292
|
const vBid = new BN(10);
|
|
194
293
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
195
|
-
const marketIndex =
|
|
294
|
+
const marketIndex = 0;
|
|
196
295
|
|
|
197
296
|
const slot = 12;
|
|
198
297
|
const oracle = {
|
|
@@ -203,41 +302,41 @@ describe('DLOB Perp Tests', () => {
|
|
|
203
302
|
};
|
|
204
303
|
const testCases = [
|
|
205
304
|
{
|
|
206
|
-
expectedIdx:
|
|
305
|
+
expectedIdx: 0,
|
|
207
306
|
isVamm: false,
|
|
208
|
-
orderId:
|
|
307
|
+
orderId: 5,
|
|
209
308
|
price: new BN(0),
|
|
210
309
|
direction: PositionDirection.LONG,
|
|
211
310
|
orderType: OrderType.MARKET,
|
|
212
311
|
},
|
|
213
312
|
{
|
|
214
|
-
expectedIdx:
|
|
313
|
+
expectedIdx: 1,
|
|
215
314
|
isVamm: false,
|
|
216
|
-
orderId:
|
|
315
|
+
orderId: 6,
|
|
217
316
|
price: new BN(0),
|
|
218
317
|
direction: PositionDirection.LONG,
|
|
219
318
|
orderType: OrderType.MARKET,
|
|
220
319
|
},
|
|
221
320
|
{
|
|
222
|
-
expectedIdx:
|
|
321
|
+
expectedIdx: 2,
|
|
223
322
|
isVamm: false,
|
|
224
|
-
orderId:
|
|
323
|
+
orderId: 7,
|
|
225
324
|
price: new BN(0),
|
|
226
325
|
direction: PositionDirection.LONG,
|
|
227
326
|
orderType: OrderType.MARKET,
|
|
228
327
|
},
|
|
229
328
|
{
|
|
230
|
-
expectedIdx:
|
|
329
|
+
expectedIdx: 3,
|
|
231
330
|
isVamm: false,
|
|
232
|
-
orderId:
|
|
331
|
+
orderId: 1,
|
|
233
332
|
price: new BN(12),
|
|
234
333
|
direction: PositionDirection.LONG,
|
|
235
334
|
orderType: OrderType.LIMIT,
|
|
236
335
|
},
|
|
237
336
|
{
|
|
238
|
-
expectedIdx:
|
|
337
|
+
expectedIdx: 4,
|
|
239
338
|
isVamm: false,
|
|
240
|
-
orderId:
|
|
339
|
+
orderId: 2,
|
|
241
340
|
price: new BN(11),
|
|
242
341
|
direction: PositionDirection.LONG,
|
|
243
342
|
orderType: OrderType.LIMIT,
|
|
@@ -245,13 +344,13 @@ describe('DLOB Perp Tests', () => {
|
|
|
245
344
|
{
|
|
246
345
|
expectedIdx: 7,
|
|
247
346
|
isVamm: false,
|
|
248
|
-
orderId:
|
|
347
|
+
orderId: 3,
|
|
249
348
|
price: new BN(8),
|
|
250
349
|
direction: PositionDirection.LONG,
|
|
251
350
|
orderType: OrderType.LIMIT,
|
|
252
351
|
},
|
|
253
352
|
{
|
|
254
|
-
expectedIdx:
|
|
353
|
+
expectedIdx: 5,
|
|
255
354
|
isVamm: true,
|
|
256
355
|
orderId: undefined,
|
|
257
356
|
price: undefined,
|
|
@@ -261,7 +360,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
261
360
|
{
|
|
262
361
|
expectedIdx: 6,
|
|
263
362
|
isVamm: false,
|
|
264
|
-
orderId:
|
|
363
|
+
orderId: 4,
|
|
265
364
|
price: new BN(9),
|
|
266
365
|
direction: PositionDirection.LONG,
|
|
267
366
|
orderType: OrderType.LIMIT,
|
|
@@ -277,7 +376,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
277
376
|
Keypair.generate().publicKey,
|
|
278
377
|
t.orderType || OrderType.LIMIT,
|
|
279
378
|
MarketType.PERP,
|
|
280
|
-
t.orderId ||
|
|
379
|
+
t.orderId || 0, // orderId
|
|
281
380
|
marketIndex,
|
|
282
381
|
t.price || new BN(0), // price
|
|
283
382
|
BASE_PRECISION, // quantity
|
|
@@ -294,28 +393,26 @@ describe('DLOB Perp Tests', () => {
|
|
|
294
393
|
const bids = dlob.getBids(marketIndex, vBid, slot, MarketType.PERP, oracle);
|
|
295
394
|
|
|
296
395
|
console.log('The Book Bids:');
|
|
396
|
+
const gotBids = [];
|
|
297
397
|
let countBids = 0;
|
|
298
398
|
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()}`
|
|
399
|
+
gotBids.push(bid);
|
|
400
|
+
printOrderNode(bid, oracle, slot);
|
|
401
|
+
}
|
|
402
|
+
for (const bid of gotBids) {
|
|
403
|
+
expect(bid.isVammNode(), `expected vAMM node`).to.be.eq(
|
|
404
|
+
expectedTestCase[countBids].isVamm
|
|
306
405
|
);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
expect(bid.order?.orderId.toNumber()).to.equal(
|
|
310
|
-
expectedTestCase[countBids].orderId?.toNumber()
|
|
406
|
+
expect(bid.order?.orderId, `expected orderId`).to.equal(
|
|
407
|
+
expectedTestCase[countBids].orderId
|
|
311
408
|
);
|
|
312
|
-
expect(bid.order?.price.toNumber()).to.equal(
|
|
409
|
+
expect(bid.order?.price.toNumber(), `expected price`).to.equal(
|
|
313
410
|
expectedTestCase[countBids].price?.toNumber()
|
|
314
411
|
);
|
|
315
|
-
expect(bid.order?.direction).to.equal(
|
|
412
|
+
expect(bid.order?.direction, `expected order direction`).to.equal(
|
|
316
413
|
expectedTestCase[countBids].direction
|
|
317
414
|
);
|
|
318
|
-
expect(bid.order?.orderType).to.equal(
|
|
415
|
+
expect(bid.order?.orderType, `expected order type`).to.equal(
|
|
319
416
|
expectedTestCase[countBids].orderType
|
|
320
417
|
);
|
|
321
418
|
countBids++;
|
|
@@ -328,8 +425,8 @@ describe('DLOB Perp Tests', () => {
|
|
|
328
425
|
const vAsk = new BN(15);
|
|
329
426
|
const vBid = new BN(10);
|
|
330
427
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
331
|
-
const marketIndex0 =
|
|
332
|
-
const marketIndex1 =
|
|
428
|
+
const marketIndex0 = 0;
|
|
429
|
+
const marketIndex1 = 1;
|
|
333
430
|
|
|
334
431
|
const slot = 12;
|
|
335
432
|
const oracle = {
|
|
@@ -342,7 +439,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
342
439
|
{
|
|
343
440
|
expectedIdx: 3,
|
|
344
441
|
isVamm: false,
|
|
345
|
-
orderId:
|
|
442
|
+
orderId: 5,
|
|
346
443
|
price: new BN(0),
|
|
347
444
|
direction: PositionDirection.LONG,
|
|
348
445
|
orderType: OrderType.MARKET,
|
|
@@ -351,7 +448,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
351
448
|
{
|
|
352
449
|
expectedIdx: 4,
|
|
353
450
|
isVamm: false,
|
|
354
|
-
orderId:
|
|
451
|
+
orderId: 6,
|
|
355
452
|
price: new BN(0),
|
|
356
453
|
direction: PositionDirection.LONG,
|
|
357
454
|
orderType: OrderType.MARKET,
|
|
@@ -360,7 +457,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
360
457
|
{
|
|
361
458
|
expectedIdx: 5,
|
|
362
459
|
isVamm: false,
|
|
363
|
-
orderId:
|
|
460
|
+
orderId: 7,
|
|
364
461
|
price: new BN(0),
|
|
365
462
|
direction: PositionDirection.LONG,
|
|
366
463
|
orderType: OrderType.MARKET,
|
|
@@ -369,7 +466,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
369
466
|
{
|
|
370
467
|
expectedIdx: 0,
|
|
371
468
|
isVamm: false,
|
|
372
|
-
orderId:
|
|
469
|
+
orderId: 1,
|
|
373
470
|
price: new BN(12),
|
|
374
471
|
direction: PositionDirection.LONG,
|
|
375
472
|
orderType: OrderType.LIMIT,
|
|
@@ -378,7 +475,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
378
475
|
{
|
|
379
476
|
expectedIdx: 1,
|
|
380
477
|
isVamm: false,
|
|
381
|
-
orderId:
|
|
478
|
+
orderId: 2,
|
|
382
479
|
price: new BN(11),
|
|
383
480
|
direction: PositionDirection.LONG,
|
|
384
481
|
orderType: OrderType.LIMIT,
|
|
@@ -387,7 +484,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
387
484
|
{
|
|
388
485
|
expectedIdx: 7,
|
|
389
486
|
isVamm: false,
|
|
390
|
-
orderId:
|
|
487
|
+
orderId: 3,
|
|
391
488
|
price: new BN(8),
|
|
392
489
|
direction: PositionDirection.LONG,
|
|
393
490
|
orderType: OrderType.LIMIT,
|
|
@@ -396,7 +493,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
396
493
|
{
|
|
397
494
|
expectedIdx: 6,
|
|
398
495
|
isVamm: false,
|
|
399
|
-
orderId:
|
|
496
|
+
orderId: 4,
|
|
400
497
|
price: new BN(9),
|
|
401
498
|
direction: PositionDirection.LONG,
|
|
402
499
|
orderType: OrderType.LIMIT,
|
|
@@ -413,7 +510,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
413
510
|
Keypair.generate().publicKey,
|
|
414
511
|
t.orderType || OrderType.LIMIT,
|
|
415
512
|
MarketType.PERP,
|
|
416
|
-
t.orderId ||
|
|
513
|
+
t.orderId || 0, // orderId
|
|
417
514
|
t.marketIndex,
|
|
418
515
|
t.price || new BN(0), // price
|
|
419
516
|
BASE_PRECISION, // quantity
|
|
@@ -471,7 +568,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
471
568
|
const vAsk = new BN(15);
|
|
472
569
|
const vBid = new BN(10);
|
|
473
570
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
474
|
-
const marketIndex =
|
|
571
|
+
const marketIndex = 0;
|
|
475
572
|
|
|
476
573
|
const slot = 12;
|
|
477
574
|
const oracle = {
|
|
@@ -484,7 +581,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
484
581
|
{
|
|
485
582
|
expectedIdx: 0,
|
|
486
583
|
isVamm: false,
|
|
487
|
-
orderId:
|
|
584
|
+
orderId: 3,
|
|
488
585
|
price: new BN(0),
|
|
489
586
|
direction: PositionDirection.SHORT,
|
|
490
587
|
orderType: OrderType.MARKET,
|
|
@@ -492,7 +589,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
492
589
|
{
|
|
493
590
|
expectedIdx: 1,
|
|
494
591
|
isVamm: false,
|
|
495
|
-
orderId:
|
|
592
|
+
orderId: 4,
|
|
496
593
|
price: new BN(0),
|
|
497
594
|
direction: PositionDirection.SHORT,
|
|
498
595
|
orderType: OrderType.MARKET,
|
|
@@ -500,7 +597,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
500
597
|
{
|
|
501
598
|
expectedIdx: 2,
|
|
502
599
|
isVamm: false,
|
|
503
|
-
orderId:
|
|
600
|
+
orderId: 5,
|
|
504
601
|
price: new BN(0),
|
|
505
602
|
direction: PositionDirection.SHORT,
|
|
506
603
|
orderType: OrderType.MARKET,
|
|
@@ -508,7 +605,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
508
605
|
{
|
|
509
606
|
expectedIdx: 3,
|
|
510
607
|
isVamm: false,
|
|
511
|
-
orderId:
|
|
608
|
+
orderId: 1,
|
|
512
609
|
price: new BN(13),
|
|
513
610
|
direction: PositionDirection.SHORT,
|
|
514
611
|
orderType: OrderType.LIMIT,
|
|
@@ -516,7 +613,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
516
613
|
{
|
|
517
614
|
expectedIdx: 6,
|
|
518
615
|
isVamm: false,
|
|
519
|
-
orderId:
|
|
616
|
+
orderId: 6,
|
|
520
617
|
price: new BN(16),
|
|
521
618
|
direction: PositionDirection.SHORT,
|
|
522
619
|
orderType: OrderType.LIMIT,
|
|
@@ -532,7 +629,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
532
629
|
{
|
|
533
630
|
expectedIdx: 7,
|
|
534
631
|
isVamm: false,
|
|
535
|
-
orderId:
|
|
632
|
+
orderId: 7,
|
|
536
633
|
price: new BN(17),
|
|
537
634
|
direction: PositionDirection.SHORT,
|
|
538
635
|
orderType: OrderType.LIMIT,
|
|
@@ -540,7 +637,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
540
637
|
{
|
|
541
638
|
expectedIdx: 4,
|
|
542
639
|
isVamm: false,
|
|
543
|
-
orderId:
|
|
640
|
+
orderId: 2,
|
|
544
641
|
price: new BN(14),
|
|
545
642
|
direction: PositionDirection.SHORT,
|
|
546
643
|
orderType: OrderType.LIMIT,
|
|
@@ -556,7 +653,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
556
653
|
Keypair.generate().publicKey,
|
|
557
654
|
t.orderType || OrderType.LIMIT,
|
|
558
655
|
MarketType.PERP,
|
|
559
|
-
t.orderId ||
|
|
656
|
+
t.orderId || 0, // orderId
|
|
560
657
|
marketIndex,
|
|
561
658
|
t.price || new BN(0), // price
|
|
562
659
|
BASE_PRECISION, // quantity
|
|
@@ -585,9 +682,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
585
682
|
);
|
|
586
683
|
|
|
587
684
|
expect(ask.isVammNode()).to.be.eq(expectedTestCase[countAsks].isVamm);
|
|
588
|
-
expect(ask.order?.orderId
|
|
589
|
-
expectedTestCase[countAsks].orderId?.toNumber()
|
|
590
|
-
);
|
|
685
|
+
expect(ask.order?.orderId).to.equal(expectedTestCase[countAsks].orderId);
|
|
591
686
|
expect(ask.order?.price.toNumber()).to.equal(
|
|
592
687
|
expectedTestCase[countAsks].price?.toNumber()
|
|
593
688
|
);
|
|
@@ -607,7 +702,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
607
702
|
const vAsk = new BN(11);
|
|
608
703
|
const vBid = new BN(10);
|
|
609
704
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
610
|
-
const marketIndex =
|
|
705
|
+
const marketIndex = 0;
|
|
611
706
|
const oracle = {
|
|
612
707
|
price: vBid.add(vAsk).div(new BN(2)),
|
|
613
708
|
slot: new BN(12),
|
|
@@ -622,7 +717,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
622
717
|
Keypair.generate().publicKey,
|
|
623
718
|
OrderType.MARKET,
|
|
624
719
|
MarketType.PERP,
|
|
625
|
-
|
|
720
|
+
i + 1,
|
|
626
721
|
marketIndex,
|
|
627
722
|
new BN(0),
|
|
628
723
|
BASE_PRECISION,
|
|
@@ -639,7 +734,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
639
734
|
Keypair.generate().publicKey,
|
|
640
735
|
OrderType.MARKET,
|
|
641
736
|
MarketType.PERP,
|
|
642
|
-
|
|
737
|
+
i + 1,
|
|
643
738
|
marketIndex,
|
|
644
739
|
new BN(0),
|
|
645
740
|
BASE_PRECISION,
|
|
@@ -665,7 +760,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
665
760
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
666
761
|
expect(getVariant(ask.order?.orderType)).to.equal('market');
|
|
667
762
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
668
|
-
expect(ask.order?.orderId
|
|
763
|
+
expect(ask.order?.orderId).to.equal(asks);
|
|
669
764
|
}
|
|
670
765
|
}
|
|
671
766
|
expect(asks).to.equal(4); // vamm ask + 3 orders
|
|
@@ -686,7 +781,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
686
781
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
687
782
|
expect(getVariant(bid.order?.orderType)).to.equal('market');
|
|
688
783
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
689
|
-
expect(bid.order?.orderId
|
|
784
|
+
expect(bid.order?.orderId).to.equal(bids);
|
|
690
785
|
}
|
|
691
786
|
bids++;
|
|
692
787
|
}
|
|
@@ -704,13 +799,13 @@ describe('DLOB Perp Tests', () => {
|
|
|
704
799
|
hasSufficientNumberOfDataPoints: true,
|
|
705
800
|
};
|
|
706
801
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
707
|
-
const marketIndex =
|
|
802
|
+
const marketIndex = 0;
|
|
708
803
|
insertOrderToDLOB(
|
|
709
804
|
dlob,
|
|
710
805
|
Keypair.generate().publicKey,
|
|
711
806
|
OrderType.LIMIT,
|
|
712
807
|
MarketType.PERP,
|
|
713
|
-
|
|
808
|
+
3, // orderId
|
|
714
809
|
marketIndex,
|
|
715
810
|
new BN(5),
|
|
716
811
|
BASE_PRECISION,
|
|
@@ -724,7 +819,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
724
819
|
Keypair.generate().publicKey,
|
|
725
820
|
OrderType.LIMIT,
|
|
726
821
|
MarketType.PERP,
|
|
727
|
-
|
|
822
|
+
2,
|
|
728
823
|
marketIndex,
|
|
729
824
|
new BN(6),
|
|
730
825
|
BASE_PRECISION,
|
|
@@ -738,7 +833,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
738
833
|
Keypair.generate().publicKey,
|
|
739
834
|
OrderType.LIMIT,
|
|
740
835
|
MarketType.PERP,
|
|
741
|
-
|
|
836
|
+
1, // orderId
|
|
742
837
|
marketIndex,
|
|
743
838
|
new BN(7),
|
|
744
839
|
BASE_PRECISION,
|
|
@@ -752,7 +847,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
752
847
|
Keypair.generate().publicKey,
|
|
753
848
|
OrderType.LIMIT,
|
|
754
849
|
MarketType.PERP,
|
|
755
|
-
|
|
850
|
+
1, // orderId
|
|
756
851
|
marketIndex,
|
|
757
852
|
new BN(12),
|
|
758
853
|
BASE_PRECISION,
|
|
@@ -766,7 +861,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
766
861
|
Keypair.generate().publicKey,
|
|
767
862
|
OrderType.LIMIT,
|
|
768
863
|
MarketType.PERP,
|
|
769
|
-
|
|
864
|
+
2, // orderId
|
|
770
865
|
marketIndex,
|
|
771
866
|
new BN(13),
|
|
772
867
|
BASE_PRECISION,
|
|
@@ -780,7 +875,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
780
875
|
Keypair.generate().publicKey,
|
|
781
876
|
OrderType.LIMIT,
|
|
782
877
|
MarketType.PERP,
|
|
783
|
-
|
|
878
|
+
3, // orderId
|
|
784
879
|
marketIndex,
|
|
785
880
|
new BN(14),
|
|
786
881
|
BASE_PRECISION,
|
|
@@ -803,7 +898,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
803
898
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
804
899
|
expect(getVariant(ask.order?.orderType)).to.equal('limit');
|
|
805
900
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
806
|
-
expect(ask.order?.orderId
|
|
901
|
+
expect(ask.order?.orderId).to.equal(asks);
|
|
807
902
|
expect(ask.order?.price.gt(vAsk)).to.equal(true);
|
|
808
903
|
}
|
|
809
904
|
|
|
@@ -829,7 +924,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
829
924
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
830
925
|
expect(getVariant(bid.order?.orderType)).to.equal('limit');
|
|
831
926
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
832
|
-
expect(bid.order?.orderId
|
|
927
|
+
expect(bid.order?.orderId).to.equal(bids);
|
|
833
928
|
expect(bid.order?.price.lt(vBid)).to.equal(true);
|
|
834
929
|
}
|
|
835
930
|
bids++;
|
|
@@ -837,11 +932,182 @@ describe('DLOB Perp Tests', () => {
|
|
|
837
932
|
expect(bids).to.equal(4); // vamm bid + 3 orders
|
|
838
933
|
});
|
|
839
934
|
|
|
935
|
+
it('Test insert floatinglimit orders', () => {
|
|
936
|
+
const slot = 12;
|
|
937
|
+
const vAsk = new BN(11).mul(PRICE_PRECISION);
|
|
938
|
+
const vBid = new BN(10).mul(PRICE_PRECISION);
|
|
939
|
+
const oracle = {
|
|
940
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
941
|
+
slot: new BN(slot),
|
|
942
|
+
confidence: new BN(1),
|
|
943
|
+
hasSufficientNumberOfDataPoints: true,
|
|
944
|
+
};
|
|
945
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
946
|
+
const marketIndex = 0;
|
|
947
|
+
|
|
948
|
+
// insert floating bids
|
|
949
|
+
insertOrderToDLOB(
|
|
950
|
+
dlob,
|
|
951
|
+
Keypair.generate().publicKey,
|
|
952
|
+
OrderType.LIMIT,
|
|
953
|
+
MarketType.PERP,
|
|
954
|
+
1, // orderId
|
|
955
|
+
marketIndex,
|
|
956
|
+
new BN(0), // price
|
|
957
|
+
BASE_PRECISION, // quantity
|
|
958
|
+
PositionDirection.LONG,
|
|
959
|
+
vBid,
|
|
960
|
+
vAsk,
|
|
961
|
+
new BN(slot),
|
|
962
|
+
30, // TiF
|
|
963
|
+
new BN(-1).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
964
|
+
);
|
|
965
|
+
insertOrderToDLOB(
|
|
966
|
+
dlob,
|
|
967
|
+
Keypair.generate().publicKey,
|
|
968
|
+
OrderType.LIMIT,
|
|
969
|
+
MarketType.PERP,
|
|
970
|
+
3, // orderId
|
|
971
|
+
marketIndex,
|
|
972
|
+
new BN(0), // price
|
|
973
|
+
BASE_PRECISION, // quantity
|
|
974
|
+
PositionDirection.LONG,
|
|
975
|
+
vBid,
|
|
976
|
+
vAsk,
|
|
977
|
+
new BN(slot),
|
|
978
|
+
30, // TiF
|
|
979
|
+
new BN(-3).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
980
|
+
);
|
|
981
|
+
insertOrderToDLOB(
|
|
982
|
+
dlob,
|
|
983
|
+
Keypair.generate().publicKey,
|
|
984
|
+
OrderType.LIMIT,
|
|
985
|
+
MarketType.PERP,
|
|
986
|
+
2, // orderId
|
|
987
|
+
marketIndex,
|
|
988
|
+
new BN(0), // price
|
|
989
|
+
BASE_PRECISION, // quantity
|
|
990
|
+
PositionDirection.LONG,
|
|
991
|
+
vBid,
|
|
992
|
+
vAsk,
|
|
993
|
+
new BN(slot),
|
|
994
|
+
30, // TiF
|
|
995
|
+
new BN(-2).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
996
|
+
);
|
|
997
|
+
|
|
998
|
+
// insert floating asks
|
|
999
|
+
insertOrderToDLOB(
|
|
1000
|
+
dlob,
|
|
1001
|
+
Keypair.generate().publicKey,
|
|
1002
|
+
OrderType.LIMIT,
|
|
1003
|
+
MarketType.PERP,
|
|
1004
|
+
5, // orderId
|
|
1005
|
+
marketIndex,
|
|
1006
|
+
new BN(0), // price
|
|
1007
|
+
BASE_PRECISION, // quantity
|
|
1008
|
+
PositionDirection.SHORT,
|
|
1009
|
+
vAsk,
|
|
1010
|
+
vBid,
|
|
1011
|
+
new BN(slot),
|
|
1012
|
+
30, // TiF
|
|
1013
|
+
new BN(2).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1014
|
+
);
|
|
1015
|
+
insertOrderToDLOB(
|
|
1016
|
+
dlob,
|
|
1017
|
+
Keypair.generate().publicKey,
|
|
1018
|
+
OrderType.LIMIT,
|
|
1019
|
+
MarketType.PERP,
|
|
1020
|
+
6, // orderId
|
|
1021
|
+
marketIndex,
|
|
1022
|
+
new BN(0), // price
|
|
1023
|
+
BASE_PRECISION, // quantity
|
|
1024
|
+
PositionDirection.SHORT,
|
|
1025
|
+
vAsk,
|
|
1026
|
+
vBid,
|
|
1027
|
+
new BN(slot),
|
|
1028
|
+
30, // TiF
|
|
1029
|
+
new BN(3).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1030
|
+
);
|
|
1031
|
+
insertOrderToDLOB(
|
|
1032
|
+
dlob,
|
|
1033
|
+
Keypair.generate().publicKey,
|
|
1034
|
+
OrderType.LIMIT,
|
|
1035
|
+
MarketType.PERP,
|
|
1036
|
+
4, // orderId
|
|
1037
|
+
marketIndex,
|
|
1038
|
+
new BN(0), // price
|
|
1039
|
+
BASE_PRECISION, // quantity
|
|
1040
|
+
PositionDirection.SHORT,
|
|
1041
|
+
vAsk,
|
|
1042
|
+
vBid,
|
|
1043
|
+
new BN(slot),
|
|
1044
|
+
30, // TiF
|
|
1045
|
+
new BN(1).mul(PRICE_PRECISION) // oraclePriceOffset
|
|
1046
|
+
);
|
|
1047
|
+
|
|
1048
|
+
// check floating bids
|
|
1049
|
+
console.log(`bids:`);
|
|
1050
|
+
let lastBidPrice = new BN(9999999999999); // very big
|
|
1051
|
+
let bids = 0;
|
|
1052
|
+
for (const bid of dlob.getBids(
|
|
1053
|
+
marketIndex,
|
|
1054
|
+
vBid,
|
|
1055
|
+
slot,
|
|
1056
|
+
MarketType.PERP,
|
|
1057
|
+
oracle
|
|
1058
|
+
)) {
|
|
1059
|
+
printOrderNode(bid, oracle, slot);
|
|
1060
|
+
|
|
1061
|
+
if (!bid.isVammNode()) {
|
|
1062
|
+
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
1063
|
+
expect(getVariant(bid.order?.orderType)).to.equal('limit');
|
|
1064
|
+
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
1065
|
+
|
|
1066
|
+
// price should be getting worse (getting lower) as we iterate
|
|
1067
|
+
const currentPrice = bid.getPrice(oracle, slot);
|
|
1068
|
+
expect(
|
|
1069
|
+
currentPrice.lte(lastBidPrice),
|
|
1070
|
+
`each bid should be lte the last. current: ${currentPrice.toString()}, last: ${lastBidPrice.toString()}`
|
|
1071
|
+
).to.be.true;
|
|
1072
|
+
}
|
|
1073
|
+
lastBidPrice = bid.getPrice(oracle, slot);
|
|
1074
|
+
bids++;
|
|
1075
|
+
}
|
|
1076
|
+
expect(bids).to.equal(4); // vamm bid + 3 orders
|
|
1077
|
+
|
|
1078
|
+
// check floating asks
|
|
1079
|
+
console.log(`asks:`);
|
|
1080
|
+
let asks = 0;
|
|
1081
|
+
for (const ask of dlob.getAsks(
|
|
1082
|
+
marketIndex,
|
|
1083
|
+
vAsk,
|
|
1084
|
+
slot,
|
|
1085
|
+
MarketType.PERP,
|
|
1086
|
+
oracle
|
|
1087
|
+
)) {
|
|
1088
|
+
printOrderNode(ask, oracle, slot);
|
|
1089
|
+
if (!ask.isVammNode()) {
|
|
1090
|
+
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
1091
|
+
expect(getVariant(ask.order?.orderType)).to.equal('limit');
|
|
1092
|
+
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
1093
|
+
|
|
1094
|
+
// price should be getting worse (getting higher) as we iterate
|
|
1095
|
+
const currentPrice = ask.getPrice(oracle, slot);
|
|
1096
|
+
expect(
|
|
1097
|
+
currentPrice.gte(lastBidPrice),
|
|
1098
|
+
`each ask should be gte the last. current: ${currentPrice.toString()}, last: ${lastBidPrice.toString()}`
|
|
1099
|
+
).to.be.true;
|
|
1100
|
+
}
|
|
1101
|
+
asks++;
|
|
1102
|
+
}
|
|
1103
|
+
expect(asks).to.equal(4); // vamm ask + 3 orders
|
|
1104
|
+
});
|
|
1105
|
+
|
|
840
1106
|
it('Test multiple market orders fill with multiple limit orders', () => {
|
|
841
1107
|
const vAsk = new BN(15);
|
|
842
1108
|
const vBid = new BN(10);
|
|
843
1109
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
844
|
-
const marketIndex =
|
|
1110
|
+
const marketIndex = 0;
|
|
845
1111
|
|
|
846
1112
|
// insert some limit buys above vamm bid, below ask
|
|
847
1113
|
insertOrderToDLOB(
|
|
@@ -849,7 +1115,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
849
1115
|
Keypair.generate().publicKey,
|
|
850
1116
|
OrderType.LIMIT,
|
|
851
1117
|
MarketType.PERP,
|
|
852
|
-
|
|
1118
|
+
1, // orderId
|
|
853
1119
|
marketIndex,
|
|
854
1120
|
new BN(11), // price
|
|
855
1121
|
BASE_PRECISION, // quantity
|
|
@@ -862,7 +1128,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
862
1128
|
Keypair.generate().publicKey,
|
|
863
1129
|
OrderType.LIMIT,
|
|
864
1130
|
MarketType.PERP,
|
|
865
|
-
|
|
1131
|
+
2, // orderId
|
|
866
1132
|
marketIndex,
|
|
867
1133
|
new BN(12), // price
|
|
868
1134
|
BASE_PRECISION, // quantity
|
|
@@ -875,7 +1141,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
875
1141
|
Keypair.generate().publicKey,
|
|
876
1142
|
OrderType.LIMIT,
|
|
877
1143
|
MarketType.PERP,
|
|
878
|
-
|
|
1144
|
+
3, // orderId
|
|
879
1145
|
marketIndex,
|
|
880
1146
|
new BN(13), // price
|
|
881
1147
|
BASE_PRECISION, // quantity
|
|
@@ -887,8 +1153,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
887
1153
|
// should have no crossing orders
|
|
888
1154
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
889
1155
|
marketIndex,
|
|
890
|
-
vBid,
|
|
891
|
-
vAsk,
|
|
892
1156
|
12, // auction over
|
|
893
1157
|
MarketType.PERP,
|
|
894
1158
|
{
|
|
@@ -906,7 +1170,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
906
1170
|
Keypair.generate().publicKey,
|
|
907
1171
|
OrderType.MARKET,
|
|
908
1172
|
MarketType.PERP,
|
|
909
|
-
|
|
1173
|
+
4, // orderId
|
|
910
1174
|
marketIndex,
|
|
911
1175
|
new BN(12), // price
|
|
912
1176
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -919,7 +1183,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
919
1183
|
Keypair.generate().publicKey,
|
|
920
1184
|
OrderType.MARKET,
|
|
921
1185
|
MarketType.PERP,
|
|
922
|
-
|
|
1186
|
+
5, // orderId
|
|
923
1187
|
marketIndex,
|
|
924
1188
|
new BN(12), // price
|
|
925
1189
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -930,8 +1194,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
930
1194
|
|
|
931
1195
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
932
1196
|
marketIndex,
|
|
933
|
-
vBid,
|
|
934
|
-
vAsk,
|
|
935
1197
|
12, // auction over
|
|
936
1198
|
MarketType.PERP,
|
|
937
1199
|
{
|
|
@@ -941,31 +1203,26 @@ describe('DLOB Perp Tests', () => {
|
|
|
941
1203
|
hasSufficientNumberOfDataPoints: true,
|
|
942
1204
|
}
|
|
943
1205
|
);
|
|
1206
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
944
1207
|
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
|
-
);
|
|
1208
|
+
printCrossedNodes(n, 12);
|
|
948
1209
|
}
|
|
949
1210
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
950
1211
|
|
|
951
1212
|
// first taker should fill with best maker
|
|
952
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
953
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
954
|
-
3
|
|
955
|
-
);
|
|
1213
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1214
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
956
1215
|
|
|
957
1216
|
// 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
|
-
);
|
|
1217
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
1218
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
962
1219
|
});
|
|
963
1220
|
|
|
964
1221
|
it('Test one market orders fills two limit orders', () => {
|
|
965
1222
|
const vAsk = new BN(15);
|
|
966
1223
|
const vBid = new BN(10);
|
|
967
1224
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
968
|
-
const marketIndex =
|
|
1225
|
+
const marketIndex = 0;
|
|
969
1226
|
|
|
970
1227
|
// insert some limit sells below vAMM ask, above bid
|
|
971
1228
|
insertOrderToDLOB(
|
|
@@ -973,7 +1230,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
973
1230
|
Keypair.generate().publicKey,
|
|
974
1231
|
OrderType.LIMIT,
|
|
975
1232
|
MarketType.PERP,
|
|
976
|
-
|
|
1233
|
+
1, // orderId
|
|
977
1234
|
marketIndex,
|
|
978
1235
|
new BN(14), // price
|
|
979
1236
|
BASE_PRECISION, // quantity
|
|
@@ -986,7 +1243,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
986
1243
|
Keypair.generate().publicKey,
|
|
987
1244
|
OrderType.LIMIT,
|
|
988
1245
|
MarketType.PERP,
|
|
989
|
-
|
|
1246
|
+
2, // orderId
|
|
990
1247
|
marketIndex,
|
|
991
1248
|
new BN(13), // price
|
|
992
1249
|
BASE_PRECISION, // quantity
|
|
@@ -999,7 +1256,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
999
1256
|
Keypair.generate().publicKey,
|
|
1000
1257
|
OrderType.LIMIT,
|
|
1001
1258
|
MarketType.PERP,
|
|
1002
|
-
|
|
1259
|
+
3, // orderId
|
|
1003
1260
|
marketIndex,
|
|
1004
1261
|
new BN(12), // price
|
|
1005
1262
|
BASE_PRECISION, // quantity
|
|
@@ -1011,8 +1268,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
1011
1268
|
// should have no crossing orders
|
|
1012
1269
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
1013
1270
|
marketIndex,
|
|
1014
|
-
vBid,
|
|
1015
|
-
vAsk,
|
|
1016
1271
|
12, // auction over
|
|
1017
1272
|
MarketType.PERP,
|
|
1018
1273
|
{
|
|
@@ -1030,7 +1285,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1030
1285
|
Keypair.generate().publicKey,
|
|
1031
1286
|
OrderType.MARKET,
|
|
1032
1287
|
MarketType.PERP,
|
|
1033
|
-
|
|
1288
|
+
4, // orderId
|
|
1034
1289
|
marketIndex,
|
|
1035
1290
|
new BN(13), // price
|
|
1036
1291
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -1041,8 +1296,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
1041
1296
|
|
|
1042
1297
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
1043
1298
|
marketIndex,
|
|
1044
|
-
vBid,
|
|
1045
|
-
vAsk,
|
|
1046
1299
|
12, // auction over
|
|
1047
1300
|
MarketType.PERP,
|
|
1048
1301
|
{
|
|
@@ -1052,31 +1305,26 @@ describe('DLOB Perp Tests', () => {
|
|
|
1052
1305
|
hasSufficientNumberOfDataPoints: true,
|
|
1053
1306
|
}
|
|
1054
1307
|
);
|
|
1308
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1055
1309
|
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
|
-
);
|
|
1310
|
+
printCrossedNodes(n, 12);
|
|
1059
1311
|
}
|
|
1060
1312
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
1061
1313
|
|
|
1062
1314
|
// taker should fill completely with best maker
|
|
1063
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
1064
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
1065
|
-
3
|
|
1066
|
-
);
|
|
1315
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1316
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
1067
1317
|
|
|
1068
1318
|
// 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
|
-
);
|
|
1319
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(4);
|
|
1320
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
1073
1321
|
});
|
|
1074
1322
|
|
|
1075
1323
|
it('Test two market orders to fill one limit order', () => {
|
|
1076
1324
|
const vAsk = new BN(15);
|
|
1077
1325
|
const vBid = new BN(8);
|
|
1078
1326
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1079
|
-
const marketIndex =
|
|
1327
|
+
const marketIndex = 0;
|
|
1080
1328
|
|
|
1081
1329
|
const slot = 12;
|
|
1082
1330
|
const oracle = {
|
|
@@ -1092,7 +1340,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1092
1340
|
Keypair.generate().publicKey,
|
|
1093
1341
|
OrderType.LIMIT,
|
|
1094
1342
|
MarketType.PERP,
|
|
1095
|
-
|
|
1343
|
+
1, // orderId
|
|
1096
1344
|
marketIndex,
|
|
1097
1345
|
new BN(14), // price
|
|
1098
1346
|
BASE_PRECISION, // quantity
|
|
@@ -1105,7 +1353,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1105
1353
|
Keypair.generate().publicKey,
|
|
1106
1354
|
OrderType.LIMIT,
|
|
1107
1355
|
MarketType.PERP,
|
|
1108
|
-
|
|
1356
|
+
2, // orderId
|
|
1109
1357
|
marketIndex,
|
|
1110
1358
|
new BN(13), // price
|
|
1111
1359
|
BASE_PRECISION, // quantity
|
|
@@ -1118,7 +1366,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1118
1366
|
Keypair.generate().publicKey,
|
|
1119
1367
|
OrderType.LIMIT,
|
|
1120
1368
|
MarketType.PERP,
|
|
1121
|
-
|
|
1369
|
+
3, // orderId
|
|
1122
1370
|
marketIndex,
|
|
1123
1371
|
new BN(9), // price <-- best price
|
|
1124
1372
|
new BN(3).mul(BASE_PRECISION), // quantity
|
|
@@ -1130,8 +1378,6 @@ describe('DLOB Perp Tests', () => {
|
|
|
1130
1378
|
// should have no crossing orders
|
|
1131
1379
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
1132
1380
|
marketIndex,
|
|
1133
|
-
vBid,
|
|
1134
|
-
vAsk,
|
|
1135
1381
|
12, // auction over
|
|
1136
1382
|
MarketType.PERP,
|
|
1137
1383
|
oracle
|
|
@@ -1144,7 +1390,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1144
1390
|
Keypair.generate().publicKey,
|
|
1145
1391
|
OrderType.MARKET,
|
|
1146
1392
|
MarketType.PERP,
|
|
1147
|
-
|
|
1393
|
+
4, // orderId
|
|
1148
1394
|
marketIndex,
|
|
1149
1395
|
new BN(0), // price
|
|
1150
1396
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -1157,7 +1403,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1157
1403
|
Keypair.generate().publicKey,
|
|
1158
1404
|
OrderType.MARKET,
|
|
1159
1405
|
MarketType.PERP,
|
|
1160
|
-
|
|
1406
|
+
5, // orderId
|
|
1161
1407
|
marketIndex,
|
|
1162
1408
|
new BN(0), // price
|
|
1163
1409
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -1168,87 +1414,39 @@ describe('DLOB Perp Tests', () => {
|
|
|
1168
1414
|
|
|
1169
1415
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
1170
1416
|
marketIndex,
|
|
1171
|
-
vBid,
|
|
1172
|
-
vAsk,
|
|
1173
1417
|
slot, // auction over
|
|
1174
1418
|
MarketType.PERP,
|
|
1175
1419
|
oracle
|
|
1176
1420
|
);
|
|
1177
|
-
const mktNodes = dlob.
|
|
1421
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
1178
1422
|
marketIndex,
|
|
1179
1423
|
slot,
|
|
1180
1424
|
MarketType.PERP
|
|
1181
1425
|
);
|
|
1182
1426
|
console.log(`market nodes: ${mktNodes.length}`);
|
|
1183
1427
|
|
|
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);
|
|
1204
|
-
|
|
1205
|
-
const bidNodes = dlob.getBids(
|
|
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);
|
|
1428
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
1225
1429
|
|
|
1226
|
-
console.log(`
|
|
1430
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1227
1431
|
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
|
-
);
|
|
1432
|
+
printCrossedNodes(n, slot);
|
|
1231
1433
|
}
|
|
1232
1434
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
1233
1435
|
|
|
1234
1436
|
// taker should fill completely with best maker
|
|
1235
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
1236
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
1237
|
-
3
|
|
1238
|
-
);
|
|
1437
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1438
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
1239
1439
|
|
|
1240
1440
|
// 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
|
-
);
|
|
1441
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
1442
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
|
|
1245
1443
|
});
|
|
1246
1444
|
|
|
1247
1445
|
it('Test trigger orders', () => {
|
|
1248
1446
|
const vAsk = new BN(15);
|
|
1249
1447
|
const vBid = new BN(8);
|
|
1250
1448
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1251
|
-
const marketIndex =
|
|
1449
|
+
const marketIndex = 0;
|
|
1252
1450
|
|
|
1253
1451
|
const slot = 20;
|
|
1254
1452
|
const oracle = {
|
|
@@ -1267,7 +1465,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1267
1465
|
Keypair.generate().publicKey,
|
|
1268
1466
|
OrderType.TRIGGER_LIMIT,
|
|
1269
1467
|
MarketType.PERP,
|
|
1270
|
-
|
|
1468
|
+
1, //orderId
|
|
1271
1469
|
marketIndex, // marketIndex
|
|
1272
1470
|
vBid, // price
|
|
1273
1471
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1283,7 +1481,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1283
1481
|
Keypair.generate().publicKey,
|
|
1284
1482
|
OrderType.TRIGGER_LIMIT,
|
|
1285
1483
|
MarketType.PERP,
|
|
1286
|
-
|
|
1484
|
+
2, //orderId
|
|
1287
1485
|
marketIndex, // marketIndex
|
|
1288
1486
|
vBid, // price
|
|
1289
1487
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1299,7 +1497,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1299
1497
|
Keypair.generate().publicKey,
|
|
1300
1498
|
OrderType.TRIGGER_MARKET,
|
|
1301
1499
|
MarketType.PERP,
|
|
1302
|
-
|
|
1500
|
+
3, //orderId
|
|
1303
1501
|
marketIndex, // marketIndex
|
|
1304
1502
|
vAsk, // price
|
|
1305
1503
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1315,7 +1513,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1315
1513
|
Keypair.generate().publicKey,
|
|
1316
1514
|
OrderType.TRIGGER_MARKET,
|
|
1317
1515
|
MarketType.PERP,
|
|
1318
|
-
|
|
1516
|
+
4, //orderId
|
|
1319
1517
|
marketIndex, // marketIndex
|
|
1320
1518
|
vBid, // price
|
|
1321
1519
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1331,7 +1529,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1331
1529
|
Keypair.generate().publicKey,
|
|
1332
1530
|
OrderType.TRIGGER_LIMIT,
|
|
1333
1531
|
MarketType.PERP,
|
|
1334
|
-
|
|
1532
|
+
5, //orderId
|
|
1335
1533
|
marketIndex, // marketIndex
|
|
1336
1534
|
vBid, // price
|
|
1337
1535
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1347,7 +1545,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1347
1545
|
Keypair.generate().publicKey,
|
|
1348
1546
|
OrderType.TRIGGER_LIMIT,
|
|
1349
1547
|
MarketType.PERP,
|
|
1350
|
-
|
|
1548
|
+
6, //orderId
|
|
1351
1549
|
marketIndex, // marketIndex
|
|
1352
1550
|
vBid, // price
|
|
1353
1551
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1363,7 +1561,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1363
1561
|
Keypair.generate().publicKey,
|
|
1364
1562
|
OrderType.TRIGGER_MARKET,
|
|
1365
1563
|
MarketType.PERP,
|
|
1366
|
-
|
|
1564
|
+
7, //orderId
|
|
1367
1565
|
marketIndex, // marketIndex
|
|
1368
1566
|
vBid, // price
|
|
1369
1567
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1379,7 +1577,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1379
1577
|
Keypair.generate().publicKey,
|
|
1380
1578
|
OrderType.TRIGGER_MARKET,
|
|
1381
1579
|
MarketType.PERP,
|
|
1382
|
-
|
|
1580
|
+
8, //orderId
|
|
1383
1581
|
marketIndex, // marketIndex
|
|
1384
1582
|
vBid, // price
|
|
1385
1583
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1396,7 +1594,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1396
1594
|
Keypair.generate().publicKey,
|
|
1397
1595
|
OrderType.TRIGGER_MARKET,
|
|
1398
1596
|
MarketType.PERP,
|
|
1399
|
-
|
|
1597
|
+
9, //orderId
|
|
1400
1598
|
marketIndex, // marketIndex
|
|
1401
1599
|
vBid, // price
|
|
1402
1600
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1412,7 +1610,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1412
1610
|
Keypair.generate().publicKey,
|
|
1413
1611
|
OrderType.TRIGGER_MARKET,
|
|
1414
1612
|
MarketType.PERP,
|
|
1415
|
-
|
|
1613
|
+
10, //orderId
|
|
1416
1614
|
marketIndex, // marketIndex
|
|
1417
1615
|
vBid, // price
|
|
1418
1616
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1428,7 +1626,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1428
1626
|
Keypair.generate().publicKey,
|
|
1429
1627
|
OrderType.TRIGGER_MARKET,
|
|
1430
1628
|
MarketType.PERP,
|
|
1431
|
-
|
|
1629
|
+
11, //orderId
|
|
1432
1630
|
marketIndex, // marketIndex
|
|
1433
1631
|
vBid, // price
|
|
1434
1632
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1444,7 +1642,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1444
1642
|
Keypair.generate().publicKey,
|
|
1445
1643
|
OrderType.TRIGGER_MARKET,
|
|
1446
1644
|
MarketType.PERP,
|
|
1447
|
-
|
|
1645
|
+
12, //orderId
|
|
1448
1646
|
marketIndex, // marketIndex
|
|
1449
1647
|
vBid, // price
|
|
1450
1648
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -1463,7 +1661,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1463
1661
|
);
|
|
1464
1662
|
console.log(`nodesToTriggeR: ${nodesToTrigger.length}`);
|
|
1465
1663
|
for (const [idx, n] of nodesToTrigger.entries()) {
|
|
1466
|
-
expect(n.node.order?.orderId
|
|
1664
|
+
expect(n.node.order?.orderId).to.equal(orderIdsToTrigger[idx]);
|
|
1467
1665
|
console.log(`nodeToTrigger: ${n.node.order?.orderId.toString()}`);
|
|
1468
1666
|
}
|
|
1469
1667
|
});
|
|
@@ -1472,7 +1670,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1472
1670
|
const vAsk = new BN(15);
|
|
1473
1671
|
const vBid = new BN(8);
|
|
1474
1672
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1475
|
-
const marketIndex =
|
|
1673
|
+
const marketIndex = 0;
|
|
1476
1674
|
|
|
1477
1675
|
const slot = 20;
|
|
1478
1676
|
const timeInForce = 30;
|
|
@@ -1483,7 +1681,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1483
1681
|
Keypair.generate().publicKey,
|
|
1484
1682
|
OrderType.MARKET,
|
|
1485
1683
|
MarketType.PERP,
|
|
1486
|
-
|
|
1684
|
+
255, // orderId
|
|
1487
1685
|
marketIndex,
|
|
1488
1686
|
new BN(2), // price, very low, don't cross vamm
|
|
1489
1687
|
BASE_PRECISION, // quantity
|
|
@@ -1498,7 +1696,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1498
1696
|
Keypair.generate().publicKey,
|
|
1499
1697
|
OrderType.MARKET,
|
|
1500
1698
|
MarketType.PERP,
|
|
1501
|
-
|
|
1699
|
+
2, // orderId
|
|
1502
1700
|
marketIndex,
|
|
1503
1701
|
new BN(30), // price, very high, don't cross vamm
|
|
1504
1702
|
BASE_PRECISION, // quantity
|
|
@@ -1527,7 +1725,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
1527
1725
|
expect(nodesToFillBefore.length).to.equal(0);
|
|
1528
1726
|
|
|
1529
1727
|
// should get order to fill after timeInForce
|
|
1530
|
-
const slot1 = slot0 + timeInForce; // overshoots expiry
|
|
1728
|
+
const slot1 = slot0 + timeInForce * 2; // overshoots expiry
|
|
1531
1729
|
const nodesToFillAfter = dlob.findNodesToFill(
|
|
1532
1730
|
marketIndex,
|
|
1533
1731
|
vBid,
|
|
@@ -1541,20 +1739,22 @@ describe('DLOB Perp Tests', () => {
|
|
|
1541
1739
|
hasSufficientNumberOfDataPoints: true,
|
|
1542
1740
|
}
|
|
1543
1741
|
);
|
|
1742
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1743
|
+
for (const n of nodesToFillAfter) {
|
|
1744
|
+
printCrossedNodes(n, slot1);
|
|
1745
|
+
}
|
|
1544
1746
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
1545
1747
|
|
|
1546
1748
|
// check that the nodes have no makers
|
|
1547
1749
|
expect(nodesToFillAfter[0].makerNode).to.equal(undefined);
|
|
1548
1750
|
expect(nodesToFillAfter[1].makerNode).to.equal(undefined);
|
|
1549
1751
|
});
|
|
1550
|
-
});
|
|
1551
1752
|
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
const
|
|
1555
|
-
const vBid = new BN(100);
|
|
1753
|
+
it('Test skips vAMM and fills market buy order with floating limit order during auction', () => {
|
|
1754
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
1755
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
1556
1756
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1557
|
-
const marketIndex =
|
|
1757
|
+
const marketIndex = 0;
|
|
1558
1758
|
|
|
1559
1759
|
const slot = 12;
|
|
1560
1760
|
const oracle = {
|
|
@@ -1563,52 +1763,751 @@ describe('DLOB Spot Tests', () => {
|
|
|
1563
1763
|
confidence: new BN(1),
|
|
1564
1764
|
hasSufficientNumberOfDataPoints: true,
|
|
1565
1765
|
};
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1766
|
+
|
|
1767
|
+
// insert some floating limit sells above vAMM ask
|
|
1768
|
+
insertOrderToDLOB(
|
|
1769
|
+
dlob,
|
|
1770
|
+
Keypair.generate().publicKey,
|
|
1771
|
+
OrderType.LIMIT,
|
|
1772
|
+
MarketType.PERP,
|
|
1773
|
+
1, // orderId
|
|
1774
|
+
marketIndex,
|
|
1775
|
+
new BN(14).mul(PRICE_PRECISION), // price
|
|
1776
|
+
BASE_PRECISION, // quantity
|
|
1777
|
+
PositionDirection.SHORT,
|
|
1778
|
+
vBid,
|
|
1779
|
+
vAsk,
|
|
1780
|
+
new BN(slot),
|
|
1781
|
+
30,
|
|
1782
|
+
new BN(1).mul(PRICE_PRECISION)
|
|
1783
|
+
);
|
|
1784
|
+
insertOrderToDLOB(
|
|
1785
|
+
dlob,
|
|
1786
|
+
Keypair.generate().publicKey,
|
|
1787
|
+
OrderType.LIMIT,
|
|
1788
|
+
MarketType.PERP,
|
|
1789
|
+
2, // orderId
|
|
1790
|
+
marketIndex,
|
|
1791
|
+
new BN(13).mul(PRICE_PRECISION), // price
|
|
1792
|
+
BASE_PRECISION, // quantity
|
|
1793
|
+
PositionDirection.SHORT,
|
|
1794
|
+
vBid,
|
|
1795
|
+
vAsk,
|
|
1796
|
+
new BN(slot),
|
|
1797
|
+
30,
|
|
1798
|
+
new BN(1).mul(PRICE_PRECISION)
|
|
1799
|
+
);
|
|
1800
|
+
insertOrderToDLOB(
|
|
1801
|
+
dlob,
|
|
1802
|
+
Keypair.generate().publicKey,
|
|
1803
|
+
OrderType.LIMIT,
|
|
1804
|
+
MarketType.PERP,
|
|
1805
|
+
3, // orderId
|
|
1806
|
+
marketIndex,
|
|
1807
|
+
new BN(9).mul(PRICE_PRECISION), // price <-- best price
|
|
1808
|
+
new BN(3).mul(BASE_PRECISION), // quantity
|
|
1809
|
+
PositionDirection.SHORT,
|
|
1810
|
+
vBid,
|
|
1811
|
+
vAsk,
|
|
1812
|
+
new BN(slot),
|
|
1813
|
+
30,
|
|
1814
|
+
new BN(1).mul(PRICE_PRECISION)
|
|
1815
|
+
);
|
|
1816
|
+
|
|
1817
|
+
// should have no crossing orders
|
|
1818
|
+
const nodesToFillBefore = dlob.findNodesToFill(
|
|
1819
|
+
marketIndex,
|
|
1820
|
+
vBid,
|
|
1821
|
+
vAsk,
|
|
1822
|
+
slot,
|
|
1823
|
+
MarketType.PERP,
|
|
1824
|
+
{
|
|
1825
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1826
|
+
slot: new BN(slot),
|
|
1827
|
+
confidence: new BN(1),
|
|
1828
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1829
|
+
}
|
|
1830
|
+
);
|
|
1831
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
1832
|
+
|
|
1833
|
+
// place two market buy orders to eat the best ask
|
|
1834
|
+
insertOrderToDLOB(
|
|
1835
|
+
dlob,
|
|
1836
|
+
Keypair.generate().publicKey,
|
|
1837
|
+
OrderType.MARKET,
|
|
1838
|
+
MarketType.PERP,
|
|
1839
|
+
4, // orderId
|
|
1840
|
+
marketIndex,
|
|
1841
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
1842
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
1843
|
+
PositionDirection.LONG,
|
|
1844
|
+
vBid,
|
|
1845
|
+
vAsk
|
|
1846
|
+
);
|
|
1847
|
+
insertOrderToDLOB(
|
|
1848
|
+
dlob,
|
|
1849
|
+
Keypair.generate().publicKey,
|
|
1850
|
+
OrderType.MARKET,
|
|
1851
|
+
MarketType.PERP,
|
|
1852
|
+
5, // orderId
|
|
1853
|
+
marketIndex,
|
|
1854
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
1855
|
+
new BN(2).mul(BASE_PRECISION), // quantity
|
|
1856
|
+
PositionDirection.LONG,
|
|
1857
|
+
vBid,
|
|
1858
|
+
vAsk
|
|
1859
|
+
);
|
|
1860
|
+
|
|
1861
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
1862
|
+
marketIndex,
|
|
1863
|
+
vBid,
|
|
1864
|
+
vAsk,
|
|
1865
|
+
slot,
|
|
1866
|
+
MarketType.PERP,
|
|
1867
|
+
{
|
|
1868
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1869
|
+
slot: new BN(slot),
|
|
1870
|
+
confidence: new BN(1),
|
|
1871
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1872
|
+
}
|
|
1873
|
+
);
|
|
1874
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
1875
|
+
marketIndex,
|
|
1876
|
+
slot,
|
|
1877
|
+
MarketType.PERP
|
|
1878
|
+
);
|
|
1879
|
+
console.log(`market nodes: ${mktNodes.length}`);
|
|
1880
|
+
|
|
1881
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
1882
|
+
|
|
1883
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
1884
|
+
for (const n of nodesToFillAfter) {
|
|
1885
|
+
printCrossedNodes(n, slot);
|
|
1886
|
+
}
|
|
1887
|
+
expect(nodesToFillAfter.length).to.equal(3);
|
|
1888
|
+
|
|
1889
|
+
// taker should fill first order completely with best maker (1/1)
|
|
1890
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
1891
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(1);
|
|
1892
|
+
|
|
1893
|
+
// taker should fill partially with second best maker (1/2)
|
|
1894
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
1895
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
1896
|
+
|
|
1897
|
+
// taker should fill completely with third best maker (2/2)
|
|
1898
|
+
expect(nodesToFillAfter[2].node.order?.orderId).to.equal(5);
|
|
1899
|
+
expect(nodesToFillAfter[2].makerNode?.order?.orderId).to.equal(3);
|
|
1900
|
+
});
|
|
1901
|
+
|
|
1902
|
+
it('Test fills market buy order with better priced vAMM after auction', () => {
|
|
1903
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
1904
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
1905
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1906
|
+
const marketIndex = 0;
|
|
1907
|
+
|
|
1908
|
+
const slot = 12;
|
|
1909
|
+
const oracle = {
|
|
1910
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
1911
|
+
slot: new BN(slot),
|
|
1912
|
+
confidence: new BN(1),
|
|
1913
|
+
hasSufficientNumberOfDataPoints: true,
|
|
1914
|
+
};
|
|
1915
|
+
|
|
1916
|
+
// insert some floating limit sells above vAMM ask
|
|
1917
|
+
insertOrderToDLOB(
|
|
1918
|
+
dlob,
|
|
1919
|
+
Keypair.generate().publicKey,
|
|
1920
|
+
OrderType.LIMIT,
|
|
1921
|
+
MarketType.PERP,
|
|
1922
|
+
1, // orderId
|
|
1923
|
+
marketIndex,
|
|
1924
|
+
new BN(14).mul(PRICE_PRECISION), // price
|
|
1925
|
+
BASE_PRECISION, // quantity
|
|
1926
|
+
PositionDirection.SHORT,
|
|
1927
|
+
vBid,
|
|
1928
|
+
vAsk,
|
|
1929
|
+
new BN(slot),
|
|
1930
|
+
0,
|
|
1931
|
+
new BN(3).mul(PRICE_PRECISION)
|
|
1932
|
+
);
|
|
1933
|
+
insertOrderToDLOB(
|
|
1934
|
+
dlob,
|
|
1935
|
+
Keypair.generate().publicKey,
|
|
1936
|
+
OrderType.LIMIT,
|
|
1937
|
+
MarketType.PERP,
|
|
1938
|
+
2, // orderId
|
|
1939
|
+
marketIndex,
|
|
1940
|
+
new BN(13).mul(PRICE_PRECISION), // price
|
|
1941
|
+
BASE_PRECISION, // quantity
|
|
1942
|
+
PositionDirection.SHORT,
|
|
1943
|
+
vBid,
|
|
1944
|
+
vAsk,
|
|
1945
|
+
new BN(slot),
|
|
1946
|
+
0,
|
|
1947
|
+
new BN(4).mul(PRICE_PRECISION)
|
|
1948
|
+
);
|
|
1949
|
+
insertOrderToDLOB(
|
|
1950
|
+
dlob,
|
|
1951
|
+
Keypair.generate().publicKey,
|
|
1952
|
+
OrderType.LIMIT,
|
|
1953
|
+
MarketType.PERP,
|
|
1954
|
+
3, // orderId
|
|
1955
|
+
marketIndex,
|
|
1956
|
+
new BN(9).mul(PRICE_PRECISION), // price <-- best price
|
|
1957
|
+
new BN(3).mul(BASE_PRECISION), // quantity
|
|
1958
|
+
PositionDirection.SHORT,
|
|
1959
|
+
vBid,
|
|
1960
|
+
vAsk,
|
|
1961
|
+
new BN(slot),
|
|
1962
|
+
0,
|
|
1963
|
+
new BN(5).mul(PRICE_PRECISION)
|
|
1964
|
+
);
|
|
1965
|
+
|
|
1966
|
+
// should have no crossing orders
|
|
1967
|
+
const auctionOverSlot = slot * 10;
|
|
1968
|
+
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
1969
|
+
marketIndex,
|
|
1970
|
+
auctionOverSlot, // auction over
|
|
1971
|
+
MarketType.PERP,
|
|
1972
|
+
oracle
|
|
1973
|
+
);
|
|
1974
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
1975
|
+
|
|
1976
|
+
// place two market buy orders
|
|
1977
|
+
insertOrderToDLOB(
|
|
1978
|
+
dlob,
|
|
1979
|
+
Keypair.generate().publicKey,
|
|
1980
|
+
OrderType.MARKET,
|
|
1981
|
+
MarketType.PERP,
|
|
1982
|
+
4, // orderId
|
|
1983
|
+
marketIndex,
|
|
1984
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
1985
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
1986
|
+
PositionDirection.LONG,
|
|
1987
|
+
vBid,
|
|
1988
|
+
vAsk,
|
|
1989
|
+
new BN(slot),
|
|
1990
|
+
0
|
|
1991
|
+
);
|
|
1992
|
+
insertOrderToDLOB(
|
|
1993
|
+
dlob,
|
|
1994
|
+
Keypair.generate().publicKey,
|
|
1995
|
+
OrderType.MARKET,
|
|
1996
|
+
MarketType.PERP,
|
|
1997
|
+
5, // orderId
|
|
1998
|
+
marketIndex,
|
|
1999
|
+
new BN(15).mul(PRICE_PRECISION), // price
|
|
2000
|
+
new BN(2).mul(BASE_PRECISION), // quantity
|
|
2001
|
+
PositionDirection.LONG,
|
|
2002
|
+
vBid,
|
|
2003
|
+
vAsk,
|
|
2004
|
+
new BN(slot),
|
|
2005
|
+
0
|
|
2006
|
+
);
|
|
2007
|
+
|
|
2008
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2009
|
+
marketIndex,
|
|
2010
|
+
vBid,
|
|
2011
|
+
vAsk,
|
|
2012
|
+
auctionOverSlot, // auction in progress
|
|
2013
|
+
MarketType.PERP,
|
|
2014
|
+
oracle
|
|
2015
|
+
);
|
|
2016
|
+
|
|
2017
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2018
|
+
for (const n of nodesToFillAfter) {
|
|
2019
|
+
printCrossedNodes(n, auctionOverSlot);
|
|
2020
|
+
}
|
|
2021
|
+
expect(nodesToFillAfter.length).to.equal(2);
|
|
2022
|
+
|
|
2023
|
+
// taker should fill completely with best maker
|
|
2024
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
2025
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(1);
|
|
2026
|
+
|
|
2027
|
+
// taker should fill the rest with the vAMM
|
|
2028
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
2029
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(undefined);
|
|
2030
|
+
});
|
|
2031
|
+
|
|
2032
|
+
it('Test skips vAMM and fills market sell order with floating limit buys during auction', () => {
|
|
2033
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
2034
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
2035
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2036
|
+
const marketIndex = 0;
|
|
2037
|
+
|
|
2038
|
+
const slot = 12;
|
|
2039
|
+
const oracle = {
|
|
2040
|
+
price: vBid.add(vAsk).div(new BN(2)), // 11.5
|
|
2041
|
+
slot: new BN(slot),
|
|
2042
|
+
confidence: new BN(1),
|
|
2043
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2044
|
+
};
|
|
2045
|
+
|
|
2046
|
+
// insert some floating limit buy below vAMM bid
|
|
2047
|
+
insertOrderToDLOB(
|
|
2048
|
+
dlob,
|
|
2049
|
+
Keypair.generate().publicKey,
|
|
2050
|
+
OrderType.LIMIT,
|
|
2051
|
+
MarketType.PERP,
|
|
2052
|
+
2, // orderId
|
|
2053
|
+
marketIndex,
|
|
2054
|
+
new BN(0).mul(PRICE_PRECISION), // price, ignored since it's a floating limit
|
|
2055
|
+
BASE_PRECISION, // quantity
|
|
2056
|
+
PositionDirection.LONG,
|
|
2057
|
+
vBid,
|
|
2058
|
+
vAsk,
|
|
2059
|
+
new BN(slot),
|
|
2060
|
+
30,
|
|
2061
|
+
new BN(-4).mul(PRICE_PRECISION) // second best bid, but worse than vBid (8): 7.5
|
|
2062
|
+
);
|
|
2063
|
+
insertOrderToDLOB(
|
|
2064
|
+
dlob,
|
|
2065
|
+
Keypair.generate().publicKey,
|
|
2066
|
+
OrderType.LIMIT,
|
|
2067
|
+
MarketType.PERP,
|
|
2068
|
+
3, // orderId
|
|
2069
|
+
marketIndex,
|
|
2070
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2071
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2072
|
+
PositionDirection.LONG,
|
|
2073
|
+
vBid,
|
|
2074
|
+
vAsk,
|
|
2075
|
+
new BN(slot),
|
|
2076
|
+
30,
|
|
2077
|
+
new BN(-1).mul(PRICE_PRECISION) // best price: 10.5
|
|
2078
|
+
);
|
|
2079
|
+
insertOrderToDLOB(
|
|
2080
|
+
dlob,
|
|
2081
|
+
Keypair.generate().publicKey,
|
|
2082
|
+
OrderType.LIMIT,
|
|
2083
|
+
MarketType.PERP,
|
|
2084
|
+
1, // orderId
|
|
2085
|
+
marketIndex,
|
|
2086
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2087
|
+
BASE_PRECISION, // quantity
|
|
2088
|
+
PositionDirection.LONG,
|
|
2089
|
+
vBid,
|
|
2090
|
+
vAsk,
|
|
2091
|
+
new BN(slot),
|
|
2092
|
+
30,
|
|
2093
|
+
new BN(-5).mul(PRICE_PRECISION) // third best bid, worse than vBid (8): 6.5
|
|
2094
|
+
);
|
|
2095
|
+
|
|
2096
|
+
// should have no crossing orders
|
|
2097
|
+
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2098
|
+
marketIndex,
|
|
2099
|
+
slot,
|
|
2100
|
+
MarketType.PERP,
|
|
2101
|
+
oracle
|
|
2102
|
+
);
|
|
2103
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2104
|
+
|
|
2105
|
+
// place two market sell orders to eat the best bid
|
|
2106
|
+
insertOrderToDLOB(
|
|
2107
|
+
dlob,
|
|
2108
|
+
Keypair.generate().publicKey,
|
|
2109
|
+
OrderType.MARKET,
|
|
2110
|
+
MarketType.PERP,
|
|
2111
|
+
4, // orderId
|
|
2112
|
+
marketIndex,
|
|
2113
|
+
new BN(5).mul(PRICE_PRECISION), // price
|
|
2114
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2115
|
+
PositionDirection.SHORT,
|
|
2116
|
+
vBid,
|
|
2117
|
+
vAsk
|
|
2118
|
+
);
|
|
2119
|
+
insertOrderToDLOB(
|
|
2120
|
+
dlob,
|
|
2121
|
+
Keypair.generate().publicKey,
|
|
2122
|
+
OrderType.MARKET,
|
|
2123
|
+
MarketType.PERP,
|
|
2124
|
+
5, // orderId
|
|
2125
|
+
marketIndex,
|
|
2126
|
+
new BN(4).mul(PRICE_PRECISION), // price
|
|
2127
|
+
new BN(2).mul(BASE_PRECISION), // quantity
|
|
2128
|
+
PositionDirection.SHORT,
|
|
2129
|
+
vBid,
|
|
2130
|
+
vAsk
|
|
2131
|
+
);
|
|
2132
|
+
|
|
2133
|
+
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2134
|
+
marketIndex,
|
|
2135
|
+
slot, // auction in progress
|
|
2136
|
+
MarketType.PERP,
|
|
2137
|
+
oracle
|
|
2138
|
+
);
|
|
2139
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
2140
|
+
marketIndex,
|
|
2141
|
+
slot,
|
|
2142
|
+
MarketType.PERP
|
|
2143
|
+
);
|
|
2144
|
+
console.log(`market nodes: ${mktNodes.length}`);
|
|
2145
|
+
|
|
2146
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2147
|
+
|
|
2148
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2149
|
+
for (const n of nodesToFillAfter) {
|
|
2150
|
+
printCrossedNodes(n, slot);
|
|
2151
|
+
}
|
|
2152
|
+
expect(nodesToFillAfter.length).to.equal(3);
|
|
2153
|
+
|
|
2154
|
+
// taker should fill first order completely with best maker (1/1)
|
|
2155
|
+
expect(
|
|
2156
|
+
nodesToFillAfter[0].node.order?.orderId,
|
|
2157
|
+
'wrong taker orderId'
|
|
2158
|
+
).to.equal(4);
|
|
2159
|
+
expect(
|
|
2160
|
+
nodesToFillAfter[0].makerNode?.order?.orderId,
|
|
2161
|
+
'wrong maker orderId'
|
|
2162
|
+
).to.equal(3);
|
|
2163
|
+
|
|
2164
|
+
// taker should fill partially with second best maker (1/2)
|
|
2165
|
+
expect(
|
|
2166
|
+
nodesToFillAfter[1].node.order?.orderId,
|
|
2167
|
+
'wrong maker orderId'
|
|
2168
|
+
).to.equal(5);
|
|
2169
|
+
expect(
|
|
2170
|
+
nodesToFillAfter[1].makerNode?.order?.orderId,
|
|
2171
|
+
'wrong maker orderId'
|
|
2172
|
+
).to.equal(2);
|
|
2173
|
+
|
|
2174
|
+
// taker should fill completely with third best maker (2/2)
|
|
2175
|
+
expect(
|
|
2176
|
+
nodesToFillAfter[2].node.order?.orderId,
|
|
2177
|
+
'wrong taker orderId'
|
|
2178
|
+
).to.equal(5);
|
|
2179
|
+
expect(
|
|
2180
|
+
nodesToFillAfter[2].makerNode?.order?.orderId,
|
|
2181
|
+
'wrong maker orderId'
|
|
2182
|
+
).to.equal(1);
|
|
2183
|
+
});
|
|
2184
|
+
|
|
2185
|
+
it('Test fills market sell order with better priced vAMM after auction', () => {
|
|
2186
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
2187
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
2188
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2189
|
+
const marketIndex = 0;
|
|
2190
|
+
|
|
2191
|
+
const slot = 12;
|
|
2192
|
+
const oracle = {
|
|
2193
|
+
price: vBid.add(vAsk).div(new BN(2)), // 11.5
|
|
2194
|
+
slot: new BN(slot),
|
|
2195
|
+
confidence: new BN(1),
|
|
2196
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2197
|
+
};
|
|
2198
|
+
|
|
2199
|
+
// insert some floating limit buy below vAMM bid
|
|
2200
|
+
insertOrderToDLOB(
|
|
2201
|
+
dlob,
|
|
2202
|
+
Keypair.generate().publicKey,
|
|
2203
|
+
OrderType.LIMIT,
|
|
2204
|
+
MarketType.PERP,
|
|
2205
|
+
2, // orderId
|
|
2206
|
+
marketIndex,
|
|
2207
|
+
new BN(0).mul(PRICE_PRECISION), // price, ignored since it's a floating limit
|
|
2208
|
+
BASE_PRECISION, // quantity
|
|
2209
|
+
PositionDirection.LONG,
|
|
2210
|
+
vBid,
|
|
2211
|
+
vAsk,
|
|
2212
|
+
new BN(slot),
|
|
2213
|
+
30,
|
|
2214
|
+
new BN(-4).mul(PRICE_PRECISION) // second best bid, but worse than vBid (8): 7.5
|
|
2215
|
+
);
|
|
2216
|
+
insertOrderToDLOB(
|
|
2217
|
+
dlob,
|
|
2218
|
+
Keypair.generate().publicKey,
|
|
2219
|
+
OrderType.LIMIT,
|
|
2220
|
+
MarketType.PERP,
|
|
2221
|
+
3, // orderId
|
|
2222
|
+
marketIndex,
|
|
2223
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2224
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2225
|
+
PositionDirection.LONG,
|
|
2226
|
+
vBid,
|
|
2227
|
+
vAsk,
|
|
2228
|
+
new BN(slot),
|
|
2229
|
+
30,
|
|
2230
|
+
new BN(-1).mul(PRICE_PRECISION) // best price: 10.5
|
|
2231
|
+
);
|
|
2232
|
+
insertOrderToDLOB(
|
|
2233
|
+
dlob,
|
|
2234
|
+
Keypair.generate().publicKey,
|
|
2235
|
+
OrderType.LIMIT,
|
|
2236
|
+
MarketType.PERP,
|
|
2237
|
+
1, // orderId
|
|
2238
|
+
marketIndex,
|
|
2239
|
+
new BN(0).mul(PRICE_PRECISION), // price; ignored since it's a floating limit
|
|
2240
|
+
BASE_PRECISION, // quantity
|
|
2241
|
+
PositionDirection.LONG,
|
|
2242
|
+
vBid,
|
|
2243
|
+
vAsk,
|
|
2244
|
+
new BN(slot),
|
|
2245
|
+
30,
|
|
2246
|
+
new BN(-5).mul(PRICE_PRECISION) // third best bid, worse than vBid (8): 6.5
|
|
2247
|
+
);
|
|
2248
|
+
|
|
2249
|
+
console.log('DLOB state before fill:');
|
|
2250
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2251
|
+
|
|
2252
|
+
const nodesToFillBefore = dlob.findNodesToFill(
|
|
2253
|
+
marketIndex,
|
|
2254
|
+
vBid,
|
|
2255
|
+
vAsk,
|
|
2256
|
+
slot,
|
|
2257
|
+
MarketType.PERP,
|
|
2258
|
+
oracle
|
|
2259
|
+
);
|
|
2260
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2261
|
+
|
|
2262
|
+
// place two market sell orders to eat the best bid
|
|
2263
|
+
insertOrderToDLOB(
|
|
2264
|
+
dlob,
|
|
2265
|
+
Keypair.generate().publicKey,
|
|
2266
|
+
OrderType.MARKET,
|
|
2267
|
+
MarketType.PERP,
|
|
2268
|
+
4, // orderId
|
|
2269
|
+
marketIndex,
|
|
2270
|
+
new BN(5).mul(PRICE_PRECISION), // price
|
|
2271
|
+
new BN(1).mul(BASE_PRECISION), // quantity, should consume best bid floating limit
|
|
2272
|
+
PositionDirection.SHORT,
|
|
2273
|
+
vBid,
|
|
2274
|
+
vAsk,
|
|
2275
|
+
new BN(slot)
|
|
2276
|
+
);
|
|
2277
|
+
insertOrderToDLOB(
|
|
2278
|
+
dlob,
|
|
2279
|
+
Keypair.generate().publicKey,
|
|
2280
|
+
OrderType.MARKET,
|
|
2281
|
+
MarketType.PERP,
|
|
2282
|
+
5, // orderId
|
|
2283
|
+
marketIndex,
|
|
2284
|
+
// new BN(8).mul(PRICE_PRECISION), // price, this price will fill with vamm
|
|
2285
|
+
new BN(4).mul(PRICE_PRECISION), // price, this SHOULD fill with vamm
|
|
2286
|
+
new BN(2).mul(BASE_PRECISION), // quantity, should be filled with next best bid (vAMM)
|
|
2287
|
+
PositionDirection.SHORT,
|
|
2288
|
+
vBid,
|
|
2289
|
+
vAsk,
|
|
2290
|
+
new BN(slot)
|
|
2291
|
+
);
|
|
2292
|
+
|
|
2293
|
+
// auction ends, but order not expired
|
|
2294
|
+
const afterAuctionSlot = slot + 11;
|
|
2295
|
+
printBookState(dlob, marketIndex, vBid, vAsk, afterAuctionSlot, oracle);
|
|
2296
|
+
|
|
2297
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2298
|
+
marketIndex,
|
|
2299
|
+
vBid,
|
|
2300
|
+
vAsk,
|
|
2301
|
+
afterAuctionSlot,
|
|
2302
|
+
MarketType.PERP,
|
|
2303
|
+
oracle
|
|
2304
|
+
);
|
|
2305
|
+
|
|
2306
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2307
|
+
for (const n of nodesToFillAfter) {
|
|
2308
|
+
printCrossedNodes(n, afterAuctionSlot);
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
// taker should fill first order completely with best maker (1/1)
|
|
2312
|
+
expect(
|
|
2313
|
+
nodesToFillAfter[0].node.order?.orderId,
|
|
2314
|
+
'wrong taker orderId'
|
|
2315
|
+
).to.equal(4);
|
|
2316
|
+
expect(
|
|
2317
|
+
nodesToFillAfter[0].makerNode?.order?.orderId,
|
|
2318
|
+
'wrong maker orderId'
|
|
2319
|
+
).to.equal(3);
|
|
2320
|
+
|
|
2321
|
+
// taker should fill second order completely with vamm
|
|
2322
|
+
expect(
|
|
2323
|
+
nodesToFillAfter[1].node.order?.orderId,
|
|
2324
|
+
'wrong taker orderId'
|
|
2325
|
+
).to.equal(5);
|
|
2326
|
+
expect(
|
|
2327
|
+
nodesToFillAfter[1].makerNode?.order?.orderId,
|
|
2328
|
+
'wrong maker orderId'
|
|
2329
|
+
).to.equal(2); // filler should match the DLOB makers, protocol will fill the taker with vAMM if it offers a better price.
|
|
2330
|
+
|
|
2331
|
+
expect(nodesToFillAfter.length).to.equal(3);
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
it('Test fills crossing bids with vAMM after auction ends', () => {
|
|
2335
|
+
const vAsk = new BN(15).mul(PRICE_PRECISION);
|
|
2336
|
+
const vBid = new BN(8).mul(PRICE_PRECISION);
|
|
2337
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2338
|
+
const marketIndex = 0;
|
|
2339
|
+
|
|
2340
|
+
const slot = 12;
|
|
2341
|
+
const oracle = {
|
|
2342
|
+
price: vBid.add(vAsk).div(new BN(2)), // 11.5
|
|
2343
|
+
slot: new BN(slot),
|
|
2344
|
+
confidence: new BN(1),
|
|
2345
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2346
|
+
};
|
|
2347
|
+
|
|
2348
|
+
// insert some floating limit buy below vAMM bid
|
|
2349
|
+
insertOrderToDLOB(
|
|
2350
|
+
dlob,
|
|
2351
|
+
Keypair.generate().publicKey,
|
|
2352
|
+
OrderType.LIMIT,
|
|
2353
|
+
MarketType.PERP,
|
|
2354
|
+
2, // orderId
|
|
2355
|
+
marketIndex,
|
|
2356
|
+
new BN(17).mul(PRICE_PRECISION), // price, crosses vAsk
|
|
2357
|
+
BASE_PRECISION, // quantity
|
|
2358
|
+
PositionDirection.LONG,
|
|
2359
|
+
vBid,
|
|
2360
|
+
vAsk,
|
|
2361
|
+
new BN(slot),
|
|
2362
|
+
30
|
|
2363
|
+
);
|
|
2364
|
+
insertOrderToDLOB(
|
|
2365
|
+
dlob,
|
|
2366
|
+
Keypair.generate().publicKey,
|
|
2367
|
+
OrderType.LIMIT,
|
|
2368
|
+
MarketType.PERP,
|
|
2369
|
+
3, // orderId
|
|
2370
|
+
marketIndex,
|
|
2371
|
+
new BN(19).mul(PRICE_PRECISION), // price; crosses vAsk
|
|
2372
|
+
new BN(1).mul(BASE_PRECISION), // quantity
|
|
2373
|
+
PositionDirection.LONG,
|
|
2374
|
+
vBid,
|
|
2375
|
+
vAsk,
|
|
2376
|
+
new BN(slot),
|
|
2377
|
+
30
|
|
2378
|
+
);
|
|
2379
|
+
insertOrderToDLOB(
|
|
2380
|
+
dlob,
|
|
2381
|
+
Keypair.generate().publicKey,
|
|
2382
|
+
OrderType.LIMIT,
|
|
2383
|
+
MarketType.PERP,
|
|
2384
|
+
1, // orderId
|
|
2385
|
+
marketIndex,
|
|
2386
|
+
new BN(5).mul(PRICE_PRECISION), // price; doens't cross
|
|
2387
|
+
BASE_PRECISION, // quantity
|
|
2388
|
+
PositionDirection.LONG,
|
|
2389
|
+
vBid,
|
|
2390
|
+
vAsk,
|
|
2391
|
+
new BN(slot),
|
|
2392
|
+
30
|
|
2393
|
+
);
|
|
2394
|
+
console.log(`Book state before fill:`);
|
|
2395
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2396
|
+
|
|
2397
|
+
const nodesToFillBefore = dlob.findNodesToFill(
|
|
2398
|
+
marketIndex,
|
|
2399
|
+
vBid,
|
|
2400
|
+
vAsk,
|
|
2401
|
+
slot,
|
|
2402
|
+
MarketType.PERP,
|
|
2403
|
+
oracle
|
|
2404
|
+
);
|
|
2405
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2406
|
+
|
|
2407
|
+
// auction ends now
|
|
2408
|
+
const afterAuctionSlot = 10 * slot;
|
|
2409
|
+
|
|
2410
|
+
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2411
|
+
marketIndex,
|
|
2412
|
+
vBid,
|
|
2413
|
+
vAsk,
|
|
2414
|
+
afterAuctionSlot,
|
|
2415
|
+
MarketType.PERP,
|
|
2416
|
+
oracle
|
|
2417
|
+
);
|
|
2418
|
+
|
|
2419
|
+
console.log(`Book state after fill:`);
|
|
2420
|
+
printBookState(dlob, marketIndex, vBid, vAsk, afterAuctionSlot, oracle);
|
|
2421
|
+
|
|
2422
|
+
console.log(`Filled nodes: ${nodesToFillAfter.length}`);
|
|
2423
|
+
for (const n of nodesToFillAfter) {
|
|
2424
|
+
printCrossedNodes(n, afterAuctionSlot);
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
// taker should fill first order completely with best maker (1/1)
|
|
2428
|
+
expect(
|
|
2429
|
+
nodesToFillAfter[0].node.order?.orderId,
|
|
2430
|
+
'wrong taker orderId'
|
|
2431
|
+
).to.equal(3);
|
|
2432
|
+
expect(
|
|
2433
|
+
nodesToFillAfter[0].makerNode?.order?.orderId,
|
|
2434
|
+
'wrong maker orderId'
|
|
2435
|
+
).to.equal(undefined);
|
|
2436
|
+
|
|
2437
|
+
// taker should fill second order completely with vamm
|
|
2438
|
+
expect(
|
|
2439
|
+
nodesToFillAfter[1].node.order?.orderId,
|
|
2440
|
+
'wrong taker orderId'
|
|
2441
|
+
).to.equal(2);
|
|
2442
|
+
expect(
|
|
2443
|
+
nodesToFillAfter[1].makerNode?.order?.orderId,
|
|
2444
|
+
'wrong maker orderId'
|
|
2445
|
+
).to.equal(undefined);
|
|
2446
|
+
|
|
2447
|
+
expect(nodesToFillAfter.length).to.equal(2);
|
|
2448
|
+
});
|
|
2449
|
+
});
|
|
2450
|
+
|
|
2451
|
+
describe('DLOB Spot Tests', () => {
|
|
2452
|
+
it('Test proper bids', () => {
|
|
2453
|
+
const vAsk = new BN(115);
|
|
2454
|
+
const vBid = new BN(100);
|
|
2455
|
+
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2456
|
+
const marketIndex = 0;
|
|
2457
|
+
|
|
2458
|
+
const slot = 12;
|
|
2459
|
+
const oracle = {
|
|
2460
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
2461
|
+
slot: new BN(slot),
|
|
2462
|
+
confidence: new BN(1),
|
|
2463
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2464
|
+
};
|
|
2465
|
+
const testCases = [
|
|
2466
|
+
{
|
|
2467
|
+
expectedIdx: 3,
|
|
2468
|
+
orderId: 5,
|
|
2469
|
+
price: new BN(0), // will calc 108
|
|
2470
|
+
direction: PositionDirection.LONG,
|
|
2471
|
+
orderType: OrderType.MARKET,
|
|
2472
|
+
},
|
|
2473
|
+
{
|
|
2474
|
+
expectedIdx: 4,
|
|
2475
|
+
orderId: 6,
|
|
2476
|
+
price: new BN(0), // will calc 108
|
|
2477
|
+
direction: PositionDirection.LONG,
|
|
2478
|
+
orderType: OrderType.MARKET,
|
|
2479
|
+
},
|
|
2480
|
+
{
|
|
2481
|
+
expectedIdx: 5,
|
|
2482
|
+
orderId: 7,
|
|
2483
|
+
price: new BN(0), // will calc 108
|
|
2484
|
+
direction: PositionDirection.LONG,
|
|
2485
|
+
orderType: OrderType.MARKET,
|
|
2486
|
+
},
|
|
2487
|
+
{
|
|
2488
|
+
expectedIdx: 0,
|
|
2489
|
+
orderId: 1,
|
|
2490
|
+
price: new BN(110),
|
|
2491
|
+
direction: PositionDirection.LONG,
|
|
2492
|
+
orderType: OrderType.LIMIT,
|
|
2493
|
+
},
|
|
2494
|
+
{
|
|
2495
|
+
expectedIdx: 1,
|
|
2496
|
+
orderId: 2,
|
|
2497
|
+
price: new BN(109),
|
|
2498
|
+
direction: PositionDirection.LONG,
|
|
2499
|
+
orderType: OrderType.LIMIT,
|
|
2500
|
+
},
|
|
2501
|
+
{
|
|
1603
2502
|
expectedIdx: 6,
|
|
1604
|
-
orderId:
|
|
2503
|
+
orderId: 3,
|
|
1605
2504
|
price: new BN(107),
|
|
1606
2505
|
direction: PositionDirection.LONG,
|
|
1607
2506
|
orderType: OrderType.LIMIT,
|
|
1608
2507
|
},
|
|
1609
2508
|
{
|
|
1610
2509
|
expectedIdx: 7,
|
|
1611
|
-
orderId:
|
|
2510
|
+
orderId: 4,
|
|
1612
2511
|
price: new BN(106),
|
|
1613
2512
|
direction: PositionDirection.LONG,
|
|
1614
2513
|
orderType: OrderType.LIMIT,
|
|
@@ -1621,7 +2520,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1621
2520
|
Keypair.generate().publicKey,
|
|
1622
2521
|
t.orderType || OrderType.LIMIT,
|
|
1623
2522
|
MarketType.SPOT,
|
|
1624
|
-
t.orderId ||
|
|
2523
|
+
t.orderId || 0, // orderId
|
|
1625
2524
|
marketIndex,
|
|
1626
2525
|
t.price || new BN(0), // price
|
|
1627
2526
|
BASE_PRECISION, // quantity
|
|
@@ -1646,18 +2545,9 @@ describe('DLOB Spot Tests', () => {
|
|
|
1646
2545
|
console.log('The Book Bids:');
|
|
1647
2546
|
let countBids = 0;
|
|
1648
2547
|
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
|
-
);
|
|
2548
|
+
printOrderNode(bid, oracle, slot);
|
|
1657
2549
|
|
|
1658
|
-
expect(bid.order?.orderId
|
|
1659
|
-
expectedTestCase[countBids].orderId?.toNumber()
|
|
1660
|
-
);
|
|
2550
|
+
expect(bid.order?.orderId).to.equal(expectedTestCase[countBids].orderId);
|
|
1661
2551
|
expect(bid.order?.price.toNumber()).to.equal(
|
|
1662
2552
|
expectedTestCase[countBids].price?.toNumber()
|
|
1663
2553
|
);
|
|
@@ -1677,8 +2567,8 @@ describe('DLOB Spot Tests', () => {
|
|
|
1677
2567
|
const vAsk = new BN(15);
|
|
1678
2568
|
const vBid = new BN(10);
|
|
1679
2569
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1680
|
-
const marketIndex0 =
|
|
1681
|
-
const marketIndex1 =
|
|
2570
|
+
const marketIndex0 = 0;
|
|
2571
|
+
const marketIndex1 = 1;
|
|
1682
2572
|
|
|
1683
2573
|
const slot = 12;
|
|
1684
2574
|
const oracle = {
|
|
@@ -1690,7 +2580,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1690
2580
|
const testCases = [
|
|
1691
2581
|
{
|
|
1692
2582
|
expectedIdx: 3,
|
|
1693
|
-
orderId:
|
|
2583
|
+
orderId: 5,
|
|
1694
2584
|
price: new BN(0),
|
|
1695
2585
|
direction: PositionDirection.LONG,
|
|
1696
2586
|
orderType: OrderType.MARKET,
|
|
@@ -1698,7 +2588,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1698
2588
|
},
|
|
1699
2589
|
{
|
|
1700
2590
|
expectedIdx: 4,
|
|
1701
|
-
orderId:
|
|
2591
|
+
orderId: 6,
|
|
1702
2592
|
price: new BN(0),
|
|
1703
2593
|
direction: PositionDirection.LONG,
|
|
1704
2594
|
orderType: OrderType.MARKET,
|
|
@@ -1706,7 +2596,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1706
2596
|
},
|
|
1707
2597
|
{
|
|
1708
2598
|
expectedIdx: 5,
|
|
1709
|
-
orderId:
|
|
2599
|
+
orderId: 7,
|
|
1710
2600
|
price: new BN(0),
|
|
1711
2601
|
direction: PositionDirection.LONG,
|
|
1712
2602
|
orderType: OrderType.MARKET,
|
|
@@ -1714,7 +2604,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1714
2604
|
},
|
|
1715
2605
|
{
|
|
1716
2606
|
expectedIdx: 0,
|
|
1717
|
-
orderId:
|
|
2607
|
+
orderId: 1,
|
|
1718
2608
|
price: new BN(12),
|
|
1719
2609
|
direction: PositionDirection.LONG,
|
|
1720
2610
|
orderType: OrderType.LIMIT,
|
|
@@ -1722,7 +2612,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1722
2612
|
},
|
|
1723
2613
|
{
|
|
1724
2614
|
expectedIdx: 1,
|
|
1725
|
-
orderId:
|
|
2615
|
+
orderId: 2,
|
|
1726
2616
|
price: new BN(11),
|
|
1727
2617
|
direction: PositionDirection.LONG,
|
|
1728
2618
|
orderType: OrderType.LIMIT,
|
|
@@ -1730,7 +2620,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1730
2620
|
},
|
|
1731
2621
|
{
|
|
1732
2622
|
expectedIdx: 7,
|
|
1733
|
-
orderId:
|
|
2623
|
+
orderId: 3,
|
|
1734
2624
|
price: new BN(8),
|
|
1735
2625
|
direction: PositionDirection.LONG,
|
|
1736
2626
|
orderType: OrderType.LIMIT,
|
|
@@ -1738,7 +2628,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1738
2628
|
},
|
|
1739
2629
|
{
|
|
1740
2630
|
expectedIdx: 6,
|
|
1741
|
-
orderId:
|
|
2631
|
+
orderId: 4,
|
|
1742
2632
|
price: new BN(9),
|
|
1743
2633
|
direction: PositionDirection.LONG,
|
|
1744
2634
|
orderType: OrderType.LIMIT,
|
|
@@ -1752,7 +2642,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1752
2642
|
Keypair.generate().publicKey,
|
|
1753
2643
|
t.orderType || OrderType.LIMIT,
|
|
1754
2644
|
MarketType.SPOT,
|
|
1755
|
-
t.orderId ||
|
|
2645
|
+
t.orderId || 0, // orderId
|
|
1756
2646
|
t.marketIndex,
|
|
1757
2647
|
t.price || new BN(0), // price
|
|
1758
2648
|
BASE_PRECISION, // quantity
|
|
@@ -1810,7 +2700,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1810
2700
|
const vAsk = new BN(15);
|
|
1811
2701
|
const vBid = new BN(10);
|
|
1812
2702
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1813
|
-
const marketIndex =
|
|
2703
|
+
const marketIndex = 0;
|
|
1814
2704
|
|
|
1815
2705
|
const slot = 12;
|
|
1816
2706
|
const oracle = {
|
|
@@ -1822,49 +2712,49 @@ describe('DLOB Spot Tests', () => {
|
|
|
1822
2712
|
const testCases = [
|
|
1823
2713
|
{
|
|
1824
2714
|
expectedIdx: 0,
|
|
1825
|
-
orderId:
|
|
2715
|
+
orderId: 3,
|
|
1826
2716
|
price: new BN(0),
|
|
1827
2717
|
direction: PositionDirection.SHORT,
|
|
1828
2718
|
orderType: OrderType.MARKET,
|
|
1829
2719
|
},
|
|
1830
2720
|
{
|
|
1831
2721
|
expectedIdx: 1,
|
|
1832
|
-
orderId:
|
|
2722
|
+
orderId: 4,
|
|
1833
2723
|
price: new BN(0),
|
|
1834
2724
|
direction: PositionDirection.SHORT,
|
|
1835
2725
|
orderType: OrderType.MARKET,
|
|
1836
2726
|
},
|
|
1837
2727
|
{
|
|
1838
2728
|
expectedIdx: 2,
|
|
1839
|
-
orderId:
|
|
2729
|
+
orderId: 5,
|
|
1840
2730
|
price: new BN(0),
|
|
1841
2731
|
direction: PositionDirection.SHORT,
|
|
1842
2732
|
orderType: OrderType.MARKET,
|
|
1843
2733
|
},
|
|
1844
2734
|
{
|
|
1845
2735
|
expectedIdx: 3,
|
|
1846
|
-
orderId:
|
|
2736
|
+
orderId: 1,
|
|
1847
2737
|
price: new BN(13),
|
|
1848
2738
|
direction: PositionDirection.SHORT,
|
|
1849
2739
|
orderType: OrderType.LIMIT,
|
|
1850
2740
|
},
|
|
1851
2741
|
{
|
|
1852
2742
|
expectedIdx: 6,
|
|
1853
|
-
orderId:
|
|
2743
|
+
orderId: 6,
|
|
1854
2744
|
price: new BN(16),
|
|
1855
2745
|
direction: PositionDirection.SHORT,
|
|
1856
2746
|
orderType: OrderType.LIMIT,
|
|
1857
2747
|
},
|
|
1858
2748
|
{
|
|
1859
2749
|
expectedIdx: 7,
|
|
1860
|
-
orderId:
|
|
2750
|
+
orderId: 7,
|
|
1861
2751
|
price: new BN(17),
|
|
1862
2752
|
direction: PositionDirection.SHORT,
|
|
1863
2753
|
orderType: OrderType.LIMIT,
|
|
1864
2754
|
},
|
|
1865
2755
|
{
|
|
1866
2756
|
expectedIdx: 4,
|
|
1867
|
-
orderId:
|
|
2757
|
+
orderId: 2,
|
|
1868
2758
|
price: new BN(14),
|
|
1869
2759
|
direction: PositionDirection.SHORT,
|
|
1870
2760
|
orderType: OrderType.LIMIT,
|
|
@@ -1877,7 +2767,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1877
2767
|
Keypair.generate().publicKey,
|
|
1878
2768
|
t.orderType || OrderType.LIMIT,
|
|
1879
2769
|
MarketType.SPOT,
|
|
1880
|
-
t.orderId ||
|
|
2770
|
+
t.orderId || 0, // orderId
|
|
1881
2771
|
marketIndex,
|
|
1882
2772
|
t.price || new BN(0), // price
|
|
1883
2773
|
BASE_PRECISION, // quantity
|
|
@@ -1905,9 +2795,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1905
2795
|
)}, price: ${ask.order?.price.toString()}, quantity: ${ask.order?.baseAssetAmountFilled.toString()}/${ask.order?.baseAssetAmount.toString()}`
|
|
1906
2796
|
);
|
|
1907
2797
|
|
|
1908
|
-
expect(ask.order?.orderId
|
|
1909
|
-
expectedTestCase[countAsks].orderId?.toNumber()
|
|
1910
|
-
);
|
|
2798
|
+
expect(ask.order?.orderId).to.equal(expectedTestCase[countAsks].orderId);
|
|
1911
2799
|
expect(ask.order?.price.toNumber()).to.equal(
|
|
1912
2800
|
expectedTestCase[countAsks].price?.toNumber()
|
|
1913
2801
|
);
|
|
@@ -1934,7 +2822,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1934
2822
|
hasSufficientNumberOfDataPoints: true,
|
|
1935
2823
|
};
|
|
1936
2824
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
1937
|
-
const marketIndex =
|
|
2825
|
+
const marketIndex = 0;
|
|
1938
2826
|
|
|
1939
2827
|
// 3 mkt buys
|
|
1940
2828
|
for (let i = 0; i < 3; i++) {
|
|
@@ -1943,7 +2831,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1943
2831
|
Keypair.generate().publicKey,
|
|
1944
2832
|
OrderType.MARKET,
|
|
1945
2833
|
MarketType.SPOT,
|
|
1946
|
-
|
|
2834
|
+
i + 1,
|
|
1947
2835
|
marketIndex,
|
|
1948
2836
|
new BN(0),
|
|
1949
2837
|
BASE_PRECISION,
|
|
@@ -1960,7 +2848,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1960
2848
|
Keypair.generate().publicKey,
|
|
1961
2849
|
OrderType.MARKET,
|
|
1962
2850
|
MarketType.SPOT,
|
|
1963
|
-
|
|
2851
|
+
i + 1,
|
|
1964
2852
|
marketIndex,
|
|
1965
2853
|
new BN(0),
|
|
1966
2854
|
BASE_PRECISION,
|
|
@@ -1986,7 +2874,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
1986
2874
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
1987
2875
|
expect(getVariant(ask.order?.orderType)).to.equal('market');
|
|
1988
2876
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
1989
|
-
expect(ask.order?.orderId
|
|
2877
|
+
expect(ask.order?.orderId).to.equal(asks);
|
|
1990
2878
|
}
|
|
1991
2879
|
}
|
|
1992
2880
|
expect(asks).to.equal(3);
|
|
@@ -2003,7 +2891,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2003
2891
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
2004
2892
|
expect(getVariant(bid.order?.orderType)).to.equal('market');
|
|
2005
2893
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
2006
|
-
expect(bid.order?.orderId
|
|
2894
|
+
expect(bid.order?.orderId).to.equal(bids + 1);
|
|
2007
2895
|
bids++;
|
|
2008
2896
|
}
|
|
2009
2897
|
expect(bids).to.equal(3); // 3 orders
|
|
@@ -2020,13 +2908,13 @@ describe('DLOB Spot Tests', () => {
|
|
|
2020
2908
|
hasSufficientNumberOfDataPoints: true,
|
|
2021
2909
|
};
|
|
2022
2910
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2023
|
-
const marketIndex =
|
|
2911
|
+
const marketIndex = 0;
|
|
2024
2912
|
insertOrderToDLOB(
|
|
2025
2913
|
dlob,
|
|
2026
2914
|
Keypair.generate().publicKey,
|
|
2027
2915
|
OrderType.LIMIT,
|
|
2028
2916
|
MarketType.SPOT,
|
|
2029
|
-
|
|
2917
|
+
3, // orderId
|
|
2030
2918
|
marketIndex,
|
|
2031
2919
|
new BN(50),
|
|
2032
2920
|
BASE_PRECISION,
|
|
@@ -2040,7 +2928,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2040
2928
|
Keypair.generate().publicKey,
|
|
2041
2929
|
OrderType.LIMIT,
|
|
2042
2930
|
MarketType.SPOT,
|
|
2043
|
-
|
|
2931
|
+
2, // orderId
|
|
2044
2932
|
marketIndex,
|
|
2045
2933
|
new BN(60),
|
|
2046
2934
|
BASE_PRECISION,
|
|
@@ -2054,7 +2942,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2054
2942
|
Keypair.generate().publicKey,
|
|
2055
2943
|
OrderType.LIMIT,
|
|
2056
2944
|
MarketType.SPOT,
|
|
2057
|
-
|
|
2945
|
+
1, // orderId
|
|
2058
2946
|
marketIndex,
|
|
2059
2947
|
new BN(70),
|
|
2060
2948
|
BASE_PRECISION,
|
|
@@ -2068,7 +2956,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2068
2956
|
Keypair.generate().publicKey,
|
|
2069
2957
|
OrderType.LIMIT,
|
|
2070
2958
|
MarketType.SPOT,
|
|
2071
|
-
|
|
2959
|
+
1, // orderId
|
|
2072
2960
|
marketIndex,
|
|
2073
2961
|
new BN(120),
|
|
2074
2962
|
BASE_PRECISION,
|
|
@@ -2082,7 +2970,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2082
2970
|
Keypair.generate().publicKey,
|
|
2083
2971
|
OrderType.LIMIT,
|
|
2084
2972
|
MarketType.SPOT,
|
|
2085
|
-
|
|
2973
|
+
2, // orderId
|
|
2086
2974
|
marketIndex,
|
|
2087
2975
|
new BN(130),
|
|
2088
2976
|
BASE_PRECISION,
|
|
@@ -2096,7 +2984,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2096
2984
|
Keypair.generate().publicKey,
|
|
2097
2985
|
OrderType.LIMIT,
|
|
2098
2986
|
MarketType.SPOT,
|
|
2099
|
-
|
|
2987
|
+
3, // orderId
|
|
2100
2988
|
marketIndex,
|
|
2101
2989
|
new BN(140),
|
|
2102
2990
|
BASE_PRECISION,
|
|
@@ -2122,7 +3010,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2122
3010
|
expect(getVariant(ask.order?.status)).to.equal('open');
|
|
2123
3011
|
expect(getVariant(ask.order?.orderType)).to.equal('limit');
|
|
2124
3012
|
expect(getVariant(ask.order?.direction)).to.equal('short');
|
|
2125
|
-
expect(ask.order?.orderId
|
|
3013
|
+
expect(ask.order?.orderId).to.equal(asks + 1);
|
|
2126
3014
|
expect(ask.order?.price.gt(vAsk)).to.equal(true);
|
|
2127
3015
|
asks++;
|
|
2128
3016
|
}
|
|
@@ -2145,7 +3033,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2145
3033
|
expect(getVariant(bid.order?.status)).to.equal('open');
|
|
2146
3034
|
expect(getVariant(bid.order?.orderType)).to.equal('limit');
|
|
2147
3035
|
expect(getVariant(bid.order?.direction)).to.equal('long');
|
|
2148
|
-
expect(bid.order?.orderId
|
|
3036
|
+
expect(bid.order?.orderId).to.equal(bids + 1);
|
|
2149
3037
|
expect(bid.order?.price.lt(vBid)).to.equal(true);
|
|
2150
3038
|
bids++;
|
|
2151
3039
|
}
|
|
@@ -2156,7 +3044,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2156
3044
|
const vAsk = new BN(15);
|
|
2157
3045
|
const vBid = new BN(10);
|
|
2158
3046
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2159
|
-
const marketIndex =
|
|
3047
|
+
const marketIndex = 0;
|
|
2160
3048
|
|
|
2161
3049
|
// insert some limit buys above vamm bid, below ask
|
|
2162
3050
|
insertOrderToDLOB(
|
|
@@ -2164,7 +3052,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2164
3052
|
Keypair.generate().publicKey,
|
|
2165
3053
|
OrderType.LIMIT,
|
|
2166
3054
|
MarketType.SPOT,
|
|
2167
|
-
|
|
3055
|
+
1, // orderId
|
|
2168
3056
|
marketIndex,
|
|
2169
3057
|
new BN(11), // price
|
|
2170
3058
|
BASE_PRECISION, // quantity
|
|
@@ -2177,7 +3065,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2177
3065
|
Keypair.generate().publicKey,
|
|
2178
3066
|
OrderType.LIMIT,
|
|
2179
3067
|
MarketType.SPOT,
|
|
2180
|
-
|
|
3068
|
+
2, // orderId
|
|
2181
3069
|
marketIndex,
|
|
2182
3070
|
new BN(12), // price
|
|
2183
3071
|
BASE_PRECISION, // quantity
|
|
@@ -2190,7 +3078,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2190
3078
|
Keypair.generate().publicKey,
|
|
2191
3079
|
OrderType.LIMIT,
|
|
2192
3080
|
MarketType.SPOT,
|
|
2193
|
-
|
|
3081
|
+
3, // orderId
|
|
2194
3082
|
marketIndex,
|
|
2195
3083
|
new BN(13), // price
|
|
2196
3084
|
BASE_PRECISION, // quantity
|
|
@@ -2202,8 +3090,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2202
3090
|
// should have no crossing orders
|
|
2203
3091
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2204
3092
|
marketIndex,
|
|
2205
|
-
vBid,
|
|
2206
|
-
vAsk,
|
|
2207
3093
|
12, // auction over
|
|
2208
3094
|
MarketType.SPOT,
|
|
2209
3095
|
{
|
|
@@ -2221,7 +3107,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2221
3107
|
Keypair.generate().publicKey,
|
|
2222
3108
|
OrderType.MARKET,
|
|
2223
3109
|
MarketType.SPOT,
|
|
2224
|
-
|
|
3110
|
+
4, // orderId
|
|
2225
3111
|
marketIndex,
|
|
2226
3112
|
new BN(12), // price
|
|
2227
3113
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -2234,7 +3120,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2234
3120
|
Keypair.generate().publicKey,
|
|
2235
3121
|
OrderType.MARKET,
|
|
2236
3122
|
MarketType.SPOT,
|
|
2237
|
-
|
|
3123
|
+
5, // orderId
|
|
2238
3124
|
marketIndex,
|
|
2239
3125
|
new BN(12), // price
|
|
2240
3126
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -2245,8 +3131,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2245
3131
|
|
|
2246
3132
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2247
3133
|
marketIndex,
|
|
2248
|
-
vBid,
|
|
2249
|
-
vAsk,
|
|
2250
3134
|
12, // auction over
|
|
2251
3135
|
MarketType.SPOT,
|
|
2252
3136
|
{
|
|
@@ -2264,23 +3148,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2264
3148
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
2265
3149
|
|
|
2266
3150
|
// first taker should fill with best maker
|
|
2267
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
2268
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
2269
|
-
3
|
|
2270
|
-
);
|
|
3151
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
3152
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
2271
3153
|
|
|
2272
3154
|
// 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
|
-
);
|
|
3155
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
3156
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
2277
3157
|
});
|
|
2278
3158
|
|
|
2279
3159
|
it('Test one market order fills two limit orders', () => {
|
|
2280
3160
|
const vAsk = new BN(15);
|
|
2281
3161
|
const vBid = new BN(10);
|
|
2282
3162
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2283
|
-
const marketIndex =
|
|
3163
|
+
const marketIndex = 0;
|
|
2284
3164
|
|
|
2285
3165
|
// insert some limit sells below vAMM ask, above bid
|
|
2286
3166
|
insertOrderToDLOB(
|
|
@@ -2288,7 +3168,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2288
3168
|
Keypair.generate().publicKey,
|
|
2289
3169
|
OrderType.LIMIT,
|
|
2290
3170
|
MarketType.SPOT,
|
|
2291
|
-
|
|
3171
|
+
1, // orderId
|
|
2292
3172
|
marketIndex,
|
|
2293
3173
|
new BN(14), // price
|
|
2294
3174
|
BASE_PRECISION, // quantity
|
|
@@ -2301,7 +3181,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2301
3181
|
Keypair.generate().publicKey,
|
|
2302
3182
|
OrderType.LIMIT,
|
|
2303
3183
|
MarketType.SPOT,
|
|
2304
|
-
|
|
3184
|
+
2, // orderId
|
|
2305
3185
|
marketIndex,
|
|
2306
3186
|
new BN(12), // price
|
|
2307
3187
|
BASE_PRECISION, // quantity
|
|
@@ -2314,7 +3194,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2314
3194
|
Keypair.generate().publicKey,
|
|
2315
3195
|
OrderType.LIMIT,
|
|
2316
3196
|
MarketType.SPOT,
|
|
2317
|
-
|
|
3197
|
+
3, // orderId
|
|
2318
3198
|
marketIndex,
|
|
2319
3199
|
new BN(11), // price
|
|
2320
3200
|
BASE_PRECISION, // quantity
|
|
@@ -2326,8 +3206,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2326
3206
|
// should have no crossing orders
|
|
2327
3207
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2328
3208
|
marketIndex,
|
|
2329
|
-
vBid,
|
|
2330
|
-
vAsk,
|
|
2331
3209
|
12, // auction over
|
|
2332
3210
|
MarketType.SPOT,
|
|
2333
3211
|
{
|
|
@@ -2345,7 +3223,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2345
3223
|
Keypair.generate().publicKey,
|
|
2346
3224
|
OrderType.MARKET,
|
|
2347
3225
|
MarketType.SPOT,
|
|
2348
|
-
|
|
3226
|
+
4, // orderId
|
|
2349
3227
|
marketIndex,
|
|
2350
3228
|
new BN(12), // price
|
|
2351
3229
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -2356,8 +3234,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2356
3234
|
|
|
2357
3235
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2358
3236
|
marketIndex,
|
|
2359
|
-
vBid,
|
|
2360
|
-
vAsk,
|
|
2361
3237
|
12, // auction over
|
|
2362
3238
|
MarketType.SPOT,
|
|
2363
3239
|
{
|
|
@@ -2375,23 +3251,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2375
3251
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
2376
3252
|
|
|
2377
3253
|
// taker should fill completely with best maker
|
|
2378
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
2379
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
2380
|
-
3
|
|
2381
|
-
);
|
|
3254
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
3255
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
2382
3256
|
|
|
2383
3257
|
// 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
|
-
);
|
|
3258
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(4);
|
|
3259
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
|
|
2388
3260
|
});
|
|
2389
3261
|
|
|
2390
3262
|
it('Test two market orders to fill one limit order', () => {
|
|
2391
3263
|
const vAsk = new BN(15);
|
|
2392
3264
|
const vBid = new BN(8);
|
|
2393
3265
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2394
|
-
const marketIndex =
|
|
3266
|
+
const marketIndex = 0;
|
|
2395
3267
|
|
|
2396
3268
|
const slot = 12;
|
|
2397
3269
|
const oracle = {
|
|
@@ -2407,7 +3279,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2407
3279
|
Keypair.generate().publicKey,
|
|
2408
3280
|
OrderType.LIMIT,
|
|
2409
3281
|
MarketType.SPOT,
|
|
2410
|
-
|
|
3282
|
+
1, // orderId
|
|
2411
3283
|
marketIndex,
|
|
2412
3284
|
new BN(14), // price
|
|
2413
3285
|
BASE_PRECISION, // quantity
|
|
@@ -2420,7 +3292,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2420
3292
|
Keypair.generate().publicKey,
|
|
2421
3293
|
OrderType.LIMIT,
|
|
2422
3294
|
MarketType.SPOT,
|
|
2423
|
-
|
|
3295
|
+
2, // orderId
|
|
2424
3296
|
marketIndex,
|
|
2425
3297
|
new BN(13), // price
|
|
2426
3298
|
BASE_PRECISION, // quantity
|
|
@@ -2433,7 +3305,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2433
3305
|
Keypair.generate().publicKey,
|
|
2434
3306
|
OrderType.LIMIT,
|
|
2435
3307
|
MarketType.SPOT,
|
|
2436
|
-
|
|
3308
|
+
3, // orderId
|
|
2437
3309
|
marketIndex,
|
|
2438
3310
|
new BN(8), // price <-- best price
|
|
2439
3311
|
new BN(3).mul(BASE_PRECISION), // quantity
|
|
@@ -2445,8 +3317,6 @@ describe('DLOB Spot Tests', () => {
|
|
|
2445
3317
|
// should have no crossing orders
|
|
2446
3318
|
const nodesToFillBefore = dlob.findCrossingNodesToFill(
|
|
2447
3319
|
marketIndex,
|
|
2448
|
-
vBid,
|
|
2449
|
-
vAsk,
|
|
2450
3320
|
12, // auction over
|
|
2451
3321
|
MarketType.SPOT,
|
|
2452
3322
|
oracle
|
|
@@ -2459,7 +3329,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2459
3329
|
Keypair.generate().publicKey,
|
|
2460
3330
|
OrderType.MARKET,
|
|
2461
3331
|
MarketType.SPOT,
|
|
2462
|
-
|
|
3332
|
+
4, // orderId
|
|
2463
3333
|
marketIndex,
|
|
2464
3334
|
new BN(0), // price
|
|
2465
3335
|
new BN(1).mul(BASE_PRECISION), // quantity
|
|
@@ -2472,7 +3342,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2472
3342
|
Keypair.generate().publicKey,
|
|
2473
3343
|
OrderType.MARKET,
|
|
2474
3344
|
MarketType.SPOT,
|
|
2475
|
-
|
|
3345
|
+
5, // orderId
|
|
2476
3346
|
marketIndex,
|
|
2477
3347
|
new BN(0), // price
|
|
2478
3348
|
new BN(2).mul(BASE_PRECISION), // quantity
|
|
@@ -2483,62 +3353,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2483
3353
|
|
|
2484
3354
|
const nodesToFillAfter = dlob.findCrossingNodesToFill(
|
|
2485
3355
|
marketIndex,
|
|
2486
|
-
vBid,
|
|
2487
|
-
vAsk,
|
|
2488
3356
|
slot, // auction over
|
|
2489
3357
|
MarketType.SPOT,
|
|
2490
3358
|
oracle
|
|
2491
3359
|
);
|
|
2492
|
-
const mktNodes = dlob.
|
|
3360
|
+
const mktNodes = dlob.findExpiredMarketNodesToFill(
|
|
2493
3361
|
marketIndex,
|
|
2494
3362
|
slot,
|
|
2495
3363
|
MarketType.SPOT
|
|
2496
3364
|
);
|
|
2497
3365
|
console.log(`market nodes: ${mktNodes.length}`);
|
|
2498
3366
|
|
|
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);
|
|
3367
|
+
printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
|
|
2540
3368
|
|
|
2541
|
-
console.log(`bids nodes: ${bb}`);
|
|
2542
3369
|
for (const n of nodesToFillAfter) {
|
|
2543
3370
|
console.log(
|
|
2544
3371
|
`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 +3374,19 @@ describe('DLOB Spot Tests', () => {
|
|
|
2547
3374
|
expect(nodesToFillAfter.length).to.equal(2);
|
|
2548
3375
|
|
|
2549
3376
|
// taker should fill completely with best maker
|
|
2550
|
-
expect(nodesToFillAfter[0].node.order?.orderId
|
|
2551
|
-
expect(nodesToFillAfter[0].makerNode?.order?.orderId
|
|
2552
|
-
3
|
|
2553
|
-
);
|
|
3377
|
+
expect(nodesToFillAfter[0].node.order?.orderId).to.equal(4);
|
|
3378
|
+
expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(3);
|
|
2554
3379
|
|
|
2555
3380
|
// 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
|
-
);
|
|
3381
|
+
expect(nodesToFillAfter[1].node.order?.orderId).to.equal(5);
|
|
3382
|
+
expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
|
|
2560
3383
|
});
|
|
2561
3384
|
|
|
2562
3385
|
it('Test trigger orders', () => {
|
|
2563
3386
|
const vAsk = new BN(15);
|
|
2564
3387
|
const vBid = new BN(8);
|
|
2565
3388
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2566
|
-
const marketIndex =
|
|
3389
|
+
const marketIndex = 0;
|
|
2567
3390
|
|
|
2568
3391
|
const slot = 20;
|
|
2569
3392
|
const oracle = {
|
|
@@ -2582,7 +3405,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2582
3405
|
Keypair.generate().publicKey,
|
|
2583
3406
|
OrderType.TRIGGER_LIMIT,
|
|
2584
3407
|
MarketType.SPOT,
|
|
2585
|
-
|
|
3408
|
+
1, //orderId
|
|
2586
3409
|
marketIndex, // marketIndex
|
|
2587
3410
|
vBid, // price
|
|
2588
3411
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2598,7 +3421,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2598
3421
|
Keypair.generate().publicKey,
|
|
2599
3422
|
OrderType.TRIGGER_LIMIT,
|
|
2600
3423
|
MarketType.SPOT,
|
|
2601
|
-
|
|
3424
|
+
2, //orderId
|
|
2602
3425
|
marketIndex, // marketIndex
|
|
2603
3426
|
vBid, // price
|
|
2604
3427
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2614,7 +3437,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2614
3437
|
Keypair.generate().publicKey,
|
|
2615
3438
|
OrderType.TRIGGER_MARKET,
|
|
2616
3439
|
MarketType.SPOT,
|
|
2617
|
-
|
|
3440
|
+
3, //orderId
|
|
2618
3441
|
marketIndex, // marketIndex
|
|
2619
3442
|
vAsk, // price
|
|
2620
3443
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2630,7 +3453,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2630
3453
|
Keypair.generate().publicKey,
|
|
2631
3454
|
OrderType.TRIGGER_MARKET,
|
|
2632
3455
|
MarketType.SPOT,
|
|
2633
|
-
|
|
3456
|
+
4, //orderId
|
|
2634
3457
|
marketIndex, // marketIndex
|
|
2635
3458
|
vBid, // price
|
|
2636
3459
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2646,7 +3469,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2646
3469
|
Keypair.generate().publicKey,
|
|
2647
3470
|
OrderType.TRIGGER_LIMIT,
|
|
2648
3471
|
MarketType.SPOT,
|
|
2649
|
-
|
|
3472
|
+
5, //orderId
|
|
2650
3473
|
marketIndex, // marketIndex
|
|
2651
3474
|
vBid, // price
|
|
2652
3475
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2662,7 +3485,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2662
3485
|
Keypair.generate().publicKey,
|
|
2663
3486
|
OrderType.TRIGGER_LIMIT,
|
|
2664
3487
|
MarketType.SPOT,
|
|
2665
|
-
|
|
3488
|
+
6, //orderId
|
|
2666
3489
|
marketIndex, // marketIndex
|
|
2667
3490
|
vBid, // price
|
|
2668
3491
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2678,7 +3501,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2678
3501
|
Keypair.generate().publicKey,
|
|
2679
3502
|
OrderType.TRIGGER_MARKET,
|
|
2680
3503
|
MarketType.SPOT,
|
|
2681
|
-
|
|
3504
|
+
7, //orderId
|
|
2682
3505
|
marketIndex, // marketIndex
|
|
2683
3506
|
vBid, // price
|
|
2684
3507
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2694,7 +3517,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2694
3517
|
Keypair.generate().publicKey,
|
|
2695
3518
|
OrderType.TRIGGER_MARKET,
|
|
2696
3519
|
MarketType.SPOT,
|
|
2697
|
-
|
|
3520
|
+
8, //orderId
|
|
2698
3521
|
marketIndex, // marketIndex
|
|
2699
3522
|
vBid, // price
|
|
2700
3523
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2711,7 +3534,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2711
3534
|
Keypair.generate().publicKey,
|
|
2712
3535
|
OrderType.TRIGGER_MARKET,
|
|
2713
3536
|
MarketType.SPOT,
|
|
2714
|
-
|
|
3537
|
+
9, //orderId
|
|
2715
3538
|
marketIndex, // marketIndex
|
|
2716
3539
|
vBid, // price
|
|
2717
3540
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2727,7 +3550,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2727
3550
|
Keypair.generate().publicKey,
|
|
2728
3551
|
OrderType.TRIGGER_MARKET,
|
|
2729
3552
|
MarketType.SPOT,
|
|
2730
|
-
|
|
3553
|
+
10, //orderId
|
|
2731
3554
|
marketIndex, // marketIndex
|
|
2732
3555
|
vBid, // price
|
|
2733
3556
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2743,7 +3566,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2743
3566
|
Keypair.generate().publicKey,
|
|
2744
3567
|
OrderType.TRIGGER_MARKET,
|
|
2745
3568
|
MarketType.SPOT,
|
|
2746
|
-
|
|
3569
|
+
11, //orderId
|
|
2747
3570
|
marketIndex, // marketIndex
|
|
2748
3571
|
vBid, // price
|
|
2749
3572
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2759,7 +3582,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2759
3582
|
Keypair.generate().publicKey,
|
|
2760
3583
|
OrderType.TRIGGER_MARKET,
|
|
2761
3584
|
MarketType.SPOT,
|
|
2762
|
-
|
|
3585
|
+
12, //orderId
|
|
2763
3586
|
marketIndex, // marketIndex
|
|
2764
3587
|
vBid, // price
|
|
2765
3588
|
BASE_PRECISION, // baseAssetAmount: BN,
|
|
@@ -2778,8 +3601,8 @@ describe('DLOB Spot Tests', () => {
|
|
|
2778
3601
|
);
|
|
2779
3602
|
console.log(`nodesToTriggeR: ${nodesToTrigger.length}`);
|
|
2780
3603
|
for (const [idx, n] of nodesToTrigger.entries()) {
|
|
2781
|
-
expect(n.node.order?.orderId
|
|
2782
|
-
console.log(`nodeToTrigger: ${n.node.order?.orderId
|
|
3604
|
+
expect(n.node.order?.orderId).to.equal(orderIdsToTrigger[idx]);
|
|
3605
|
+
console.log(`nodeToTrigger: ${n.node.order?.orderId}`);
|
|
2783
3606
|
}
|
|
2784
3607
|
});
|
|
2785
3608
|
|
|
@@ -2787,7 +3610,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2787
3610
|
const vAsk = new BN(15);
|
|
2788
3611
|
const vBid = new BN(8);
|
|
2789
3612
|
const dlob = new DLOB(mockPerpMarkets, mockSpotMarkets, false);
|
|
2790
|
-
const marketIndex =
|
|
3613
|
+
const marketIndex = 0;
|
|
2791
3614
|
|
|
2792
3615
|
const slot = 20;
|
|
2793
3616
|
const timeInForce = 30;
|
|
@@ -2798,7 +3621,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2798
3621
|
Keypair.generate().publicKey,
|
|
2799
3622
|
OrderType.MARKET,
|
|
2800
3623
|
MarketType.SPOT,
|
|
2801
|
-
|
|
3624
|
+
255, // orderId
|
|
2802
3625
|
marketIndex,
|
|
2803
3626
|
new BN(2), // price, very low, don't cross vamm
|
|
2804
3627
|
BASE_PRECISION, // quantity
|
|
@@ -2813,7 +3636,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2813
3636
|
Keypair.generate().publicKey,
|
|
2814
3637
|
OrderType.MARKET,
|
|
2815
3638
|
MarketType.SPOT,
|
|
2816
|
-
|
|
3639
|
+
2, // orderId
|
|
2817
3640
|
marketIndex,
|
|
2818
3641
|
new BN(30), // price, very high, don't cross vamm
|
|
2819
3642
|
BASE_PRECISION, // quantity
|
|
@@ -2842,7 +3665,7 @@ describe('DLOB Spot Tests', () => {
|
|
|
2842
3665
|
expect(nodesToFillBefore.length).to.equal(0);
|
|
2843
3666
|
|
|
2844
3667
|
// should get order to fill after timeInForce
|
|
2845
|
-
const slot1 = slot0 + timeInForce; // overshoots expiry
|
|
3668
|
+
const slot1 = slot0 + timeInForce * 2; // overshoots expiry
|
|
2846
3669
|
const nodesToFillAfter = dlob.findNodesToFill(
|
|
2847
3670
|
marketIndex,
|
|
2848
3671
|
vBid,
|