@drift-labs/sdk 2.41.0-beta.0 → 2.41.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +5 -4
- 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 +5 -1
- 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/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', () => {
|