@drift-labs/sdk 0.2.0-master.24 → 0.2.0-master.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +13 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
- package/lib/accounts/types.d.ts +8 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
- package/lib/addresses/pda.d.ts +8 -6
- package/lib/addresses/pda.js +35 -27
- package/lib/admin.d.ts +9 -6
- package/lib/admin.js +90 -54
- package/lib/clearingHouse.d.ts +71 -42
- package/lib/clearingHouse.js +765 -282
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +19 -17
- package/lib/clearingHouseUser.js +145 -123
- package/lib/config.d.ts +7 -7
- package/lib/config.js +21 -21
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/events/eventSubscriber.d.ts +4 -2
- package/lib/events/eventSubscriber.js +16 -9
- package/lib/events/fetchLogs.d.ts +10 -1
- package/lib/events/fetchLogs.js +27 -7
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +6 -2
- package/lib/events/types.d.ts +4 -2
- package/lib/events/types.js +2 -0
- package/lib/examples/makeTradeExample.js +18 -6
- package/lib/idl/clearing_house.json +1128 -347
- package/lib/index.d.ts +6 -3
- package/lib/index.js +6 -3
- package/lib/math/amm.d.ts +5 -3
- package/lib/math/amm.js +42 -4
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +10 -9
- package/lib/math/market.js +29 -6
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +5 -5
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +19 -0
- package/lib/math/spotBalance.js +176 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +2 -0
- package/lib/math/spotPosition.js +8 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +148 -39
- package/lib/types.js +37 -9
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +106 -0
- package/my-script/multiConnections.ts +119 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.js +249 -0
- package/src/accounts/bulkUserStatsSubscription.js +75 -0
- package/src/accounts/bulkUserSubscription.js +75 -0
- package/src/accounts/fetch.js +92 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
- package/src/accounts/pollingOracleSubscriber.js +156 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
- package/src/accounts/pollingUserAccountSubscriber.js +208 -0
- package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
- package/src/accounts/types.js +28 -0
- package/src/accounts/types.ts +11 -9
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +138 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
- package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
- package/src/addresses/pda.js +186 -0
- package/src/addresses/pda.ts +56 -42
- package/src/admin.js +1284 -0
- package/src/admin.ts +149 -75
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.js +3433 -0
- package/src/clearingHouse.ts +1097 -380
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.js +874 -0
- package/src/clearingHouseUser.ts +237 -172
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/clearingHouseUserStats.js +115 -0
- package/src/clearingHouseUserStatsConfig.js +2 -0
- package/src/config.js +80 -0
- package/src/config.ts +30 -30
- package/src/constants/numericConstants.js +18 -11
- package/src/constants/numericConstants.ts +17 -15
- package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/spotMarkets.js +51 -0
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/events/eventList.js +66 -23
- package/src/events/eventSubscriber.js +202 -0
- package/src/events/eventSubscriber.ts +20 -12
- package/src/events/fetchLogs.js +117 -0
- package/src/events/fetchLogs.ts +35 -8
- package/src/events/pollingLogProvider.js +113 -0
- package/src/events/pollingLogProvider.ts +10 -2
- package/src/events/sort.js +41 -0
- package/src/events/txEventCache.js +22 -19
- package/src/events/types.js +25 -0
- package/src/events/types.ts +7 -1
- package/src/events/webSocketLogProvider.js +76 -0
- package/src/examples/makeTradeExample.ts +27 -6
- package/src/factory/bigNum.js +183 -180
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +1128 -347
- package/src/index.js +75 -0
- package/src/index.ts +6 -3
- package/src/math/amm.js +422 -0
- package/src/math/amm.ts +73 -5
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +4 -3
- package/src/math/funding.js +223 -175
- package/src/math/funding.ts +7 -7
- package/src/math/insurance.js +27 -0
- package/src/math/margin.js +77 -0
- package/src/math/margin.ts +34 -23
- package/src/math/market.js +105 -0
- package/src/math/market.ts +71 -19
- package/src/math/oracles.js +40 -10
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.js +153 -0
- package/src/math/orders.ts +5 -5
- package/src/math/position.js +172 -0
- package/src/math/position.ts +31 -31
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.js +176 -0
- package/src/math/spotBalance.ts +290 -0
- package/src/math/spotMarket.js +8 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.js +8 -0
- package/src/math/spotPosition.ts +6 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.js +81 -74
- package/src/math/trade.ts +4 -4
- package/src/math/utils.js +8 -7
- package/src/oracles/oracleClientCache.js +10 -9
- package/src/oracles/pythClient.js +52 -17
- package/src/oracles/quoteAssetOracleClient.js +44 -13
- package/src/oracles/switchboardClient.js +69 -37
- package/src/oracles/types.js +1 -1
- package/src/orderParams.js +14 -6
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.js +102 -0
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.js +2 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.js +67 -20
- package/src/token/index.js +4 -4
- package/src/tokenFaucet.js +288 -154
- package/src/tx/retryTxSender.js +280 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.js +1 -1
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.js +7 -6
- package/src/types.js +216 -0
- package/src/types.ts +131 -39
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +46 -11
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +46 -12
- package/src/wallet.js +55 -18
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/addresses/marketAddresses.js +0 -26
- package/src/constants/banks.js +0 -42
- package/src/examples/makeTradeExample.js +0 -80
- package/src/math/bankBalance.ts +0 -258
- package/src/math/state.js +0 -15
- package/src/math/utils.js.map +0 -1
- package/src/util/getTokenAddress.js +0 -9
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
|
+
var utils_1 = require("./utils");
|
|
5
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
var anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
var assert_1 = require("../assert/assert");
|
|
8
|
+
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
9
|
+
imfFactor, liabilityWeight, precision) {
|
|
10
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
11
|
+
return liabilityWeight;
|
|
12
|
+
}
|
|
13
|
+
var sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
14
|
+
var denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
15
|
+
(0, assert_1.assert)(denom0.gt(numericConstants_1.ZERO));
|
|
16
|
+
var liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
|
|
17
|
+
var denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
18
|
+
(0, assert_1.assert)(denom.gt(numericConstants_1.ZERO));
|
|
19
|
+
var sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
|
20
|
+
.mul(imfFactor)
|
|
21
|
+
.div(denom) // 1e5
|
|
22
|
+
);
|
|
23
|
+
var maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
|
|
24
|
+
return maxLiabilityWeight;
|
|
25
|
+
}
|
|
26
|
+
exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
|
|
27
|
+
function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
|
|
28
|
+
imfFactor, assetWeight) {
|
|
29
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
30
|
+
return assetWeight;
|
|
31
|
+
}
|
|
32
|
+
var sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
33
|
+
var imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
34
|
+
var sizeDiscountAssetWeight = imfNumerator
|
|
35
|
+
.mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
36
|
+
.div(numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(sizeSqrt // 1e5
|
|
37
|
+
.mul(imfFactor)
|
|
38
|
+
.div(new anchor_1.BN(100000)) // 1e5
|
|
39
|
+
));
|
|
40
|
+
var minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
41
|
+
return minAssetWeight;
|
|
42
|
+
}
|
|
43
|
+
exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
|
|
44
|
+
function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData) {
|
|
45
|
+
var oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
|
|
46
|
+
.mul(oraclePriceData.price)
|
|
47
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
|
|
48
|
+
.mul(oraclePriceData.price)
|
|
49
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
|
|
50
|
+
var marginPrice;
|
|
51
|
+
if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
52
|
+
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
56
|
+
}
|
|
57
|
+
return marginPrice;
|
|
58
|
+
}
|
|
59
|
+
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
60
|
+
function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData) {
|
|
61
|
+
return perpPosition.baseAssetAmount
|
|
62
|
+
.abs()
|
|
63
|
+
.mul(oraclePriceData.price)
|
|
64
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
65
|
+
}
|
|
66
|
+
exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
|
|
67
|
+
function calculateWorstCaseBaseAssetAmount(perpPosition) {
|
|
68
|
+
var allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
|
|
69
|
+
var allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
|
|
70
|
+
if (allBids.abs().gt(allAsks.abs())) {
|
|
71
|
+
return allBids;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return allAsks;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
|
package/src/math/margin.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { squareRootBN } from './utils';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
SPOT_MARKET_WEIGHT_PRECISION,
|
|
4
|
+
SPOT_MARKET_IMF_PRECISION,
|
|
5
5
|
ZERO,
|
|
6
6
|
BID_ASK_SPREAD_PRECISION,
|
|
7
7
|
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
} from '../constants/numericConstants';
|
|
10
10
|
import { BN } from '@project-serum/anchor';
|
|
11
11
|
import { OraclePriceData } from '../oracles/types';
|
|
12
|
-
import {
|
|
12
|
+
import { PerpMarketAccount, PerpPosition } from '..';
|
|
13
|
+
import { assert } from '../assert/assert';
|
|
13
14
|
|
|
14
15
|
export function calculateSizePremiumLiabilityWeight(
|
|
15
16
|
size: BN, // AMM_RESERVE_PRECISION
|
|
@@ -22,14 +23,22 @@ export function calculateSizePremiumLiabilityWeight(
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const sizeSqrt = squareRootBN(size.div(new BN(1000)).add(new BN(1))); //1e13 -> 1e10 -> 1e5
|
|
26
|
+
|
|
27
|
+
const denom0 = BN.max(new BN(1), SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
28
|
+
assert(denom0.gt(ZERO));
|
|
25
29
|
const liabilityWeightNumerator = liabilityWeight.sub(
|
|
26
|
-
liabilityWeight.div(
|
|
30
|
+
liabilityWeight.div(
|
|
31
|
+
BN.max(new BN(1), SPOT_MARKET_IMF_PRECISION.div(imfFactor))
|
|
32
|
+
)
|
|
27
33
|
);
|
|
28
34
|
|
|
35
|
+
const denom = new BN(100_000).mul(SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
36
|
+
assert(denom.gt(ZERO));
|
|
37
|
+
|
|
29
38
|
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(
|
|
30
39
|
sizeSqrt // 1e5
|
|
31
40
|
.mul(imfFactor)
|
|
32
|
-
.div(
|
|
41
|
+
.div(denom) // 1e5
|
|
33
42
|
);
|
|
34
43
|
|
|
35
44
|
const maxLiabilityWeight = BN.max(
|
|
@@ -49,17 +58,19 @@ export function calculateSizeDiscountAssetWeight(
|
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
const sizeSqrt = squareRootBN(size.div(new BN(1000)).add(new BN(1))); //1e13 -> 1e10 -> 1e5
|
|
52
|
-
const imfNumerator =
|
|
53
|
-
|
|
61
|
+
const imfNumerator = SPOT_MARKET_IMF_PRECISION.add(
|
|
62
|
+
SPOT_MARKET_IMF_PRECISION.div(new BN(10))
|
|
54
63
|
);
|
|
55
64
|
|
|
56
|
-
const sizeDiscountAssetWeight = imfNumerator
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
const sizeDiscountAssetWeight = imfNumerator
|
|
66
|
+
.mul(SPOT_MARKET_WEIGHT_PRECISION)
|
|
67
|
+
.div(
|
|
68
|
+
SPOT_MARKET_IMF_PRECISION.add(
|
|
69
|
+
sizeSqrt // 1e5
|
|
70
|
+
.mul(imfFactor)
|
|
71
|
+
.div(new BN(100_000)) // 1e5
|
|
72
|
+
)
|
|
73
|
+
);
|
|
63
74
|
|
|
64
75
|
const minAssetWeight = BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
65
76
|
|
|
@@ -67,8 +78,8 @@ export function calculateSizeDiscountAssetWeight(
|
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
export function calculateOraclePriceForPerpMargin(
|
|
70
|
-
|
|
71
|
-
market:
|
|
81
|
+
perpPosition: PerpPosition,
|
|
82
|
+
market: PerpMarketAccount,
|
|
72
83
|
oraclePriceData: OraclePriceData
|
|
73
84
|
): BN {
|
|
74
85
|
const oraclePriceOffset = BN.min(
|
|
@@ -83,7 +94,7 @@ export function calculateOraclePriceForPerpMargin(
|
|
|
83
94
|
);
|
|
84
95
|
|
|
85
96
|
let marginPrice: BN;
|
|
86
|
-
if (
|
|
97
|
+
if (perpPosition.baseAssetAmount.gt(ZERO)) {
|
|
87
98
|
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
88
99
|
} else {
|
|
89
100
|
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
@@ -93,21 +104,21 @@ export function calculateOraclePriceForPerpMargin(
|
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
export function calculateBaseAssetValueWithOracle(
|
|
96
|
-
market:
|
|
97
|
-
|
|
107
|
+
market: PerpMarketAccount,
|
|
108
|
+
perpPosition: PerpPosition,
|
|
98
109
|
oraclePriceData: OraclePriceData
|
|
99
110
|
): BN {
|
|
100
|
-
return
|
|
111
|
+
return perpPosition.baseAssetAmount
|
|
101
112
|
.abs()
|
|
102
113
|
.mul(oraclePriceData.price)
|
|
103
114
|
.div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
export function calculateWorstCaseBaseAssetAmount(
|
|
107
|
-
|
|
118
|
+
perpPosition: PerpPosition
|
|
108
119
|
): BN {
|
|
109
|
-
const allBids =
|
|
110
|
-
const allAsks =
|
|
120
|
+
const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
|
|
121
|
+
const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
|
|
111
122
|
|
|
112
123
|
if (allBids.abs().gt(allAsks.abs())) {
|
|
113
124
|
return allBids;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.calculateNetUserImbalance = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
4
|
+
var anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
var types_1 = require("../types");
|
|
6
|
+
var amm_1 = require("./amm");
|
|
7
|
+
var margin_1 = require("./margin");
|
|
8
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
9
|
+
var spotBalance_1 = require("./spotBalance");
|
|
10
|
+
/**
|
|
11
|
+
* Calculates market mark price
|
|
12
|
+
*
|
|
13
|
+
* @param market
|
|
14
|
+
* @return markPrice : Precision MARK_PRICE_PRECISION
|
|
15
|
+
*/
|
|
16
|
+
function calculateMarkPrice(market, oraclePriceData) {
|
|
17
|
+
var newAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
|
|
18
|
+
return (0, amm_1.calculatePrice)(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
|
|
19
|
+
}
|
|
20
|
+
exports.calculateMarkPrice = calculateMarkPrice;
|
|
21
|
+
/**
|
|
22
|
+
* Calculates market bid price
|
|
23
|
+
*
|
|
24
|
+
* @param market
|
|
25
|
+
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
26
|
+
*/
|
|
27
|
+
function calculateBidPrice(market, oraclePriceData) {
|
|
28
|
+
var _a = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.SHORT, oraclePriceData), baseAssetReserve = _a.baseAssetReserve, quoteAssetReserve = _a.quoteAssetReserve, newPeg = _a.newPeg;
|
|
29
|
+
return (0, amm_1.calculatePrice)(baseAssetReserve, quoteAssetReserve, newPeg);
|
|
30
|
+
}
|
|
31
|
+
exports.calculateBidPrice = calculateBidPrice;
|
|
32
|
+
/**
|
|
33
|
+
* Calculates market ask price
|
|
34
|
+
*
|
|
35
|
+
* @param market
|
|
36
|
+
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
37
|
+
*/
|
|
38
|
+
function calculateAskPrice(market, oraclePriceData) {
|
|
39
|
+
var _a = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.LONG, oraclePriceData), baseAssetReserve = _a.baseAssetReserve, quoteAssetReserve = _a.quoteAssetReserve, newPeg = _a.newPeg;
|
|
40
|
+
return (0, amm_1.calculatePrice)(baseAssetReserve, quoteAssetReserve, newPeg);
|
|
41
|
+
}
|
|
42
|
+
exports.calculateAskPrice = calculateAskPrice;
|
|
43
|
+
function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
|
|
44
|
+
var _a = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', direction)), newQuoteAssetReserve = _a[0], newBaseAssetReserve = _a[1];
|
|
45
|
+
var newAmm = Object.assign({}, market.amm);
|
|
46
|
+
var newMarket = Object.assign({}, market);
|
|
47
|
+
newMarket.amm = newAmm;
|
|
48
|
+
newMarket.amm.quoteAssetReserve = newQuoteAssetReserve;
|
|
49
|
+
newMarket.amm.baseAssetReserve = newBaseAssetReserve;
|
|
50
|
+
return newMarket;
|
|
51
|
+
}
|
|
52
|
+
exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
|
|
53
|
+
function calculateMarkOracleSpread(market, oraclePriceData) {
|
|
54
|
+
var markPrice = calculateMarkPrice(market, oraclePriceData);
|
|
55
|
+
return calculateOracleSpread(markPrice, oraclePriceData);
|
|
56
|
+
}
|
|
57
|
+
exports.calculateMarkOracleSpread = calculateMarkOracleSpread;
|
|
58
|
+
function calculateOracleSpread(price, oraclePriceData) {
|
|
59
|
+
return price.sub(oraclePriceData.price);
|
|
60
|
+
}
|
|
61
|
+
exports.calculateOracleSpread = calculateOracleSpread;
|
|
62
|
+
function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
63
|
+
var marginRatio;
|
|
64
|
+
switch (marginCategory) {
|
|
65
|
+
case 'Initial':
|
|
66
|
+
marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
67
|
+
break;
|
|
68
|
+
case 'Maintenance':
|
|
69
|
+
marginRatio = market.marginRatioMaintenance;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
return marginRatio;
|
|
73
|
+
}
|
|
74
|
+
exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
|
|
75
|
+
function calculateUnrealizedAssetWeight(market, unrealizedPnl, marginCategory) {
|
|
76
|
+
var assetWeight;
|
|
77
|
+
switch (marginCategory) {
|
|
78
|
+
case 'Initial':
|
|
79
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedImfFactor, new anchor_1.BN(market.unrealizedInitialAssetWeight));
|
|
80
|
+
break;
|
|
81
|
+
case 'Maintenance':
|
|
82
|
+
assetWeight = new anchor_1.BN(market.unrealizedMaintenanceAssetWeight);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
return assetWeight;
|
|
86
|
+
}
|
|
87
|
+
exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
|
|
88
|
+
function calculateMarketAvailablePNL(perpMarket, spotMarket) {
|
|
89
|
+
return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.balance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
90
|
+
}
|
|
91
|
+
exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
|
|
92
|
+
function calculateNetUserImbalance(market, bank, oraclePriceData) {
|
|
93
|
+
var netUserPositionValue = market.amm.netBaseAssetAmount
|
|
94
|
+
.mul(oraclePriceData.price)
|
|
95
|
+
.div(numericConstants_1.BASE_PRECISION)
|
|
96
|
+
.div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
97
|
+
var netUserCostBasis = market.amm.quoteAssetAmountLong
|
|
98
|
+
.add(market.amm.quoteAssetAmountShort)
|
|
99
|
+
.sub(market.amm.cumulativeSocialLoss);
|
|
100
|
+
var userEntitledPnl = netUserPositionValue.add(netUserCostBasis);
|
|
101
|
+
var pnlPool = (0, spotBalance_1.getTokenAmount)(market.pnlPool.balance, bank, types_1.SpotBalanceType.DEPOSIT);
|
|
102
|
+
var imbalance = userEntitledPnl.sub(pnlPool);
|
|
103
|
+
return imbalance;
|
|
104
|
+
}
|
|
105
|
+
exports.calculateNetUserImbalance = calculateNetUserImbalance;
|
package/src/math/market.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BN } from '@project-serum/anchor';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
PerpMarketAccount,
|
|
4
4
|
PositionDirection,
|
|
5
5
|
MarginCategory,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
SpotMarketAccount,
|
|
7
|
+
SpotBalanceType,
|
|
8
8
|
} from '../types';
|
|
9
9
|
import {
|
|
10
10
|
calculateAmmReservesAfterSwap,
|
|
@@ -18,8 +18,13 @@ import {
|
|
|
18
18
|
calculateSizePremiumLiabilityWeight,
|
|
19
19
|
} from './margin';
|
|
20
20
|
import { OraclePriceData } from '../oracles/types';
|
|
21
|
-
import {
|
|
22
|
-
|
|
21
|
+
import {
|
|
22
|
+
BASE_PRECISION,
|
|
23
|
+
MARGIN_PRECISION,
|
|
24
|
+
PRICE_TO_QUOTE_PRECISION,
|
|
25
|
+
ZERO,
|
|
26
|
+
} from '../constants/numericConstants';
|
|
27
|
+
import { getTokenAmount } from './spotBalance';
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
30
|
* Calculates market mark price
|
|
@@ -28,7 +33,7 @@ import { getTokenAmount } from './bankBalance';
|
|
|
28
33
|
* @return markPrice : Precision MARK_PRICE_PRECISION
|
|
29
34
|
*/
|
|
30
35
|
export function calculateMarkPrice(
|
|
31
|
-
market:
|
|
36
|
+
market: PerpMarketAccount,
|
|
32
37
|
oraclePriceData: OraclePriceData
|
|
33
38
|
): BN {
|
|
34
39
|
const newAmm = calculateUpdatedAMM(market.amm, oraclePriceData);
|
|
@@ -46,7 +51,7 @@ export function calculateMarkPrice(
|
|
|
46
51
|
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
47
52
|
*/
|
|
48
53
|
export function calculateBidPrice(
|
|
49
|
-
market:
|
|
54
|
+
market: PerpMarketAccount,
|
|
50
55
|
oraclePriceData: OraclePriceData
|
|
51
56
|
): BN {
|
|
52
57
|
const { baseAssetReserve, quoteAssetReserve, newPeg } =
|
|
@@ -66,7 +71,7 @@ export function calculateBidPrice(
|
|
|
66
71
|
* @return bidPrice : Precision MARK_PRICE_PRECISION
|
|
67
72
|
*/
|
|
68
73
|
export function calculateAskPrice(
|
|
69
|
-
market:
|
|
74
|
+
market: PerpMarketAccount,
|
|
70
75
|
oraclePriceData: OraclePriceData
|
|
71
76
|
): BN {
|
|
72
77
|
const { baseAssetReserve, quoteAssetReserve, newPeg } =
|
|
@@ -82,8 +87,8 @@ export function calculateAskPrice(
|
|
|
82
87
|
export function calculateNewMarketAfterTrade(
|
|
83
88
|
baseAssetAmount: BN,
|
|
84
89
|
direction: PositionDirection,
|
|
85
|
-
market:
|
|
86
|
-
):
|
|
90
|
+
market: PerpMarketAccount
|
|
91
|
+
): PerpMarketAccount {
|
|
87
92
|
const [newQuoteAssetReserve, newBaseAssetReserve] =
|
|
88
93
|
calculateAmmReservesAfterSwap(
|
|
89
94
|
market.amm,
|
|
@@ -102,7 +107,7 @@ export function calculateNewMarketAfterTrade(
|
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
export function calculateMarkOracleSpread(
|
|
105
|
-
market:
|
|
110
|
+
market: PerpMarketAccount,
|
|
106
111
|
oraclePriceData: OraclePriceData
|
|
107
112
|
): BN {
|
|
108
113
|
const markPrice = calculateMarkPrice(market, oraclePriceData);
|
|
@@ -117,7 +122,7 @@ export function calculateOracleSpread(
|
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
export function calculateMarketMarginRatio(
|
|
120
|
-
market:
|
|
125
|
+
market: PerpMarketAccount,
|
|
121
126
|
size: BN,
|
|
122
127
|
marginCategory: MarginCategory
|
|
123
128
|
): number {
|
|
@@ -140,18 +145,34 @@ export function calculateMarketMarginRatio(
|
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
export function calculateUnrealizedAssetWeight(
|
|
143
|
-
market:
|
|
148
|
+
market: PerpMarketAccount,
|
|
149
|
+
quoteSpotMarket: SpotMarketAccount,
|
|
144
150
|
unrealizedPnl: BN,
|
|
145
|
-
marginCategory: MarginCategory
|
|
151
|
+
marginCategory: MarginCategory,
|
|
152
|
+
oraclePriceData: OraclePriceData
|
|
146
153
|
): BN {
|
|
147
154
|
let assetWeight: BN;
|
|
148
|
-
|
|
149
155
|
switch (marginCategory) {
|
|
150
156
|
case 'Initial':
|
|
157
|
+
assetWeight = new BN(market.unrealizedInitialAssetWeight);
|
|
158
|
+
|
|
159
|
+
if (market.unrealizedMaxImbalance.gt(ZERO)) {
|
|
160
|
+
const netUnsettledPnl = calculateNetUserImbalance(
|
|
161
|
+
market,
|
|
162
|
+
quoteSpotMarket,
|
|
163
|
+
oraclePriceData
|
|
164
|
+
);
|
|
165
|
+
if (netUnsettledPnl.gt(market.unrealizedMaxImbalance)) {
|
|
166
|
+
assetWeight = assetWeight
|
|
167
|
+
.mul(market.unrealizedMaxImbalance)
|
|
168
|
+
.div(netUnsettledPnl);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
151
172
|
assetWeight = calculateSizeDiscountAssetWeight(
|
|
152
173
|
unrealizedPnl,
|
|
153
174
|
market.unrealizedImfFactor,
|
|
154
|
-
|
|
175
|
+
assetWeight
|
|
155
176
|
);
|
|
156
177
|
break;
|
|
157
178
|
case 'Maintenance':
|
|
@@ -163,8 +184,39 @@ export function calculateUnrealizedAssetWeight(
|
|
|
163
184
|
}
|
|
164
185
|
|
|
165
186
|
export function calculateMarketAvailablePNL(
|
|
166
|
-
|
|
167
|
-
|
|
187
|
+
perpMarket: PerpMarketAccount,
|
|
188
|
+
spotMarket: SpotMarketAccount
|
|
189
|
+
): BN {
|
|
190
|
+
return getTokenAmount(
|
|
191
|
+
perpMarket.pnlPool.balance,
|
|
192
|
+
spotMarket,
|
|
193
|
+
SpotBalanceType.DEPOSIT
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function calculateNetUserImbalance(
|
|
198
|
+
market: PerpMarketAccount,
|
|
199
|
+
bank: SpotMarketAccount,
|
|
200
|
+
oraclePriceData: OraclePriceData
|
|
168
201
|
): BN {
|
|
169
|
-
|
|
202
|
+
const netUserPositionValue = market.amm.netBaseAssetAmount
|
|
203
|
+
.mul(oraclePriceData.price)
|
|
204
|
+
.div(BASE_PRECISION)
|
|
205
|
+
.div(PRICE_TO_QUOTE_PRECISION);
|
|
206
|
+
|
|
207
|
+
const netUserCostBasis = market.amm.quoteAssetAmountLong
|
|
208
|
+
.add(market.amm.quoteAssetAmountShort)
|
|
209
|
+
.sub(market.amm.cumulativeSocialLoss);
|
|
210
|
+
|
|
211
|
+
const userEntitledPnl = netUserPositionValue.add(netUserCostBasis);
|
|
212
|
+
|
|
213
|
+
const pnlPool = getTokenAmount(
|
|
214
|
+
market.pnlPool.balance,
|
|
215
|
+
bank,
|
|
216
|
+
SpotBalanceType.DEPOSIT
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
const imbalance = userEntitledPnl.sub(pnlPool);
|
|
220
|
+
|
|
221
|
+
return imbalance;
|
|
170
222
|
}
|
package/src/math/oracles.js
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.isOracleValid = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.isOracleTooDivergent = exports.isOracleValid = exports.oraclePriceBands = void 0;
|
|
4
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
var index_1 = require("../index");
|
|
6
|
+
var assert_1 = require("../assert/assert");
|
|
7
|
+
function oraclePriceBands(market, oraclePriceData) {
|
|
8
|
+
var maxPercentDiff = market.marginRatioInitial - market.marginRatioMaintenance;
|
|
9
|
+
var 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
|
-
|
|
8
|
-
|
|
17
|
+
var isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
|
|
18
|
+
var isOraclePriceTooVolatile = oraclePriceData.price
|
|
9
19
|
.div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
|
|
10
20
|
.gt(oracleGuardRails.validity.tooVolatileRatio) ||
|
|
11
21
|
amm.lastOraclePriceTwap
|
|
12
22
|
.div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
|
|
13
23
|
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
14
|
-
|
|
15
|
-
.
|
|
16
|
-
.
|
|
17
|
-
|
|
24
|
+
var 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));
|
|
29
|
+
var oracleIsStale = oraclePriceData.slot
|
|
18
30
|
.sub(new index_1.BN(slot))
|
|
19
31
|
.gt(oracleGuardRails.validity.slotsBeforeStale);
|
|
20
32
|
return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
|
|
@@ -24,3 +36,21 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
|
24
36
|
isConfidenceTooLarge);
|
|
25
37
|
}
|
|
26
38
|
exports.isOracleValid = isOracleValid;
|
|
39
|
+
function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
40
|
+
var sinceLastUpdate = now.sub(amm.lastOraclePriceTwapTs);
|
|
41
|
+
var sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
|
|
42
|
+
var oracleTwap5min = amm.lastOraclePriceTwap5min
|
|
43
|
+
.mul(sinceStart)
|
|
44
|
+
.add(oraclePriceData.price)
|
|
45
|
+
.mul(sinceLastUpdate)
|
|
46
|
+
.div(sinceStart.add(sinceLastUpdate));
|
|
47
|
+
var oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
48
|
+
var oracleSpreadPct = oracleSpread
|
|
49
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
50
|
+
.div(oracleTwap5min);
|
|
51
|
+
var tooDivergent = oracleSpreadPct
|
|
52
|
+
.abs()
|
|
53
|
+
.gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
|
|
54
|
+
return tooDivergent;
|
|
55
|
+
}
|
|
56
|
+
exports.isOracleTooDivergent = isOracleTooDivergent;
|
package/src/math/oracles.ts
CHANGED
|
@@ -2,11 +2,28 @@ import { AMM, OracleGuardRails } from '../types';
|
|
|
2
2
|
import { OraclePriceData } from '../oracles/types';
|
|
3
3
|
import {
|
|
4
4
|
BID_ASK_SPREAD_PRECISION,
|
|
5
|
+
MARGIN_PRECISION,
|
|
5
6
|
MARK_PRICE_PRECISION,
|
|
6
7
|
ONE,
|
|
7
8
|
ZERO,
|
|
8
9
|
} from '../constants/numericConstants';
|
|
9
|
-
import { BN } from '../index';
|
|
10
|
+
import { BN, PerpMarketAccount } from '../index';
|
|
11
|
+
import { assert } from '../assert/assert';
|
|
12
|
+
|
|
13
|
+
export function oraclePriceBands(
|
|
14
|
+
market: PerpMarketAccount,
|
|
15
|
+
oraclePriceData: OraclePriceData
|
|
16
|
+
): [BN, BN] {
|
|
17
|
+
const maxPercentDiff =
|
|
18
|
+
market.marginRatioInitial - market.marginRatioMaintenance;
|
|
19
|
+
const offset = oraclePriceData.price
|
|
20
|
+
.mul(new BN(maxPercentDiff))
|
|
21
|
+
.div(MARGIN_PRECISION);
|
|
22
|
+
|
|
23
|
+
assert(offset.gt(ZERO));
|
|
24
|
+
|
|
25
|
+
return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
|
|
26
|
+
}
|
|
10
27
|
|
|
11
28
|
export function isOracleValid(
|
|
12
29
|
amm: AMM,
|