@drift-labs/sdk 0.2.0-temp.2 → 2.0.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 +27 -29
- package/lib/accounts/bulkAccountLoader.d.ts +2 -0
- package/lib/accounts/bulkAccountLoader.js +36 -29
- package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
- package/lib/accounts/bulkUserStatsSubscription.js +21 -0
- package/lib/accounts/bulkUserSubscription.d.ts +2 -2
- package/lib/accounts/bulkUserSubscription.js +0 -1
- package/lib/accounts/fetch.d.ts +2 -1
- package/lib/accounts/fetch.js +9 -1
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +20 -25
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +45 -49
- package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
- package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +1 -1
- package/lib/accounts/pollingUserAccountSubscriber.js +5 -11
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +107 -0
- package/lib/accounts/types.d.ts +26 -15
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +49 -0
- package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +47 -45
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
- package/lib/addresses/marketAddresses.d.ts +1 -3
- package/lib/addresses/marketAddresses.js +1 -1
- package/lib/addresses/pda.d.ts +15 -9
- package/lib/addresses/pda.js +73 -35
- package/lib/adminClient.d.ts +65 -0
- package/lib/adminClient.js +637 -0
- package/lib/config.d.ts +10 -10
- package/lib/config.js +26 -22
- package/lib/constants/numericConstants.d.ts +29 -12
- package/lib/constants/numericConstants.js +40 -21
- package/lib/constants/perpMarkets.d.ts +18 -0
- package/lib/constants/{markets.js → perpMarkets.js} +20 -9
- package/lib/constants/spotMarkets.d.ts +19 -0
- package/lib/constants/spotMarkets.js +63 -0
- package/lib/dlob/DLOB.d.ts +82 -0
- package/lib/dlob/DLOB.js +694 -0
- package/lib/dlob/DLOBNode.d.ts +54 -0
- package/lib/dlob/DLOBNode.js +77 -0
- package/lib/dlob/NodeList.d.ts +27 -0
- package/lib/dlob/NodeList.js +144 -0
- package/lib/driftClient.d.ts +234 -0
- package/lib/driftClient.js +2108 -0
- package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +9 -9
- package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
- package/lib/events/eventList.d.ts +0 -1
- package/lib/events/eventList.js +0 -7
- package/lib/events/eventSubscriber.d.ts +5 -2
- package/lib/events/eventSubscriber.js +25 -11
- package/lib/events/fetchLogs.d.ts +13 -2
- package/lib/events/fetchLogs.js +45 -14
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +7 -3
- package/lib/events/sort.js +8 -11
- package/lib/events/txEventCache.d.ts +0 -2
- package/lib/events/txEventCache.js +0 -14
- package/lib/events/types.d.ts +11 -3
- package/lib/events/types.js +8 -0
- package/lib/events/webSocketLogProvider.js +1 -1
- package/lib/examples/makeTradeExample.js +30 -18
- package/lib/factory/bigNum.d.ts +8 -4
- package/lib/factory/bigNum.js +109 -19
- package/lib/idl/drift.json +8392 -0
- package/lib/index.d.ts +29 -12
- package/lib/index.js +29 -12
- package/lib/math/amm.d.ts +9 -6
- package/lib/math/amm.js +91 -38
- package/lib/math/conversion.js +1 -1
- package/lib/math/exchangeStatus.d.ts +4 -0
- package/lib/math/exchangeStatus.js +18 -0
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +23 -21
- package/lib/math/insurance.d.ts +4 -0
- package/lib/math/insurance.js +27 -0
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +82 -0
- package/lib/math/market.d.ts +14 -9
- package/lib/math/market.js +70 -10
- package/lib/math/oracles.d.ts +4 -0
- package/lib/math/oracles.js +36 -8
- package/lib/math/orders.d.ts +16 -6
- package/lib/math/orders.js +97 -17
- package/lib/math/position.d.ts +27 -13
- package/lib/math/position.js +91 -37
- package/lib/math/repeg.js +17 -8
- package/lib/math/spotBalance.d.ts +22 -0
- package/lib/math/spotBalance.js +192 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +6 -0
- package/lib/math/spotPosition.js +23 -0
- package/lib/math/trade.d.ts +10 -10
- package/lib/math/trade.js +27 -31
- package/lib/oracles/pythClient.js +1 -1
- package/lib/oracles/quoteAssetOracleClient.js +1 -1
- package/lib/oracles/switchboardClient.js +1 -1
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
- package/lib/serum/serumFulfillmentConfigMap.js +17 -0
- package/lib/serum/serumSubscriber.d.ts +27 -0
- package/lib/serum/serumSubscriber.js +56 -0
- package/lib/serum/types.d.ts +11 -0
- package/{src/oracles → lib/serum}/types.js +0 -0
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tokenFaucet.js +23 -12
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +13 -4
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +631 -222
- package/lib/types.js +137 -24
- package/lib/user.d.ts +228 -0
- package/lib/user.js +959 -0
- package/lib/userConfig.d.ts +14 -0
- package/lib/{clearingHouseUserConfig.js → userConfig.js} +0 -0
- package/lib/userMap/userMap.d.ts +41 -0
- package/lib/userMap/userMap.js +85 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/lib/userName.d.ts +1 -0
- package/lib/userName.js +3 -2
- package/lib/userStats.d.ts +18 -0
- package/lib/userStats.js +49 -0
- package/lib/userStatsConfig.d.ts +14 -0
- package/{src/clearingHouseConfig.js → lib/userStatsConfig.js} +0 -0
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +12 -5
- package/src/accounts/bulkAccountLoader.ts +44 -34
- package/src/accounts/bulkUserStatsSubscription.ts +33 -0
- package/src/accounts/bulkUserSubscription.ts +2 -3
- package/src/accounts/fetch.ts +27 -2
- package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +65 -75
- package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
- package/src/accounts/pollingUserAccountSubscriber.ts +5 -12
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +166 -0
- package/src/accounts/types.ts +35 -15
- package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +78 -73
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
- package/src/addresses/marketAddresses.ts +3 -4
- package/src/addresses/pda.ts +105 -33
- package/src/adminClient.ts +1207 -0
- package/src/config.ts +41 -34
- package/src/constants/numericConstants.ts +59 -26
- package/src/constants/{markets.ts → perpMarkets.ts} +22 -11
- package/src/constants/spotMarkets.ts +83 -0
- package/src/dlob/DLOB.ts +1120 -0
- package/src/dlob/DLOBNode.ts +155 -0
- package/src/dlob/NodeList.ts +195 -0
- package/src/driftClient.ts +3594 -0
- package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +9 -8
- package/src/events/eventList.ts +1 -8
- package/src/events/eventSubscriber.ts +36 -14
- package/src/events/fetchLogs.ts +60 -15
- package/src/events/pollingLogProvider.ts +11 -3
- package/src/events/sort.ts +11 -15
- package/src/events/txEventCache.ts +0 -16
- package/src/events/types.ts +27 -2
- package/src/events/webSocketLogProvider.ts +1 -1
- package/src/examples/makeTradeExample.js +152 -75
- package/src/examples/makeTradeExample.ts +44 -28
- package/src/factory/bigNum.ts +150 -22
- package/src/idl/drift.json +8392 -0
- package/src/idl/pyth.json +98 -2
- package/src/index.ts +29 -12
- package/src/math/amm.ts +161 -48
- package/src/math/conversion.ts +2 -2
- package/src/math/exchangeStatus.ts +31 -0
- package/src/math/funding.ts +41 -31
- package/src/math/insurance.ts +35 -0
- package/src/math/margin.ts +133 -0
- package/src/math/market.ts +143 -14
- package/src/math/oracles.ts +63 -9
- package/src/math/orders.ts +168 -26
- package/src/math/position.ts +133 -59
- package/src/math/repeg.ts +19 -9
- package/src/math/spotBalance.ts +319 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.ts +47 -0
- package/src/math/trade.ts +33 -37
- package/src/oracles/pythClient.ts +2 -2
- package/src/oracles/quoteAssetOracleClient.ts +2 -2
- package/src/oracles/switchboardClient.ts +2 -2
- package/src/orderParams.ts +16 -8
- package/src/serum/serumFulfillmentConfigMap.ts +26 -0
- package/src/serum/serumSubscriber.ts +99 -0
- package/src/serum/types.ts +13 -0
- package/src/tokenFaucet.ts +38 -15
- package/src/tx/retryTxSender.ts +16 -5
- package/src/tx/types.ts +2 -1
- package/src/types.ts +594 -195
- package/src/user.ts +1599 -0
- package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
- package/src/userMap/userMap.ts +124 -0
- package/src/userMap/userStatsMap.ts +108 -0
- package/src/userName.ts +2 -1
- package/src/userStats.ts +75 -0
- package/src/userStatsConfig.ts +18 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +46 -11
- package/tests/dlob/helpers.ts +619 -0
- package/tests/dlob/test.ts +4586 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +0 -49
- package/lib/admin.d.ts +0 -44
- package/lib/admin.js +0 -438
- package/lib/clearingHouse.d.ts +0 -146
- package/lib/clearingHouse.js +0 -1154
- package/lib/clearingHouseUser.d.ts +0 -187
- package/lib/clearingHouseUser.js +0 -634
- package/lib/clearingHouseUserConfig.d.ts +0 -14
- package/lib/constants/banks.d.ts +0 -16
- package/lib/constants/banks.js +0 -41
- package/lib/constants/markets.d.ts +0 -19
- package/lib/idl/clearing_house.json +0 -4464
- package/lib/math/bankBalance.d.ts +0 -9
- package/lib/math/bankBalance.js +0 -75
- package/lib/math/state.d.ts +0 -8
- package/lib/math/state.js +0 -15
- package/lib/orders.d.ts +0 -8
- package/lib/orders.js +0 -134
- package/src/accounts/bulkAccountLoader.js +0 -197
- package/src/accounts/bulkUserSubscription.js +0 -33
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
- package/src/accounts/pollingOracleSubscriber.js +0 -93
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
- package/src/accounts/pollingUserAccountSubscriber.js +0 -132
- package/src/accounts/types.js +0 -10
- package/src/accounts/utils.js +0 -7
- package/src/accounts/webSocketAccountSubscriber.js +0 -93
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
- package/src/addresses/marketAddresses.js +0 -26
- package/src/admin.js +0 -517
- package/src/admin.ts +0 -730
- package/src/clearingHouse.ts +0 -1828
- package/src/clearingHouseUser.ts +0 -978
- package/src/clearingHouseUserConfig.js +0 -2
- package/src/config.js +0 -67
- package/src/constants/banks.js +0 -42
- package/src/constants/banks.ts +0 -50
- package/src/constants/markets.js +0 -42
- package/src/constants/numericConstants.js +0 -41
- package/src/events/eventSubscriber.js +0 -139
- package/src/events/fetchLogs.js +0 -50
- package/src/events/pollingLogProvider.js +0 -64
- package/src/events/sort.js +0 -44
- package/src/events/txEventCache.js +0 -71
- package/src/events/types.js +0 -20
- package/src/events/webSocketLogProvider.js +0 -41
- package/src/factory/bigNum.js +0 -390
- package/src/factory/oracleClient.js +0 -20
- package/src/idl/clearing_house.json +0 -4464
- package/src/index.js +0 -69
- package/src/math/amm.js +0 -369
- package/src/math/auction.js +0 -42
- package/src/math/bankBalance.ts +0 -112
- package/src/math/conversion.js +0 -11
- package/src/math/funding.js +0 -248
- package/src/math/oracles.js +0 -26
- package/src/math/repeg.js +0 -128
- package/src/math/state.js +0 -15
- package/src/math/state.ts +0 -14
- package/src/math/trade.js +0 -253
- package/src/math/utils.js +0 -26
- package/src/math/utils.js.map +0 -1
- package/src/mockUSDCFaucet.js +0 -280
- package/src/oracles/oracleClientCache.js +0 -19
- package/src/oracles/pythClient.js +0 -46
- package/src/oracles/quoteAssetOracleClient.js +0 -32
- package/src/oracles/switchboardClient.js +0 -69
- package/src/orderParams.js +0 -20
- package/src/orders.ts +0 -245
- package/src/slot/SlotSubscriber.js +0 -39
- package/src/tokenFaucet.js +0 -189
- package/src/types.js +0 -125
- package/src/userName.js +0 -20
- package/src/wallet.js +0 -35
package/lib/math/funding.js
CHANGED
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.calculateFundingPool = exports.calculateLongShortFundingRateAndLiveTwaps = exports.calculateLongShortFundingRate = exports.calculateEstimatedFundingRate = exports.calculateAllEstimatedFundingRate = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
-
const
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
const amm_1 = require("./amm");
|
|
7
8
|
/**
|
|
8
9
|
*
|
|
9
10
|
* @param market
|
|
@@ -19,7 +20,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
19
20
|
const secondsInHour = new anchor_1.BN(3600);
|
|
20
21
|
const hoursInDay = new anchor_1.BN(24);
|
|
21
22
|
const ONE = new anchor_1.BN(1);
|
|
22
|
-
if (
|
|
23
|
+
if ((0, types_1.isVariant)(market.status, 'uninitialized')) {
|
|
23
24
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
24
25
|
}
|
|
25
26
|
const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
|
|
@@ -31,15 +32,16 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
31
32
|
const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
|
|
32
33
|
const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
|
|
33
34
|
const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
|
|
34
|
-
const
|
|
35
|
+
const [bid, ask] = (0, amm_1.calculateBidAskPrice)(market.amm, oraclePriceData);
|
|
36
|
+
const baseAssetPriceWithMantissa = bid.add(ask).div(new anchor_1.BN(2));
|
|
35
37
|
const markTwapWithMantissa = markTwapTimeSinceLastUpdate
|
|
36
38
|
.mul(lastMarkTwapWithMantissa)
|
|
37
39
|
.add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
|
|
38
40
|
.div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
|
|
39
41
|
// calculate real-time (predicted) oracle twap
|
|
40
42
|
// note: oracle twap depends on `when the chord is struck` (market is trade)
|
|
41
|
-
const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
|
|
42
|
-
const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
|
|
43
|
+
const lastOracleTwapWithMantissa = market.amm.historicalOracleData.lastOraclePriceTwap;
|
|
44
|
+
const lastOraclePriceTwapTs = market.amm.historicalOracleData.lastOraclePriceTwapTs;
|
|
43
45
|
const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
|
|
44
46
|
const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
|
|
45
47
|
const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
|
|
@@ -50,11 +52,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
50
52
|
const oracleLiveVsTwap = oraclePrice
|
|
51
53
|
.sub(lastOracleTwapWithMantissa)
|
|
52
54
|
.abs()
|
|
53
|
-
.mul(numericConstants_1.
|
|
55
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
54
56
|
.mul(new anchor_1.BN(100))
|
|
55
57
|
.div(lastOracleTwapWithMantissa);
|
|
56
58
|
// verify pyth live input is within 10% of last twap for live update
|
|
57
|
-
if (oracleLiveVsTwap.lte(numericConstants_1.
|
|
59
|
+
if (oracleLiveVsTwap.lte(numericConstants_1.PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
|
|
58
60
|
oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
|
|
59
61
|
.mul(lastOracleTwapWithMantissa)
|
|
60
62
|
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
@@ -67,7 +69,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
67
69
|
.div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
|
|
68
70
|
const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
|
|
69
71
|
const twapSpreadPct = twapSpread
|
|
70
|
-
.mul(numericConstants_1.
|
|
72
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
71
73
|
.mul(new anchor_1.BN(100))
|
|
72
74
|
.div(shrunkLastOracleTwapwithMantissa);
|
|
73
75
|
const lowerboundEst = twapSpreadPct
|
|
@@ -81,7 +83,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
81
83
|
const interpRateQuote = twapSpreadPct
|
|
82
84
|
.mul(periodAdjustment)
|
|
83
85
|
.div(hoursInDay)
|
|
84
|
-
.div(numericConstants_1.
|
|
86
|
+
.div(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
|
|
85
87
|
let feePoolSize = calculateFundingPool(market);
|
|
86
88
|
if (interpRateQuote.lt(new anchor_1.BN(0))) {
|
|
87
89
|
feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
|
|
@@ -89,9 +91,9 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
89
91
|
let cappedAltEst;
|
|
90
92
|
let largerSide;
|
|
91
93
|
let smallerSide;
|
|
92
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
93
|
-
largerSide = market.baseAssetAmountLong.abs();
|
|
94
|
-
smallerSide = market.baseAssetAmountShort.abs();
|
|
94
|
+
if (market.amm.baseAssetAmountLong.gt(market.amm.baseAssetAmountShort.abs())) {
|
|
95
|
+
largerSide = market.amm.baseAssetAmountLong.abs();
|
|
96
|
+
smallerSide = market.amm.baseAssetAmountShort.abs();
|
|
95
97
|
if (twapSpread.gt(new anchor_1.BN(0))) {
|
|
96
98
|
return [
|
|
97
99
|
markTwapWithMantissa,
|
|
@@ -102,9 +104,9 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
102
104
|
];
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
106
|
-
largerSide = market.baseAssetAmountShort.abs();
|
|
107
|
-
smallerSide = market.baseAssetAmountLong.abs();
|
|
107
|
+
else if (market.amm.baseAssetAmountLong.lt(market.amm.baseAssetAmountShort.abs())) {
|
|
108
|
+
largerSide = market.amm.baseAssetAmountShort.abs();
|
|
109
|
+
smallerSide = market.amm.baseAssetAmountLong.abs();
|
|
108
110
|
if (twapSpread.lt(new anchor_1.BN(0))) {
|
|
109
111
|
return [
|
|
110
112
|
markTwapWithMantissa,
|
|
@@ -128,11 +130,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
128
130
|
// funding smaller flow
|
|
129
131
|
cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
|
|
130
132
|
const feePoolTopOff = feePoolSize
|
|
131
|
-
.mul(numericConstants_1.
|
|
133
|
+
.mul(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
|
|
132
134
|
.mul(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
133
135
|
cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
|
|
134
136
|
cappedAltEst = cappedAltEst
|
|
135
|
-
.mul(numericConstants_1.
|
|
137
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
136
138
|
.mul(new anchor_1.BN(100))
|
|
137
139
|
.div(oracleTwapWithMantissa)
|
|
138
140
|
.mul(periodAdjustment);
|
|
@@ -183,10 +185,10 @@ exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
|
|
|
183
185
|
*/
|
|
184
186
|
async function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
185
187
|
const [_1, _2, _, cappedAltEst, interpEst] = await calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
186
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
|
|
188
|
+
if (market.amm.baseAssetAmountLong.gt(market.amm.baseAssetAmountShort)) {
|
|
187
189
|
return [cappedAltEst, interpEst];
|
|
188
190
|
}
|
|
189
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
|
|
191
|
+
else if (market.amm.baseAssetAmountLong.lt(market.amm.baseAssetAmountShort)) {
|
|
190
192
|
return [interpEst, cappedAltEst];
|
|
191
193
|
}
|
|
192
194
|
else {
|
|
@@ -203,10 +205,10 @@ exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
|
|
|
203
205
|
*/
|
|
204
206
|
async function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
205
207
|
const [markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst] = await calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
206
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
208
|
+
if (market.amm.baseAssetAmountLong.gt(market.amm.baseAssetAmountShort.abs())) {
|
|
207
209
|
return [markTwapLive, oracleTwapLive, cappedAltEst, interpEst];
|
|
208
210
|
}
|
|
209
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
211
|
+
else if (market.amm.baseAssetAmountLong.lt(market.amm.baseAssetAmountShort.abs())) {
|
|
210
212
|
return [markTwapLive, oracleTwapLive, interpEst, cappedAltEst];
|
|
211
213
|
}
|
|
212
214
|
else {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '../index';
|
|
3
|
+
export declare function stakeAmountToShares(amount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
|
|
4
|
+
export declare function unstakeSharesToAmount(nShares: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unstakeSharesToAmount = exports.stakeAmountToShares = void 0;
|
|
4
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
function stakeAmountToShares(amount, totalIfShares, insuranceFundVaultBalance) {
|
|
7
|
+
let nShares;
|
|
8
|
+
if (insuranceFundVaultBalance.gt(numericConstants_1.ZERO)) {
|
|
9
|
+
nShares = amount.mul(totalIfShares).div(insuranceFundVaultBalance);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
nShares = amount;
|
|
13
|
+
}
|
|
14
|
+
return nShares;
|
|
15
|
+
}
|
|
16
|
+
exports.stakeAmountToShares = stakeAmountToShares;
|
|
17
|
+
function unstakeSharesToAmount(nShares, totalIfShares, insuranceFundVaultBalance) {
|
|
18
|
+
let amount;
|
|
19
|
+
if (totalIfShares.gt(numericConstants_1.ZERO)) {
|
|
20
|
+
amount = index_1.BN.max(numericConstants_1.ZERO, nShares.mul(insuranceFundVaultBalance).div(totalIfShares));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
amount = numericConstants_1.ZERO;
|
|
24
|
+
}
|
|
25
|
+
return amount;
|
|
26
|
+
}
|
|
27
|
+
exports.unstakeSharesToAmount = unstakeSharesToAmount;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@project-serum/anchor';
|
|
3
|
+
import { OraclePriceData } from '../oracles/types';
|
|
4
|
+
import { PerpMarketAccount, PerpPosition } from '..';
|
|
5
|
+
export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
6
|
+
imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
|
|
7
|
+
export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
8
|
+
imfFactor: BN, assetWeight: BN): BN;
|
|
9
|
+
export declare function calculateOraclePriceForPerpMargin(perpPosition: PerpPosition, market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
10
|
+
export declare function calculateBaseAssetValueWithOracle(market: PerpMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData): BN;
|
|
11
|
+
export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition): BN;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const assert_1 = require("../assert/assert");
|
|
9
|
+
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
10
|
+
imfFactor, liabilityWeight, precision) {
|
|
11
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
12
|
+
return liabilityWeight;
|
|
13
|
+
}
|
|
14
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
15
|
+
const denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
16
|
+
(0, assert_1.assert)(denom0.gt(numericConstants_1.ZERO));
|
|
17
|
+
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
|
|
18
|
+
const denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
19
|
+
(0, assert_1.assert)(denom.gt(numericConstants_1.ZERO));
|
|
20
|
+
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
|
21
|
+
.mul(imfFactor)
|
|
22
|
+
.div(denom) // 1e5
|
|
23
|
+
);
|
|
24
|
+
const maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
|
|
25
|
+
return maxLiabilityWeight;
|
|
26
|
+
}
|
|
27
|
+
exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
|
|
28
|
+
function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
|
|
29
|
+
imfFactor, assetWeight) {
|
|
30
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
31
|
+
return assetWeight;
|
|
32
|
+
}
|
|
33
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
34
|
+
const imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
35
|
+
const sizeDiscountAssetWeight = imfNumerator
|
|
36
|
+
.mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
37
|
+
.div(numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(sizeSqrt // 1e5
|
|
38
|
+
.mul(imfFactor)
|
|
39
|
+
.div(new anchor_1.BN(100000)) // 1e5
|
|
40
|
+
));
|
|
41
|
+
const minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
42
|
+
return minAssetWeight;
|
|
43
|
+
}
|
|
44
|
+
exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
|
|
45
|
+
function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData) {
|
|
46
|
+
const oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
|
|
47
|
+
.mul(oraclePriceData.price)
|
|
48
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
|
|
49
|
+
.mul(oraclePriceData.price)
|
|
50
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
|
|
51
|
+
let marginPrice;
|
|
52
|
+
if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
53
|
+
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
57
|
+
}
|
|
58
|
+
return marginPrice;
|
|
59
|
+
}
|
|
60
|
+
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
61
|
+
function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData) {
|
|
62
|
+
let price = oraclePriceData.price;
|
|
63
|
+
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
64
|
+
price = market.expiryPrice;
|
|
65
|
+
}
|
|
66
|
+
return perpPosition.baseAssetAmount
|
|
67
|
+
.abs()
|
|
68
|
+
.mul(price)
|
|
69
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
70
|
+
}
|
|
71
|
+
exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
|
|
72
|
+
function calculateWorstCaseBaseAssetAmount(perpPosition) {
|
|
73
|
+
const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
|
|
74
|
+
const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
|
|
75
|
+
if (allBids.abs().gt(allAsks.abs())) {
|
|
76
|
+
return allBids;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return allAsks;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
|
package/lib/math/market.d.ts
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from '@project-serum/anchor';
|
|
3
|
-
import {
|
|
3
|
+
import { PerpMarketAccount, PositionDirection, MarginCategory, SpotMarketAccount } from '../types';
|
|
4
4
|
import { OraclePriceData } from '../oracles/types';
|
|
5
5
|
/**
|
|
6
6
|
* Calculates market mark price
|
|
7
7
|
*
|
|
8
8
|
* @param market
|
|
9
|
-
* @return markPrice : Precision
|
|
9
|
+
* @return markPrice : Precision PRICE_PRECISION
|
|
10
10
|
*/
|
|
11
|
-
export declare function
|
|
11
|
+
export declare function calculateReservePrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
12
12
|
/**
|
|
13
13
|
* Calculates market bid price
|
|
14
14
|
*
|
|
15
15
|
* @param market
|
|
16
|
-
* @return bidPrice : Precision
|
|
16
|
+
* @return bidPrice : Precision PRICE_PRECISION
|
|
17
17
|
*/
|
|
18
|
-
export declare function calculateBidPrice(market:
|
|
18
|
+
export declare function calculateBidPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
19
19
|
/**
|
|
20
20
|
* Calculates market ask price
|
|
21
21
|
*
|
|
22
22
|
* @param market
|
|
23
|
-
* @return
|
|
23
|
+
* @return askPrice : Precision PRICE_PRECISION
|
|
24
24
|
*/
|
|
25
|
-
export declare function calculateAskPrice(market:
|
|
26
|
-
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market:
|
|
27
|
-
export declare function
|
|
25
|
+
export declare function calculateAskPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
26
|
+
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
|
|
27
|
+
export declare function calculateOracleReserveSpread(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
28
28
|
export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
|
|
29
|
+
export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory): number;
|
|
30
|
+
export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount, quoteSpotMarket: SpotMarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory, oraclePriceData: OraclePriceData): BN;
|
|
31
|
+
export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
|
|
32
|
+
export declare function calculateNetUserPnl(perpMarket: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
33
|
+
export declare function calculateNetUserPnlImbalance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount, oraclePriceData: OraclePriceData): BN;
|
package/lib/math/market.js
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateOracleSpread = exports.
|
|
3
|
+
exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateOracleReserveSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const amm_1 = require("./amm");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
8
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
9
|
+
const spotBalance_1 = require("./spotBalance");
|
|
6
10
|
/**
|
|
7
11
|
* Calculates market mark price
|
|
8
12
|
*
|
|
9
13
|
* @param market
|
|
10
|
-
* @return markPrice : Precision
|
|
14
|
+
* @return markPrice : Precision PRICE_PRECISION
|
|
11
15
|
*/
|
|
12
|
-
function
|
|
16
|
+
function calculateReservePrice(market, oraclePriceData) {
|
|
13
17
|
const newAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
|
|
14
18
|
return (0, amm_1.calculatePrice)(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
|
|
15
19
|
}
|
|
16
|
-
exports.
|
|
20
|
+
exports.calculateReservePrice = calculateReservePrice;
|
|
17
21
|
/**
|
|
18
22
|
* Calculates market bid price
|
|
19
23
|
*
|
|
20
24
|
* @param market
|
|
21
|
-
* @return bidPrice : Precision
|
|
25
|
+
* @return bidPrice : Precision PRICE_PRECISION
|
|
22
26
|
*/
|
|
23
27
|
function calculateBidPrice(market, oraclePriceData) {
|
|
24
28
|
const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.SHORT, oraclePriceData);
|
|
@@ -29,7 +33,7 @@ exports.calculateBidPrice = calculateBidPrice;
|
|
|
29
33
|
* Calculates market ask price
|
|
30
34
|
*
|
|
31
35
|
* @param market
|
|
32
|
-
* @return
|
|
36
|
+
* @return askPrice : Precision PRICE_PRECISION
|
|
33
37
|
*/
|
|
34
38
|
function calculateAskPrice(market, oraclePriceData) {
|
|
35
39
|
const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.LONG, oraclePriceData);
|
|
@@ -46,12 +50,68 @@ function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
|
|
|
46
50
|
return newMarket;
|
|
47
51
|
}
|
|
48
52
|
exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
return calculateOracleSpread(
|
|
53
|
+
function calculateOracleReserveSpread(market, oraclePriceData) {
|
|
54
|
+
const reservePrice = calculateReservePrice(market, oraclePriceData);
|
|
55
|
+
return calculateOracleSpread(reservePrice, oraclePriceData);
|
|
52
56
|
}
|
|
53
|
-
exports.
|
|
57
|
+
exports.calculateOracleReserveSpread = calculateOracleReserveSpread;
|
|
54
58
|
function calculateOracleSpread(price, oraclePriceData) {
|
|
55
59
|
return price.sub(oraclePriceData.price);
|
|
56
60
|
}
|
|
57
61
|
exports.calculateOracleSpread = calculateOracleSpread;
|
|
62
|
+
function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
63
|
+
let marginRatio;
|
|
64
|
+
switch (marginCategory) {
|
|
65
|
+
case 'Initial':
|
|
66
|
+
marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
67
|
+
break;
|
|
68
|
+
case 'Maintenance':
|
|
69
|
+
marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioMaintenance), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
return marginRatio;
|
|
73
|
+
}
|
|
74
|
+
exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
|
|
75
|
+
function calculateUnrealizedAssetWeight(market, quoteSpotMarket, unrealizedPnl, marginCategory, oraclePriceData) {
|
|
76
|
+
let assetWeight;
|
|
77
|
+
switch (marginCategory) {
|
|
78
|
+
case 'Initial':
|
|
79
|
+
assetWeight = new anchor_1.BN(market.unrealizedPnlInitialAssetWeight);
|
|
80
|
+
if (market.unrealizedPnlMaxImbalance.gt(numericConstants_1.ZERO)) {
|
|
81
|
+
const netUnsettledPnl = calculateNetUserPnlImbalance(market, quoteSpotMarket, oraclePriceData);
|
|
82
|
+
if (netUnsettledPnl.gt(market.unrealizedPnlMaxImbalance)) {
|
|
83
|
+
assetWeight = assetWeight
|
|
84
|
+
.mul(market.unrealizedPnlMaxImbalance)
|
|
85
|
+
.div(netUnsettledPnl);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, new anchor_1.BN(market.unrealizedPnlImfFactor), assetWeight);
|
|
89
|
+
break;
|
|
90
|
+
case 'Maintenance':
|
|
91
|
+
assetWeight = new anchor_1.BN(market.unrealizedPnlMaintenanceAssetWeight);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
return assetWeight;
|
|
95
|
+
}
|
|
96
|
+
exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
|
|
97
|
+
function calculateMarketAvailablePNL(perpMarket, spotMarket) {
|
|
98
|
+
return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.scaledBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
99
|
+
}
|
|
100
|
+
exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
|
|
101
|
+
function calculateNetUserPnl(perpMarket, oraclePriceData) {
|
|
102
|
+
const netUserPositionValue = perpMarket.amm.baseAssetAmountWithAmm
|
|
103
|
+
.mul(oraclePriceData.price)
|
|
104
|
+
.div(numericConstants_1.BASE_PRECISION)
|
|
105
|
+
.div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
106
|
+
const netUserCostBasis = perpMarket.amm.quoteAssetAmount;
|
|
107
|
+
const netUserPnl = netUserPositionValue.add(netUserCostBasis);
|
|
108
|
+
return netUserPnl;
|
|
109
|
+
}
|
|
110
|
+
exports.calculateNetUserPnl = calculateNetUserPnl;
|
|
111
|
+
function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
|
|
112
|
+
const netUserPnl = calculateNetUserPnl(perpMarket, oraclePriceData);
|
|
113
|
+
const pnlPool = (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.scaledBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
114
|
+
const imbalance = netUserPnl.sub(pnlPool);
|
|
115
|
+
return imbalance;
|
|
116
|
+
}
|
|
117
|
+
exports.calculateNetUserPnlImbalance = calculateNetUserPnlImbalance;
|
package/lib/math/oracles.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import { AMM, OracleGuardRails } from '../types';
|
|
2
3
|
import { OraclePriceData } from '../oracles/types';
|
|
4
|
+
import { BN, PerpMarketAccount } from '../index';
|
|
5
|
+
export declare function oraclePriceBands(market: PerpMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
|
|
3
6
|
export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
|
|
7
|
+
export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;
|
package/lib/math/oracles.js
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isOracleValid = void 0;
|
|
3
|
+
exports.isOracleTooDivergent = exports.isOracleValid = exports.oraclePriceBands = void 0;
|
|
4
4
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
5
|
const index_1 = require("../index");
|
|
6
|
+
const assert_1 = require("../assert/assert");
|
|
7
|
+
function oraclePriceBands(market, oraclePriceData) {
|
|
8
|
+
const maxPercentDiff = market.marginRatioInitial - market.marginRatioMaintenance;
|
|
9
|
+
const offset = oraclePriceData.price
|
|
10
|
+
.mul(new index_1.BN(maxPercentDiff))
|
|
11
|
+
.div(numericConstants_1.MARGIN_PRECISION);
|
|
12
|
+
(0, assert_1.assert)(offset.gt(numericConstants_1.ZERO));
|
|
13
|
+
return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
|
|
14
|
+
}
|
|
15
|
+
exports.oraclePriceBands = oraclePriceBands;
|
|
6
16
|
function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
7
|
-
const isOraclePriceNonPositive = oraclePriceData.price.
|
|
17
|
+
const isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
|
|
8
18
|
const isOraclePriceTooVolatile = oraclePriceData.price
|
|
9
|
-
.div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
|
|
19
|
+
.div(index_1.BN.max(numericConstants_1.ONE, amm.historicalOracleData.lastOraclePriceTwap))
|
|
10
20
|
.gt(oracleGuardRails.validity.tooVolatileRatio) ||
|
|
11
|
-
amm.lastOraclePriceTwap
|
|
21
|
+
amm.historicalOracleData.lastOraclePriceTwap
|
|
12
22
|
.div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
|
|
13
23
|
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
14
|
-
const isConfidenceTooLarge =
|
|
15
|
-
.
|
|
16
|
-
.
|
|
24
|
+
const isConfidenceTooLarge = new index_1.BN(amm.baseSpread)
|
|
25
|
+
.add(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
|
|
26
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
27
|
+
.div(oraclePriceData.price)
|
|
28
|
+
.gt(new index_1.BN(amm.maxSpread));
|
|
17
29
|
const oracleIsStale = oraclePriceData.slot
|
|
18
30
|
.sub(new index_1.BN(slot))
|
|
19
|
-
.gt(oracleGuardRails.validity.
|
|
31
|
+
.gt(oracleGuardRails.validity.slotsBeforeStaleForAmm);
|
|
20
32
|
return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
|
|
21
33
|
oracleIsStale ||
|
|
22
34
|
isOraclePriceNonPositive ||
|
|
@@ -24,3 +36,19 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
|
24
36
|
isConfidenceTooLarge);
|
|
25
37
|
}
|
|
26
38
|
exports.isOracleValid = isOracleValid;
|
|
39
|
+
function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
40
|
+
const sinceLastUpdate = now.sub(amm.historicalOracleData.lastOraclePriceTwapTs);
|
|
41
|
+
const sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
|
|
42
|
+
const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5Min
|
|
43
|
+
.mul(sinceStart)
|
|
44
|
+
.add(oraclePriceData.price)
|
|
45
|
+
.mul(sinceLastUpdate)
|
|
46
|
+
.div(sinceStart.add(sinceLastUpdate));
|
|
47
|
+
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
48
|
+
const oracleSpreadPct = oracleSpread.mul(numericConstants_1.PRICE_PRECISION).div(oracleTwap5min);
|
|
49
|
+
const tooDivergent = oracleSpreadPct
|
|
50
|
+
.abs()
|
|
51
|
+
.gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
|
|
52
|
+
return tooDivergent;
|
|
53
|
+
}
|
|
54
|
+
exports.isOracleTooDivergent = isOracleTooDivergent;
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { User } from '../user';
|
|
3
|
+
import { PerpMarketAccount, Order } from '../types';
|
|
4
4
|
import { BN } from '@project-serum/anchor';
|
|
5
5
|
import { OraclePriceData } from '../oracles/types';
|
|
6
|
-
export declare function isOrderRiskIncreasing(user:
|
|
7
|
-
export declare function isOrderRiskIncreasingInSameDirection(user:
|
|
8
|
-
export declare function isOrderReduceOnly(user:
|
|
6
|
+
export declare function isOrderRiskIncreasing(user: User, order: Order): boolean;
|
|
7
|
+
export declare function isOrderRiskIncreasingInSameDirection(user: User, order: Order): boolean;
|
|
8
|
+
export declare function isOrderReduceOnly(user: User, order: Order): boolean;
|
|
9
9
|
export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
|
|
10
|
-
export declare function getLimitPrice(order: Order,
|
|
10
|
+
export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
11
|
+
export declare function getOptionalLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number): BN | undefined;
|
|
12
|
+
export declare function hasLimitPrice(order: Order, slot: number): boolean;
|
|
13
|
+
export declare function isFillableByVAMM(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number, ts: number): boolean;
|
|
14
|
+
export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
15
|
+
export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, market: PerpMarketAccount, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
|
|
16
|
+
export declare function isOrderExpired(order: Order, ts: number): boolean;
|
|
17
|
+
export declare function isMarketOrder(order: Order): boolean;
|
|
18
|
+
export declare function isLimitOrder(order: Order): boolean;
|
|
19
|
+
export declare function mustBeTriggered(order: Order): boolean;
|
|
20
|
+
export declare function isTriggered(order: Order): boolean;
|