@drift-labs/sdk 2.41.0-beta.0 → 2.41.0-beta.2
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/README.md +0 -1
- package/VERSION +1 -1
- package/bun.lockb +0 -0
- package/lib/accounts/types.d.ts +5 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -1
- package/lib/accounts/webSocketAccountSubscriber.js +28 -2
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +2 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +6 -5
- package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +32 -0
- package/lib/accounts/webSocketProgramAccountSubscriber.js +99 -0
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +2 -1
- package/lib/accounts/webSocketUserAccountSubscriber.js +3 -2
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +2 -1
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +3 -2
- package/lib/addresses/pda.d.ts +1 -0
- package/lib/addresses/pda.js +5 -1
- package/lib/adminClient.d.ts +2 -0
- package/lib/adminClient.js +20 -0
- package/lib/auctionSubscriber/auctionSubscriber.d.ts +3 -2
- package/lib/auctionSubscriber/auctionSubscriber.js +15 -7
- package/lib/auctionSubscriber/types.d.ts +1 -0
- package/lib/dlob/DLOB.d.ts +2 -6
- package/lib/dlob/DLOB.js +9 -11
- package/lib/dlob/DLOBSubscriber.js +4 -7
- package/lib/dlob/orderBookLevels.d.ts +4 -2
- package/lib/dlob/orderBookLevels.js +79 -16
- package/lib/driftClient.d.ts +2 -1
- package/lib/driftClient.js +13 -14
- package/lib/driftClientConfig.d.ts +1 -0
- package/lib/factory/bigNum.js +4 -2
- package/lib/idl/drift.json +222 -2
- package/lib/jupiter/jupiterClient.d.ts +4 -1
- package/lib/jupiter/jupiterClient.js +4 -1
- package/lib/math/amm.js +7 -2
- package/lib/math/auction.d.ts +12 -1
- package/lib/math/auction.js +22 -1
- package/lib/math/market.js +2 -4
- package/lib/math/superStake.d.ts +51 -4
- package/lib/math/superStake.js +173 -21
- package/lib/math/trade.js +2 -4
- package/lib/math/utils.d.ts +1 -0
- package/lib/math/utils.js +10 -1
- package/lib/orderSubscriber/OrderSubscriber.d.ts +1 -3
- package/lib/orderSubscriber/OrderSubscriber.js +4 -3
- package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -2
- package/lib/orderSubscriber/WebsocketSubscription.js +15 -12
- package/lib/orderSubscriber/types.d.ts +1 -0
- package/lib/user.d.ts +2 -2
- package/lib/user.js +5 -5
- package/package.json +2 -1
- package/src/accounts/types.ts +8 -1
- package/src/accounts/webSocketAccountSubscriber.ts +36 -2
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +15 -5
- package/src/accounts/webSocketProgramAccountSubscriber.ts +152 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +10 -2
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +10 -2
- package/src/addresses/pda.ts +9 -0
- package/src/adminClient.ts +32 -0
- package/src/auctionSubscriber/auctionSubscriber.ts +30 -21
- package/src/auctionSubscriber/types.ts +1 -0
- package/src/dlob/DLOB.ts +9 -32
- package/src/dlob/DLOBSubscriber.ts +8 -7
- package/src/dlob/orderBookLevels.ts +133 -32
- package/src/driftClient.ts +14 -16
- package/src/driftClientConfig.ts +1 -0
- package/src/factory/bigNum.ts +2 -0
- package/src/idl/drift.json +222 -2
- package/src/jupiter/jupiterClient.ts +6 -0
- package/src/math/amm.ts +9 -2
- package/src/math/auction.ts +36 -2
- package/src/math/market.ts +4 -9
- package/src/math/superStake.ts +247 -23
- package/src/math/trade.ts +3 -11
- package/src/math/utils.ts +12 -0
- package/src/orderSubscriber/OrderSubscriber.ts +12 -7
- package/src/orderSubscriber/WebsocketSubscription.ts +34 -23
- package/src/orderSubscriber/types.ts +1 -0
- package/src/user.ts +7 -5
- package/tests/amm/test.ts +402 -0
- package/tests/auctions/test.ts +66 -0
- package/tests/dlob/test.ts +1 -73
package/src/user.ts
CHANGED
|
@@ -1465,8 +1465,10 @@ export class User {
|
|
|
1465
1465
|
* calculates current user leverage which is (total liability size) / (net asset value)
|
|
1466
1466
|
* @returns : Precision TEN_THOUSAND
|
|
1467
1467
|
*/
|
|
1468
|
-
public getLeverage(): BN {
|
|
1469
|
-
return this.calculateLeverageFromComponents(
|
|
1468
|
+
public getLeverage(includeOpenOrders = true): BN {
|
|
1469
|
+
return this.calculateLeverageFromComponents(
|
|
1470
|
+
this.getLeverageComponents(includeOpenOrders)
|
|
1471
|
+
);
|
|
1470
1472
|
}
|
|
1471
1473
|
|
|
1472
1474
|
calculateLeverageFromComponents({
|
|
@@ -1491,7 +1493,7 @@ export class User {
|
|
|
1491
1493
|
return totalLiabilityValue.mul(TEN_THOUSAND).div(netAssetValue);
|
|
1492
1494
|
}
|
|
1493
1495
|
|
|
1494
|
-
getLeverageComponents(): {
|
|
1496
|
+
getLeverageComponents(includeOpenOrders = true): {
|
|
1495
1497
|
perpLiabilityValue: BN;
|
|
1496
1498
|
perpPnl: BN;
|
|
1497
1499
|
spotAssetValue: BN;
|
|
@@ -1500,7 +1502,7 @@ export class User {
|
|
|
1500
1502
|
const perpLiability = this.getTotalPerpPositionValue(
|
|
1501
1503
|
undefined,
|
|
1502
1504
|
undefined,
|
|
1503
|
-
|
|
1505
|
+
includeOpenOrders
|
|
1504
1506
|
);
|
|
1505
1507
|
const perpPnl = this.getUnrealizedPNL(true);
|
|
1506
1508
|
|
|
@@ -1511,7 +1513,7 @@ export class User {
|
|
|
1511
1513
|
undefined,
|
|
1512
1514
|
undefined,
|
|
1513
1515
|
undefined,
|
|
1514
|
-
|
|
1516
|
+
includeOpenOrders
|
|
1515
1517
|
);
|
|
1516
1518
|
|
|
1517
1519
|
return {
|
package/tests/amm/test.ts
CHANGED
|
@@ -13,6 +13,12 @@ import {
|
|
|
13
13
|
calculateAllEstimatedFundingRate,
|
|
14
14
|
calculateLongShortFundingRateAndLiveTwaps,
|
|
15
15
|
OraclePriceData,
|
|
16
|
+
getVammL2Generator,
|
|
17
|
+
BASE_PRECISION,
|
|
18
|
+
PerpMarketAccount,
|
|
19
|
+
L2Level,
|
|
20
|
+
calculateUpdatedAMM,
|
|
21
|
+
calculateMarketOpenBidAsk,
|
|
16
22
|
} from '../../src';
|
|
17
23
|
import { mockPerpMarkets } from '../dlob/helpers';
|
|
18
24
|
|
|
@@ -552,4 +558,400 @@ describe('AMM Tests', () => {
|
|
|
552
558
|
assert(est1.eq(est2));
|
|
553
559
|
assert(est2.eq(new BN('-1550')));
|
|
554
560
|
});
|
|
561
|
+
|
|
562
|
+
it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders, low liquidity)', async () => {
|
|
563
|
+
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
564
|
+
|
|
565
|
+
const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
|
|
566
|
+
const cc = 38104569;
|
|
567
|
+
mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
568
|
+
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(
|
|
569
|
+
new BN(1234835)
|
|
570
|
+
);
|
|
571
|
+
mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.sub(BASE_PRECISION);
|
|
572
|
+
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
573
|
+
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
574
|
+
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
|
575
|
+
|
|
576
|
+
const now = new BN(1688881915);
|
|
577
|
+
|
|
578
|
+
const oraclePriceData: OraclePriceData = {
|
|
579
|
+
price: new BN(18.624 * PRICE_PRECISION.toNumber()),
|
|
580
|
+
slot: new BN(0),
|
|
581
|
+
confidence: new BN(1),
|
|
582
|
+
hasSufficientNumberOfDataPoints: true,
|
|
583
|
+
};
|
|
584
|
+
mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
|
|
585
|
+
18.5535 * PRICE_PRECISION.toNumber()
|
|
586
|
+
);
|
|
587
|
+
|
|
588
|
+
const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, oraclePriceData);
|
|
589
|
+
|
|
590
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
591
|
+
updatedAmm.baseAssetReserve,
|
|
592
|
+
updatedAmm.minBaseAssetReserve,
|
|
593
|
+
updatedAmm.maxBaseAssetReserve,
|
|
594
|
+
updatedAmm.orderStepSize
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
const generator = getVammL2Generator({
|
|
598
|
+
marketAccount: mockMarket1,
|
|
599
|
+
oraclePriceData,
|
|
600
|
+
numOrders: 10,
|
|
601
|
+
now,
|
|
602
|
+
topOfBookQuoteAmounts: [],
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
const bids = Array.from(generator.getL2Bids());
|
|
606
|
+
// console.log(bids);
|
|
607
|
+
|
|
608
|
+
const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
|
|
609
|
+
return total.add(order.size);
|
|
610
|
+
}, ZERO);
|
|
611
|
+
|
|
612
|
+
console.log(
|
|
613
|
+
'totalBidSize:',
|
|
614
|
+
totalBidSize.toString(),
|
|
615
|
+
'openBids:',
|
|
616
|
+
openBids.toString()
|
|
617
|
+
);
|
|
618
|
+
assert(totalBidSize.sub(openBids).abs().lt(new BN(10))); // smol err
|
|
619
|
+
assert(totalBidSize.sub(openBids).lt(ZERO)); // under estimation
|
|
620
|
+
|
|
621
|
+
const asks = Array.from(generator.getL2Asks());
|
|
622
|
+
// console.log(asks);
|
|
623
|
+
|
|
624
|
+
const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
|
|
625
|
+
return total.add(order.size);
|
|
626
|
+
}, ZERO);
|
|
627
|
+
console.log(
|
|
628
|
+
'totalAskSize:',
|
|
629
|
+
totalAskSize.toString(),
|
|
630
|
+
'openAsks:',
|
|
631
|
+
openAsks.toString()
|
|
632
|
+
);
|
|
633
|
+
assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders)', async () => {
|
|
637
|
+
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
638
|
+
|
|
639
|
+
const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
|
|
640
|
+
const cc = 38104569;
|
|
641
|
+
mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
642
|
+
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.mul(
|
|
643
|
+
new BN(2)
|
|
644
|
+
);
|
|
645
|
+
mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.div(
|
|
646
|
+
new BN(2)
|
|
647
|
+
);
|
|
648
|
+
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
649
|
+
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
650
|
+
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
|
651
|
+
|
|
652
|
+
const now = new BN(1688881915);
|
|
653
|
+
|
|
654
|
+
const oraclePriceData: OraclePriceData = {
|
|
655
|
+
price: new BN(18.624 * PRICE_PRECISION.toNumber()),
|
|
656
|
+
slot: new BN(0),
|
|
657
|
+
confidence: new BN(1),
|
|
658
|
+
hasSufficientNumberOfDataPoints: true,
|
|
659
|
+
};
|
|
660
|
+
mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
|
|
661
|
+
18.5535 * PRICE_PRECISION.toNumber()
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, oraclePriceData);
|
|
665
|
+
|
|
666
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
667
|
+
updatedAmm.baseAssetReserve,
|
|
668
|
+
updatedAmm.minBaseAssetReserve,
|
|
669
|
+
updatedAmm.maxBaseAssetReserve,
|
|
670
|
+
updatedAmm.orderStepSize
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
const generator = getVammL2Generator({
|
|
674
|
+
marketAccount: mockMarket1,
|
|
675
|
+
oraclePriceData,
|
|
676
|
+
numOrders: 10,
|
|
677
|
+
now,
|
|
678
|
+
topOfBookQuoteAmounts: [],
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
const bids = Array.from(generator.getL2Bids());
|
|
682
|
+
// console.log(bids);
|
|
683
|
+
|
|
684
|
+
const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
|
|
685
|
+
return total.add(order.size);
|
|
686
|
+
}, ZERO);
|
|
687
|
+
|
|
688
|
+
console.log(
|
|
689
|
+
'totalBidSize:',
|
|
690
|
+
totalBidSize.toString(),
|
|
691
|
+
'openBids:',
|
|
692
|
+
openBids.toString()
|
|
693
|
+
);
|
|
694
|
+
assert(totalBidSize.eq(openBids));
|
|
695
|
+
|
|
696
|
+
const asks = Array.from(generator.getL2Asks());
|
|
697
|
+
// console.log(asks);
|
|
698
|
+
|
|
699
|
+
const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
|
|
700
|
+
return total.add(order.size);
|
|
701
|
+
}, ZERO);
|
|
702
|
+
console.log(
|
|
703
|
+
'totalAskSize:',
|
|
704
|
+
totalAskSize.toString(),
|
|
705
|
+
'openAsks:',
|
|
706
|
+
openAsks.toString()
|
|
707
|
+
);
|
|
708
|
+
assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
it('orderbook L2 gen (4 topOfBookQuoteAmounts, 10 numOrders)', async () => {
|
|
712
|
+
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
713
|
+
|
|
714
|
+
const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
|
|
715
|
+
const cc = 38104569;
|
|
716
|
+
mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
717
|
+
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.mul(
|
|
718
|
+
new BN(2)
|
|
719
|
+
);
|
|
720
|
+
mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.div(
|
|
721
|
+
new BN(2)
|
|
722
|
+
);
|
|
723
|
+
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
724
|
+
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
725
|
+
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
|
726
|
+
|
|
727
|
+
const now = new BN(1688881915);
|
|
728
|
+
|
|
729
|
+
const oraclePriceData: OraclePriceData = {
|
|
730
|
+
price: new BN(18.624 * PRICE_PRECISION.toNumber()),
|
|
731
|
+
slot: new BN(0),
|
|
732
|
+
confidence: new BN(1),
|
|
733
|
+
hasSufficientNumberOfDataPoints: true,
|
|
734
|
+
};
|
|
735
|
+
mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
|
|
736
|
+
18.5535 * PRICE_PRECISION.toNumber()
|
|
737
|
+
);
|
|
738
|
+
|
|
739
|
+
const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, oraclePriceData);
|
|
740
|
+
|
|
741
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
742
|
+
updatedAmm.baseAssetReserve,
|
|
743
|
+
updatedAmm.minBaseAssetReserve,
|
|
744
|
+
updatedAmm.maxBaseAssetReserve,
|
|
745
|
+
updatedAmm.orderStepSize
|
|
746
|
+
);
|
|
747
|
+
|
|
748
|
+
assert(!openAsks.eq(openBids));
|
|
749
|
+
|
|
750
|
+
const generator = getVammL2Generator({
|
|
751
|
+
marketAccount: mockMarket1,
|
|
752
|
+
oraclePriceData,
|
|
753
|
+
numOrders: 10,
|
|
754
|
+
now,
|
|
755
|
+
topOfBookQuoteAmounts: [
|
|
756
|
+
new BN(10).mul(QUOTE_PRECISION),
|
|
757
|
+
new BN(100).mul(QUOTE_PRECISION),
|
|
758
|
+
new BN(1000).mul(QUOTE_PRECISION),
|
|
759
|
+
new BN(10000).mul(QUOTE_PRECISION),
|
|
760
|
+
],
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
const bids = Array.from(generator.getL2Bids());
|
|
764
|
+
// console.log(bids);
|
|
765
|
+
|
|
766
|
+
const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
|
|
767
|
+
return total.add(order.size);
|
|
768
|
+
}, ZERO);
|
|
769
|
+
|
|
770
|
+
console.log(
|
|
771
|
+
'totalBidSize:',
|
|
772
|
+
totalBidSize.toString(),
|
|
773
|
+
'openBids:',
|
|
774
|
+
openBids.toString()
|
|
775
|
+
);
|
|
776
|
+
assert(totalBidSize.eq(openBids));
|
|
777
|
+
|
|
778
|
+
const asks = Array.from(generator.getL2Asks());
|
|
779
|
+
// console.log(asks);
|
|
780
|
+
|
|
781
|
+
const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
|
|
782
|
+
return total.add(order.size);
|
|
783
|
+
}, ZERO);
|
|
784
|
+
console.log(
|
|
785
|
+
'totalAskSize:',
|
|
786
|
+
totalAskSize.toString(),
|
|
787
|
+
'openAsks:',
|
|
788
|
+
openAsks.toString()
|
|
789
|
+
);
|
|
790
|
+
assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
it('orderbook L2 gen (4 topOfBookQuoteAmounts, 10 numOrders, low bid liquidity)', async () => {
|
|
795
|
+
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
796
|
+
|
|
797
|
+
const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
|
|
798
|
+
const cc = 38104569;
|
|
799
|
+
mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
800
|
+
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(BASE_PRECISION); // only 1 base
|
|
801
|
+
mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.div(
|
|
802
|
+
new BN(2)
|
|
803
|
+
);
|
|
804
|
+
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
805
|
+
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
806
|
+
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
|
807
|
+
|
|
808
|
+
const now = new BN(1688881915);
|
|
809
|
+
|
|
810
|
+
const oraclePriceData: OraclePriceData = {
|
|
811
|
+
price: new BN(18.624 * PRICE_PRECISION.toNumber()),
|
|
812
|
+
slot: new BN(0),
|
|
813
|
+
confidence: new BN(1),
|
|
814
|
+
hasSufficientNumberOfDataPoints: true,
|
|
815
|
+
};
|
|
816
|
+
mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
|
|
817
|
+
18.5535 * PRICE_PRECISION.toNumber()
|
|
818
|
+
);
|
|
819
|
+
|
|
820
|
+
const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, oraclePriceData);
|
|
821
|
+
|
|
822
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
823
|
+
updatedAmm.baseAssetReserve,
|
|
824
|
+
updatedAmm.minBaseAssetReserve,
|
|
825
|
+
updatedAmm.maxBaseAssetReserve,
|
|
826
|
+
updatedAmm.orderStepSize
|
|
827
|
+
);
|
|
828
|
+
|
|
829
|
+
assert(!openAsks.eq(openBids));
|
|
830
|
+
|
|
831
|
+
const generator = getVammL2Generator({
|
|
832
|
+
marketAccount: mockMarket1,
|
|
833
|
+
oraclePriceData,
|
|
834
|
+
numOrders: 10,
|
|
835
|
+
now,
|
|
836
|
+
topOfBookQuoteAmounts: [
|
|
837
|
+
new BN(10).mul(QUOTE_PRECISION),
|
|
838
|
+
new BN(100).mul(QUOTE_PRECISION),
|
|
839
|
+
new BN(1000).mul(QUOTE_PRECISION),
|
|
840
|
+
new BN(10000).mul(QUOTE_PRECISION),
|
|
841
|
+
],
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
const bids = Array.from(generator.getL2Bids());
|
|
845
|
+
assert(bids.length == 2);
|
|
846
|
+
console.log(bids[0].size.toString());
|
|
847
|
+
console.log(bids[1].size.toString());
|
|
848
|
+
|
|
849
|
+
const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
|
|
850
|
+
return total.add(order.size);
|
|
851
|
+
}, ZERO);
|
|
852
|
+
|
|
853
|
+
console.log(
|
|
854
|
+
'totalBidSize:',
|
|
855
|
+
totalBidSize.toString(),
|
|
856
|
+
'openBids:',
|
|
857
|
+
openBids.toString()
|
|
858
|
+
);
|
|
859
|
+
assert(totalBidSize.eq(openBids));
|
|
860
|
+
|
|
861
|
+
const asks = Array.from(generator.getL2Asks());
|
|
862
|
+
// console.log(asks);
|
|
863
|
+
|
|
864
|
+
const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
|
|
865
|
+
return total.add(order.size);
|
|
866
|
+
}, ZERO);
|
|
867
|
+
console.log(
|
|
868
|
+
'totalAskSize:',
|
|
869
|
+
totalAskSize.toString(),
|
|
870
|
+
'openAsks:',
|
|
871
|
+
openAsks.toString()
|
|
872
|
+
);
|
|
873
|
+
assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
it('orderbook L2 gen (4 topOfBookQuoteAmounts, 10 numOrders, low ask liquidity)', async () => {
|
|
878
|
+
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
879
|
+
|
|
880
|
+
const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
|
|
881
|
+
const cc = 38104569;
|
|
882
|
+
mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
883
|
+
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(BASE_PRECISION.mul(new BN(1000))); // 1000 base
|
|
884
|
+
mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.sub(
|
|
885
|
+
BASE_PRECISION.div(new BN(2))
|
|
886
|
+
); // only .5 base
|
|
887
|
+
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
888
|
+
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
889
|
+
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
|
890
|
+
|
|
891
|
+
const now = new BN(1688881915);
|
|
892
|
+
|
|
893
|
+
const oraclePriceData: OraclePriceData = {
|
|
894
|
+
price: new BN(18.624 * PRICE_PRECISION.toNumber()),
|
|
895
|
+
slot: new BN(0),
|
|
896
|
+
confidence: new BN(1),
|
|
897
|
+
hasSufficientNumberOfDataPoints: true,
|
|
898
|
+
};
|
|
899
|
+
mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
|
|
900
|
+
18.5535 * PRICE_PRECISION.toNumber()
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, oraclePriceData);
|
|
904
|
+
|
|
905
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
906
|
+
updatedAmm.baseAssetReserve,
|
|
907
|
+
updatedAmm.minBaseAssetReserve,
|
|
908
|
+
updatedAmm.maxBaseAssetReserve,
|
|
909
|
+
updatedAmm.orderStepSize
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
assert(!openAsks.eq(openBids));
|
|
913
|
+
|
|
914
|
+
const generator = getVammL2Generator({
|
|
915
|
+
marketAccount: mockMarket1,
|
|
916
|
+
oraclePriceData,
|
|
917
|
+
numOrders: 10,
|
|
918
|
+
now,
|
|
919
|
+
topOfBookQuoteAmounts: [
|
|
920
|
+
new BN(10).mul(QUOTE_PRECISION),
|
|
921
|
+
new BN(100).mul(QUOTE_PRECISION),
|
|
922
|
+
new BN(1000).mul(QUOTE_PRECISION),
|
|
923
|
+
new BN(10000).mul(QUOTE_PRECISION),
|
|
924
|
+
],
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
const bids = Array.from(generator.getL2Bids());
|
|
928
|
+
|
|
929
|
+
const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
|
|
930
|
+
return total.add(order.size);
|
|
931
|
+
}, ZERO);
|
|
932
|
+
|
|
933
|
+
console.log(
|
|
934
|
+
'totalBidSize:',
|
|
935
|
+
totalBidSize.toString(),
|
|
936
|
+
'openBids:',
|
|
937
|
+
openBids.toString()
|
|
938
|
+
);
|
|
939
|
+
assert(totalBidSize.sub(openBids).abs().lt(new BN(5)));
|
|
940
|
+
|
|
941
|
+
const asks = Array.from(generator.getL2Asks());
|
|
942
|
+
// console.log(asks);
|
|
943
|
+
|
|
944
|
+
assert(asks.length == 1);
|
|
945
|
+
console.log(asks[0].size.toString());
|
|
946
|
+
const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
|
|
947
|
+
return total.add(order.size);
|
|
948
|
+
}, ZERO);
|
|
949
|
+
console.log(
|
|
950
|
+
'totalAskSize:',
|
|
951
|
+
totalAskSize.toString(),
|
|
952
|
+
'openAsks:',
|
|
953
|
+
openAsks.toString()
|
|
954
|
+
);
|
|
955
|
+
assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
|
|
956
|
+
});
|
|
555
957
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {PRICE_PRECISION, BN, deriveOracleAuctionParams} from "../../src";
|
|
2
|
+
import {assert} from "chai";
|
|
3
|
+
import {PositionDirection} from "../../lib";
|
|
4
|
+
|
|
5
|
+
describe('Auction Tests', () => {
|
|
6
|
+
|
|
7
|
+
it('deriveOracleAuctionParams', async () => {
|
|
8
|
+
let oraclePrice = new BN(100).mul(PRICE_PRECISION);
|
|
9
|
+
let auctionStartPrice = new BN(90).mul(PRICE_PRECISION);
|
|
10
|
+
let auctionEndPrice = new BN(110).mul(PRICE_PRECISION);
|
|
11
|
+
let limitPrice = new BN(120).mul(PRICE_PRECISION);
|
|
12
|
+
|
|
13
|
+
let oracleOrderParams = deriveOracleAuctionParams({
|
|
14
|
+
direction: PositionDirection.LONG,
|
|
15
|
+
oraclePrice,
|
|
16
|
+
auctionStartPrice,
|
|
17
|
+
auctionEndPrice,
|
|
18
|
+
limitPrice,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
assert(oracleOrderParams.auctionStartPrice.eq(new BN(-10).mul(PRICE_PRECISION)));
|
|
22
|
+
assert(oracleOrderParams.auctionEndPrice.eq(new BN(10).mul(PRICE_PRECISION)));
|
|
23
|
+
assert(oracleOrderParams.oraclePriceOffset === 20 * PRICE_PRECISION.toNumber());
|
|
24
|
+
|
|
25
|
+
oracleOrderParams = deriveOracleAuctionParams({
|
|
26
|
+
direction: PositionDirection.LONG,
|
|
27
|
+
oraclePrice,
|
|
28
|
+
auctionStartPrice: oraclePrice,
|
|
29
|
+
auctionEndPrice: oraclePrice,
|
|
30
|
+
limitPrice: oraclePrice,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
assert(oracleOrderParams.auctionStartPrice.eq(new BN(0)));
|
|
34
|
+
assert(oracleOrderParams.auctionEndPrice.eq(new BN(0)));
|
|
35
|
+
assert(oracleOrderParams.oraclePriceOffset === 1);
|
|
36
|
+
|
|
37
|
+
oraclePrice = new BN(100).mul(PRICE_PRECISION);
|
|
38
|
+
auctionStartPrice = new BN(110).mul(PRICE_PRECISION);
|
|
39
|
+
auctionEndPrice = new BN(90).mul(PRICE_PRECISION);
|
|
40
|
+
limitPrice = new BN(80).mul(PRICE_PRECISION);
|
|
41
|
+
|
|
42
|
+
oracleOrderParams = deriveOracleAuctionParams({
|
|
43
|
+
direction: PositionDirection.SHORT,
|
|
44
|
+
oraclePrice,
|
|
45
|
+
auctionStartPrice,
|
|
46
|
+
auctionEndPrice,
|
|
47
|
+
limitPrice,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
assert(oracleOrderParams.auctionStartPrice.eq(new BN(10).mul(PRICE_PRECISION)));
|
|
51
|
+
assert(oracleOrderParams.auctionEndPrice.eq(new BN(-10).mul(PRICE_PRECISION)));
|
|
52
|
+
assert(oracleOrderParams.oraclePriceOffset === -20 * PRICE_PRECISION.toNumber());
|
|
53
|
+
|
|
54
|
+
oracleOrderParams = deriveOracleAuctionParams({
|
|
55
|
+
direction: PositionDirection.SHORT,
|
|
56
|
+
oraclePrice,
|
|
57
|
+
auctionStartPrice: oraclePrice,
|
|
58
|
+
auctionEndPrice: oraclePrice,
|
|
59
|
+
limitPrice: oraclePrice,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
assert(oracleOrderParams.auctionStartPrice.eq(new BN(0)));
|
|
63
|
+
assert(oracleOrderParams.auctionEndPrice.eq(new BN(0)));
|
|
64
|
+
assert(oracleOrderParams.oraclePriceOffset === -1);
|
|
65
|
+
});
|
|
66
|
+
});
|
package/tests/dlob/test.ts
CHANGED
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
convertToNumber,
|
|
24
24
|
QUOTE_PRECISION,
|
|
25
25
|
isVariant,
|
|
26
|
-
TWO,
|
|
27
26
|
} from '../../src';
|
|
28
27
|
|
|
29
28
|
import { mockPerpMarkets, mockSpotMarkets, mockStateAccount } from './helpers';
|
|
@@ -3669,78 +3668,7 @@ describe('DLOB Perp Tests', () => {
|
|
|
3669
3668
|
vBid
|
|
3670
3669
|
);
|
|
3671
3670
|
|
|
3672
|
-
expect(nodesToFillBefore.length).to.equal(
|
|
3673
|
-
|
|
3674
|
-
// insert a sell right above amm bid
|
|
3675
|
-
insertOrderToDLOB(
|
|
3676
|
-
dlob,
|
|
3677
|
-
user0.publicKey,
|
|
3678
|
-
OrderType.LIMIT,
|
|
3679
|
-
MarketType.PERP,
|
|
3680
|
-
5, // orderId
|
|
3681
|
-
marketIndex,
|
|
3682
|
-
vBid.add(PRICE_PRECISION.div(TWO)),
|
|
3683
|
-
new BN(1).mul(BASE_PRECISION), // quantity
|
|
3684
|
-
PositionDirection.SHORT,
|
|
3685
|
-
ZERO,
|
|
3686
|
-
ZERO,
|
|
3687
|
-
new BN(slot),
|
|
3688
|
-
new BN(200),
|
|
3689
|
-
undefined,
|
|
3690
|
-
undefined,
|
|
3691
|
-
0
|
|
3692
|
-
);
|
|
3693
|
-
|
|
3694
|
-
// insert a buy below the amm ask
|
|
3695
|
-
insertOrderToDLOB(
|
|
3696
|
-
dlob,
|
|
3697
|
-
user1.publicKey,
|
|
3698
|
-
OrderType.LIMIT,
|
|
3699
|
-
MarketType.PERP,
|
|
3700
|
-
6, // orderId
|
|
3701
|
-
marketIndex,
|
|
3702
|
-
vAsk.sub(PRICE_PRECISION.div(TWO)), // price,
|
|
3703
|
-
new BN(8768).mul(BASE_PRECISION).div(new BN(10000)), // quantity
|
|
3704
|
-
PositionDirection.LONG,
|
|
3705
|
-
ZERO,
|
|
3706
|
-
ZERO,
|
|
3707
|
-
new BN(slot),
|
|
3708
|
-
undefined,
|
|
3709
|
-
undefined,
|
|
3710
|
-
undefined,
|
|
3711
|
-
0
|
|
3712
|
-
);
|
|
3713
|
-
|
|
3714
|
-
const nodesToFillAfter = dlob.findTakingNodesToFill(
|
|
3715
|
-
marketIndex,
|
|
3716
|
-
slot,
|
|
3717
|
-
MarketType.PERP,
|
|
3718
|
-
oracle,
|
|
3719
|
-
false,
|
|
3720
|
-
10,
|
|
3721
|
-
vAsk,
|
|
3722
|
-
vBid
|
|
3723
|
-
);
|
|
3724
|
-
|
|
3725
|
-
expect(nodesToFillAfter.length).to.equal(2);
|
|
3726
|
-
|
|
3727
|
-
expect(
|
|
3728
|
-
nodesToFillAfter[0].node.order?.orderId,
|
|
3729
|
-
'wrong taker orderId'
|
|
3730
|
-
).to.equal(4);
|
|
3731
|
-
expect(
|
|
3732
|
-
nodesToFillAfter[0].makerNodes[0]?.order?.orderId,
|
|
3733
|
-
'wrong maker orderId'
|
|
3734
|
-
).to.equal(6);
|
|
3735
|
-
|
|
3736
|
-
expect(
|
|
3737
|
-
nodesToFillAfter[1].node.order?.orderId,
|
|
3738
|
-
'wrong taker orderId'
|
|
3739
|
-
).to.equal(2);
|
|
3740
|
-
expect(
|
|
3741
|
-
nodesToFillAfter[1].makerNodes[0]?.order?.orderId,
|
|
3742
|
-
'wrong maker orderId'
|
|
3743
|
-
).to.equal(5);
|
|
3671
|
+
expect(nodesToFillBefore.length).to.equal(2);
|
|
3744
3672
|
});
|
|
3745
3673
|
|
|
3746
3674
|
it('Test limit bid fills during auction', () => {
|