@drift-labs/sdk 0.2.0-master.29 → 0.2.0-master.30
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 +13 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +10 -11
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +4 -4
- package/lib/accounts/types.d.ts +4 -6
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +10 -11
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +6 -8
- package/lib/addresses/marketAddresses.d.ts +1 -3
- package/lib/addresses/pda.d.ts +5 -5
- package/lib/addresses/pda.js +5 -5
- package/lib/admin.d.ts +27 -28
- package/lib/admin.js +12 -37
- package/lib/clearingHouse.d.ts +61 -62
- package/lib/clearingHouse.js +92 -110
- package/lib/clearingHouseConfig.d.ts +2 -4
- package/lib/clearingHouseUser.d.ts +16 -16
- package/lib/clearingHouseUser.js +16 -16
- package/lib/config.d.ts +2 -4
- package/lib/config.js +1 -1
- package/lib/constants/numericConstants.d.ts +7 -8
- package/lib/constants/numericConstants.js +17 -18
- package/lib/constants/perpMarkets.d.ts +2 -3
- package/lib/constants/perpMarkets.js +3 -3
- package/lib/constants/spotMarkets.d.ts +2 -1
- package/lib/constants/spotMarkets.js +6 -4
- package/lib/dlob/DLOB.d.ts +13 -13
- package/lib/dlob/DLOB.js +36 -40
- package/lib/dlob/DLOBNode.js +2 -2
- package/lib/events/sort.js +1 -1
- package/lib/examples/makeTradeExample.js +3 -3
- package/lib/idl/clearing_house.json +359 -310
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +10 -10
- package/lib/math/conversion.js +1 -1
- package/lib/math/funding.js +9 -9
- package/lib/math/margin.js +3 -3
- package/lib/math/market.d.ts +4 -4
- package/lib/math/market.js +7 -7
- package/lib/math/oracles.js +6 -8
- package/lib/math/position.d.ts +2 -2
- package/lib/math/position.js +9 -9
- package/lib/math/repeg.js +7 -6
- package/lib/math/spotBalance.js +5 -5
- package/lib/math/spotPosition.js +2 -2
- package/lib/math/trade.d.ts +6 -6
- package/lib/math/trade.js +15 -19
- package/lib/oracles/pythClient.js +1 -1
- package/lib/oracles/quoteAssetOracleClient.js +1 -1
- package/lib/oracles/switchboardClient.js +1 -1
- package/lib/types.d.ts +63 -51
- package/lib/types.js +1 -1
- package/package.json +2 -1
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +15 -15
- package/src/accounts/types.ts +4 -5
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +17 -25
- package/src/addresses/marketAddresses.ts +1 -2
- package/src/addresses/pda.ts +10 -10
- package/src/admin.ts +42 -79
- package/src/clearingHouse.ts +164 -212
- package/src/clearingHouseConfig.ts +2 -3
- package/src/clearingHouseUser.ts +35 -35
- package/src/config.ts +3 -4
- package/src/constants/numericConstants.ts +19 -21
- package/src/constants/perpMarkets.ts +5 -5
- package/src/constants/spotMarkets.ts +8 -5
- package/src/dlob/DLOB.ts +54 -70
- package/src/dlob/DLOBNode.ts +5 -6
- package/src/events/sort.ts +1 -1
- package/src/examples/makeTradeExample.js +2 -2
- package/src/examples/makeTradeExample.ts +5 -8
- package/src/idl/clearing_house.json +359 -310
- package/src/math/amm.ts +14 -11
- package/src/math/conversion.ts +2 -2
- package/src/math/funding.ts +13 -11
- package/src/math/margin.ts +4 -5
- package/src/math/market.ts +5 -5
- package/src/math/oracles.ts +9 -9
- package/src/math/position.ts +11 -19
- package/src/math/repeg.ts +8 -7
- package/src/math/spotBalance.ts +6 -6
- package/src/math/spotPosition.ts +2 -2
- package/src/math/trade.ts +17 -21
- package/src/oracles/pythClient.ts +2 -2
- package/src/oracles/quoteAssetOracleClient.ts +2 -2
- package/src/oracles/switchboardClient.ts +2 -2
- package/src/types.ts +69 -51
- package/tests/dlob/helpers.ts +56 -4
- package/src/addresses/marketAddresses.js +0 -26
- package/src/constants/banks.js +0 -42
- package/src/constants/markets.js +0 -42
- package/src/events/txEventCache.js +0 -71
- package/src/factory/bigNum.js +0 -390
- package/src/factory/oracleClient.js +0 -20
- package/src/math/auction.js +0 -42
- package/src/math/conversion.js +0 -11
- package/src/math/funding.js +0 -248
- package/src/math/repeg.js +0 -128
- package/src/math/trade.js +0 -253
- package/src/math/utils.js +0 -26
- package/src/math/utils.js.map +0 -1
- 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/oracles/types.js +0 -2
- package/src/userName.js +0 -20
- package/src/wallet.js +0 -35
package/lib/math/amm.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePr
|
|
|
19
19
|
* @param baseAssetReserves
|
|
20
20
|
* @param quoteAssetReserves
|
|
21
21
|
* @param pegMultiplier
|
|
22
|
-
* @returns price : Precision
|
|
22
|
+
* @returns price : Precision PRICE_PRECISION
|
|
23
23
|
*/
|
|
24
24
|
export declare function calculatePrice(baseAssetReserves: BN, quoteAssetReserves: BN, pegMultiplier: BN): BN;
|
|
25
25
|
export declare type AssetType = 'quote' | 'base';
|
|
@@ -64,7 +64,7 @@ export declare function getSwapDirection(inputAssetType: AssetType, positionDire
|
|
|
64
64
|
* Helper function calculating terminal price of amm
|
|
65
65
|
*
|
|
66
66
|
* @param market
|
|
67
|
-
* @returns cost : Precision
|
|
67
|
+
* @returns cost : Precision PRICE_PRECISION
|
|
68
68
|
*/
|
|
69
69
|
export declare function calculateTerminalPrice(market: PerpMarketAccount): BN;
|
|
70
70
|
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData): [BN, PositionDirection];
|
package/lib/math/amm.js
CHANGED
|
@@ -127,14 +127,14 @@ exports.calculateBidAskPrice = calculateBidAskPrice;
|
|
|
127
127
|
* @param baseAssetReserves
|
|
128
128
|
* @param quoteAssetReserves
|
|
129
129
|
* @param pegMultiplier
|
|
130
|
-
* @returns price : Precision
|
|
130
|
+
* @returns price : Precision PRICE_PRECISION
|
|
131
131
|
*/
|
|
132
132
|
function calculatePrice(baseAssetReserves, quoteAssetReserves, pegMultiplier) {
|
|
133
133
|
if (baseAssetReserves.abs().lte(numericConstants_1.ZERO)) {
|
|
134
134
|
return new anchor_1.BN(0);
|
|
135
135
|
}
|
|
136
136
|
return quoteAssetReserves
|
|
137
|
-
.mul(numericConstants_1.
|
|
137
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
138
138
|
.mul(pegMultiplier)
|
|
139
139
|
.div(numericConstants_1.PEG_PRECISION)
|
|
140
140
|
.div(baseAssetReserves);
|
|
@@ -187,10 +187,10 @@ exports.calculateMarketOpenBidAsk = calculateMarketOpenBidAsk;
|
|
|
187
187
|
function calculateInventoryScale(netBaseAssetAmount, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
|
|
188
188
|
// inventory skew
|
|
189
189
|
const [openBids, openAsks] = calculateMarketOpenBidAsk(baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve);
|
|
190
|
-
const
|
|
191
|
-
const inventoryScale = anchor_1.BN.min(netBaseAssetAmount.abs(),
|
|
192
|
-
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(new anchor_1.BN(
|
|
193
|
-
.div(
|
|
190
|
+
const minSideLiquidity = anchor_1.BN.max(new anchor_1.BN(1), anchor_1.BN.min(openBids.abs(), openAsks.abs()));
|
|
191
|
+
const inventoryScale = anchor_1.BN.min(netBaseAssetAmount.abs(), minSideLiquidity)
|
|
192
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(new anchor_1.BN(10)))
|
|
193
|
+
.div(minSideLiquidity)
|
|
194
194
|
.toNumber() / numericConstants_1.BID_ASK_SPREAD_PRECISION.toNumber();
|
|
195
195
|
return inventoryScale;
|
|
196
196
|
}
|
|
@@ -203,7 +203,7 @@ function calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuote
|
|
|
203
203
|
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
204
204
|
const localBaseAssetValue = netBaseAssetAmount
|
|
205
205
|
.mul(markPrice)
|
|
206
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.
|
|
206
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.PRICE_PRECISION));
|
|
207
207
|
const effectiveLeverage = localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
|
|
208
208
|
(Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
|
|
209
209
|
1 / numericConstants_1.QUOTE_PRECISION.toNumber();
|
|
@@ -353,7 +353,7 @@ exports.getSwapDirection = getSwapDirection;
|
|
|
353
353
|
* Helper function calculating terminal price of amm
|
|
354
354
|
*
|
|
355
355
|
* @param market
|
|
356
|
-
* @returns cost : Precision
|
|
356
|
+
* @returns cost : Precision PRICE_PRECISION
|
|
357
357
|
*/
|
|
358
358
|
function calculateTerminalPrice(market) {
|
|
359
359
|
const directionToClose = market.amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
|
|
@@ -361,7 +361,7 @@ function calculateTerminalPrice(market) {
|
|
|
361
361
|
: types_1.PositionDirection.LONG;
|
|
362
362
|
const [newQuoteAssetReserve, newBaseAssetReserve] = calculateAmmReservesAfterSwap(market.amm, 'base', market.amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose));
|
|
363
363
|
const terminalPrice = newQuoteAssetReserve
|
|
364
|
-
.mul(numericConstants_1.
|
|
364
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
365
365
|
.mul(market.amm.pegMultiplier)
|
|
366
366
|
.div(numericConstants_1.PEG_PRECISION)
|
|
367
367
|
.div(newBaseAssetReserve);
|
|
@@ -371,7 +371,7 @@ exports.calculateTerminalPrice = calculateTerminalPrice;
|
|
|
371
371
|
function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData) {
|
|
372
372
|
const invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
373
373
|
const newBaseAssetReserveSquared = invariant
|
|
374
|
-
.mul(numericConstants_1.
|
|
374
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
375
375
|
.mul(amm.pegMultiplier)
|
|
376
376
|
.div(limit_price)
|
|
377
377
|
.div(numericConstants_1.PEG_PRECISION);
|
package/lib/math/conversion.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.convertToNumber = void 0;
|
|
4
4
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
-
const convertToNumber = (bigNumber, precision = numericConstants_1.
|
|
5
|
+
const convertToNumber = (bigNumber, precision = numericConstants_1.PRICE_PRECISION) => {
|
|
6
6
|
if (!bigNumber)
|
|
7
7
|
return 0;
|
|
8
8
|
return (bigNumber.div(precision).toNumber() +
|
package/lib/math/funding.js
CHANGED
|
@@ -32,15 +32,15 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
32
32
|
const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
|
|
33
33
|
const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
|
|
34
34
|
const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
|
|
35
|
-
const baseAssetPriceWithMantissa = (0, market_1.
|
|
35
|
+
const baseAssetPriceWithMantissa = (0, market_1.calculateReservePrice)(market, oraclePriceData);
|
|
36
36
|
const markTwapWithMantissa = markTwapTimeSinceLastUpdate
|
|
37
37
|
.mul(lastMarkTwapWithMantissa)
|
|
38
38
|
.add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
|
|
39
39
|
.div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
|
|
40
40
|
// calculate real-time (predicted) oracle twap
|
|
41
41
|
// note: oracle twap depends on `when the chord is struck` (market is trade)
|
|
42
|
-
const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
|
|
43
|
-
const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
|
|
42
|
+
const lastOracleTwapWithMantissa = market.amm.historicalOracleData.lastOraclePriceTwap;
|
|
43
|
+
const lastOraclePriceTwapTs = market.amm.historicalOracleData.lastOraclePriceTwapTs;
|
|
44
44
|
const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
|
|
45
45
|
const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
|
|
46
46
|
const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
|
|
@@ -51,11 +51,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
51
51
|
const oracleLiveVsTwap = oraclePrice
|
|
52
52
|
.sub(lastOracleTwapWithMantissa)
|
|
53
53
|
.abs()
|
|
54
|
-
.mul(numericConstants_1.
|
|
54
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
55
55
|
.mul(new anchor_1.BN(100))
|
|
56
56
|
.div(lastOracleTwapWithMantissa);
|
|
57
57
|
// verify pyth live input is within 10% of last twap for live update
|
|
58
|
-
if (oracleLiveVsTwap.lte(numericConstants_1.
|
|
58
|
+
if (oracleLiveVsTwap.lte(numericConstants_1.PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
|
|
59
59
|
oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
|
|
60
60
|
.mul(lastOracleTwapWithMantissa)
|
|
61
61
|
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
@@ -68,7 +68,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
68
68
|
.div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
|
|
69
69
|
const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
|
|
70
70
|
const twapSpreadPct = twapSpread
|
|
71
|
-
.mul(numericConstants_1.
|
|
71
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
72
72
|
.mul(new anchor_1.BN(100))
|
|
73
73
|
.div(shrunkLastOracleTwapwithMantissa);
|
|
74
74
|
const lowerboundEst = twapSpreadPct
|
|
@@ -82,7 +82,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
82
82
|
const interpRateQuote = twapSpreadPct
|
|
83
83
|
.mul(periodAdjustment)
|
|
84
84
|
.div(hoursInDay)
|
|
85
|
-
.div(numericConstants_1.
|
|
85
|
+
.div(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
|
|
86
86
|
let feePoolSize = calculateFundingPool(market);
|
|
87
87
|
if (interpRateQuote.lt(new anchor_1.BN(0))) {
|
|
88
88
|
feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
|
|
@@ -129,11 +129,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
129
129
|
// funding smaller flow
|
|
130
130
|
cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
|
|
131
131
|
const feePoolTopOff = feePoolSize
|
|
132
|
-
.mul(numericConstants_1.
|
|
132
|
+
.mul(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
|
|
133
133
|
.mul(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
134
134
|
cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
|
|
135
135
|
cappedAltEst = cappedAltEst
|
|
136
|
-
.mul(numericConstants_1.
|
|
136
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
137
137
|
.mul(new anchor_1.BN(100))
|
|
138
138
|
.div(oracleTwapWithMantissa)
|
|
139
139
|
.mul(periodAdjustment);
|
package/lib/math/margin.js
CHANGED
|
@@ -10,7 +10,7 @@ imfFactor, liabilityWeight, precision) {
|
|
|
10
10
|
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
11
11
|
return liabilityWeight;
|
|
12
12
|
}
|
|
13
|
-
const sizeSqrt = (0, utils_1.squareRootBN)(size.
|
|
13
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
14
14
|
const denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
15
15
|
(0, assert_1.assert)(denom0.gt(numericConstants_1.ZERO));
|
|
16
16
|
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
|
|
@@ -29,7 +29,7 @@ imfFactor, assetWeight) {
|
|
|
29
29
|
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
30
30
|
return assetWeight;
|
|
31
31
|
}
|
|
32
|
-
const sizeSqrt = (0, utils_1.squareRootBN)(size.
|
|
32
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
33
33
|
const imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
34
34
|
const sizeDiscountAssetWeight = imfNumerator
|
|
35
35
|
.mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
@@ -61,7 +61,7 @@ function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData
|
|
|
61
61
|
return perpPosition.baseAssetAmount
|
|
62
62
|
.abs()
|
|
63
63
|
.mul(oraclePriceData.price)
|
|
64
|
-
.div(numericConstants_1.
|
|
64
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
65
65
|
}
|
|
66
66
|
exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
|
|
67
67
|
function calculateWorstCaseBaseAssetAmount(perpPosition) {
|
package/lib/math/market.d.ts
CHANGED
|
@@ -6,21 +6,21 @@ import { OraclePriceData } from '../oracles/types';
|
|
|
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
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 askPrice : Precision
|
|
23
|
+
* @return askPrice : Precision PRICE_PRECISION
|
|
24
24
|
*/
|
|
25
25
|
export declare function calculateAskPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
26
26
|
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
|
package/lib/math/market.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.
|
|
3
|
+
exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const amm_1 = require("./amm");
|
|
@@ -11,18 +11,18 @@ const spotBalance_1 = require("./spotBalance");
|
|
|
11
11
|
* Calculates market mark price
|
|
12
12
|
*
|
|
13
13
|
* @param market
|
|
14
|
-
* @return markPrice : Precision
|
|
14
|
+
* @return markPrice : Precision PRICE_PRECISION
|
|
15
15
|
*/
|
|
16
|
-
function
|
|
16
|
+
function calculateReservePrice(market, oraclePriceData) {
|
|
17
17
|
const newAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
|
|
18
18
|
return (0, amm_1.calculatePrice)(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
|
|
19
19
|
}
|
|
20
|
-
exports.
|
|
20
|
+
exports.calculateReservePrice = calculateReservePrice;
|
|
21
21
|
/**
|
|
22
22
|
* Calculates market bid price
|
|
23
23
|
*
|
|
24
24
|
* @param market
|
|
25
|
-
* @return bidPrice : Precision
|
|
25
|
+
* @return bidPrice : Precision PRICE_PRECISION
|
|
26
26
|
*/
|
|
27
27
|
function calculateBidPrice(market, oraclePriceData) {
|
|
28
28
|
const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.SHORT, oraclePriceData);
|
|
@@ -33,7 +33,7 @@ exports.calculateBidPrice = calculateBidPrice;
|
|
|
33
33
|
* Calculates market ask price
|
|
34
34
|
*
|
|
35
35
|
* @param market
|
|
36
|
-
* @return askPrice : Precision
|
|
36
|
+
* @return askPrice : Precision PRICE_PRECISION
|
|
37
37
|
*/
|
|
38
38
|
function calculateAskPrice(market, oraclePriceData) {
|
|
39
39
|
const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.LONG, oraclePriceData);
|
|
@@ -51,7 +51,7 @@ function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
|
|
|
51
51
|
}
|
|
52
52
|
exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
|
|
53
53
|
function calculateMarkOracleSpread(market, oraclePriceData) {
|
|
54
|
-
const markPrice =
|
|
54
|
+
const markPrice = calculateReservePrice(market, oraclePriceData);
|
|
55
55
|
return calculateOracleSpread(markPrice, oraclePriceData);
|
|
56
56
|
}
|
|
57
57
|
exports.calculateMarkOracleSpread = calculateMarkOracleSpread;
|
package/lib/math/oracles.js
CHANGED
|
@@ -16,9 +16,9 @@ exports.oraclePriceBands = oraclePriceBands;
|
|
|
16
16
|
function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
17
17
|
const isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
|
|
18
18
|
const isOraclePriceTooVolatile = oraclePriceData.price
|
|
19
|
-
.div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
|
|
19
|
+
.div(index_1.BN.max(numericConstants_1.ONE, amm.historicalOracleData.lastOraclePriceTwap))
|
|
20
20
|
.gt(oracleGuardRails.validity.tooVolatileRatio) ||
|
|
21
|
-
amm.lastOraclePriceTwap
|
|
21
|
+
amm.historicalOracleData.lastOraclePriceTwap
|
|
22
22
|
.div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
|
|
23
23
|
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
24
24
|
const isConfidenceTooLarge = new index_1.BN(amm.baseSpread)
|
|
@@ -28,7 +28,7 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
|
28
28
|
.gt(new index_1.BN(amm.maxSpread));
|
|
29
29
|
const oracleIsStale = oraclePriceData.slot
|
|
30
30
|
.sub(new index_1.BN(slot))
|
|
31
|
-
.gt(oracleGuardRails.validity.
|
|
31
|
+
.gt(oracleGuardRails.validity.slotsBeforeStaleForAmm);
|
|
32
32
|
return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
|
|
33
33
|
oracleIsStale ||
|
|
34
34
|
isOraclePriceNonPositive ||
|
|
@@ -37,17 +37,15 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
|
37
37
|
}
|
|
38
38
|
exports.isOracleValid = isOracleValid;
|
|
39
39
|
function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
40
|
-
const sinceLastUpdate = now.sub(amm.lastOraclePriceTwapTs);
|
|
40
|
+
const sinceLastUpdate = now.sub(amm.historicalOracleData.lastOraclePriceTwapTs);
|
|
41
41
|
const sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
|
|
42
|
-
const oracleTwap5min = amm.lastOraclePriceTwap5min
|
|
42
|
+
const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5min
|
|
43
43
|
.mul(sinceStart)
|
|
44
44
|
.add(oraclePriceData.price)
|
|
45
45
|
.mul(sinceLastUpdate)
|
|
46
46
|
.div(sinceStart.add(sinceLastUpdate));
|
|
47
47
|
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
48
|
-
const oracleSpreadPct = oracleSpread
|
|
49
|
-
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
50
|
-
.div(oracleTwap5min);
|
|
48
|
+
const oracleSpreadPct = oracleSpread.mul(numericConstants_1.PRICE_PRECISION).div(oracleTwap5min);
|
|
51
49
|
const tooDivergent = oracleSpreadPct
|
|
52
50
|
.abs()
|
|
53
51
|
.gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
|
package/lib/math/position.d.ts
CHANGED
|
@@ -33,13 +33,13 @@ export declare function positionIsAvailable(position: PerpPosition): boolean;
|
|
|
33
33
|
/**
|
|
34
34
|
*
|
|
35
35
|
* @param userPosition
|
|
36
|
-
* @returns Precision:
|
|
36
|
+
* @returns Precision: PRICE_PRECISION (10^10)
|
|
37
37
|
*/
|
|
38
38
|
export declare function calculateEntryPrice(userPosition: PerpPosition): BN;
|
|
39
39
|
/**
|
|
40
40
|
*
|
|
41
41
|
* @param userPosition
|
|
42
|
-
* @returns Precision:
|
|
42
|
+
* @returns Precision: PRICE_PRECISION (10^10)
|
|
43
43
|
*/
|
|
44
44
|
export declare function calculateCostBasis(userPosition: PerpPosition): BN;
|
|
45
45
|
export declare function findDirectionToClose(userPosition: PerpPosition): PositionDirection;
|
package/lib/math/position.js
CHANGED
|
@@ -75,7 +75,7 @@ function calculatePositionPNL(market, perpPosition, withFunding = false, oracleP
|
|
|
75
75
|
.mul(baseAssetValueSign)
|
|
76
76
|
.add(perpPosition.quoteAssetAmount);
|
|
77
77
|
if (withFunding) {
|
|
78
|
-
const fundingRatePnL = calculatePositionFundingPNL(market, perpPosition)
|
|
78
|
+
const fundingRatePnL = calculatePositionFundingPNL(market, perpPosition);
|
|
79
79
|
pnl = pnl.add(fundingRatePnL);
|
|
80
80
|
}
|
|
81
81
|
return pnl;
|
|
@@ -83,7 +83,7 @@ function calculatePositionPNL(market, perpPosition, withFunding = false, oracleP
|
|
|
83
83
|
exports.calculatePositionPNL = calculatePositionPNL;
|
|
84
84
|
function calculateClaimablePnl(market, spotMarket, perpPosition, oraclePriceData) {
|
|
85
85
|
const unrealizedPnl = calculatePositionPNL(market, perpPosition, true, oraclePriceData);
|
|
86
|
-
const fundingPnL = calculatePositionFundingPNL(market, perpPosition)
|
|
86
|
+
const fundingPnL = calculatePositionFundingPNL(market, perpPosition);
|
|
87
87
|
let unsettledPnl = unrealizedPnl.add(fundingPnL);
|
|
88
88
|
if (unrealizedPnl.gt(numericConstants_1.ZERO)) {
|
|
89
89
|
const excessPnlPool = __1.BN.max(numericConstants_1.ZERO, (0, market_1.calculateNetUserPnlImbalance)(market, spotMarket, oraclePriceData).mul(new __1.BN(-1)));
|
|
@@ -116,14 +116,14 @@ function calculatePositionFundingPNL(market, perpPosition) {
|
|
|
116
116
|
.sub(perpPosition.lastCumulativeFundingRate)
|
|
117
117
|
.mul(perpPosition.baseAssetAmount)
|
|
118
118
|
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
119
|
-
.div(numericConstants_1.
|
|
119
|
+
.div(numericConstants_1.FUNDING_RATE_BUFFER_PRECISION)
|
|
120
120
|
.mul(new __1.BN(-1));
|
|
121
121
|
return perPositionFundingRate;
|
|
122
122
|
}
|
|
123
123
|
exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
|
|
124
124
|
function positionIsAvailable(position) {
|
|
125
125
|
return (position.baseAssetAmount.eq(numericConstants_1.ZERO) &&
|
|
126
|
-
position.openOrders
|
|
126
|
+
position.openOrders === 0 &&
|
|
127
127
|
position.quoteAssetAmount.eq(numericConstants_1.ZERO) &&
|
|
128
128
|
position.lpShares.eq(numericConstants_1.ZERO));
|
|
129
129
|
}
|
|
@@ -131,14 +131,14 @@ exports.positionIsAvailable = positionIsAvailable;
|
|
|
131
131
|
/**
|
|
132
132
|
*
|
|
133
133
|
* @param userPosition
|
|
134
|
-
* @returns Precision:
|
|
134
|
+
* @returns Precision: PRICE_PRECISION (10^10)
|
|
135
135
|
*/
|
|
136
136
|
function calculateEntryPrice(userPosition) {
|
|
137
137
|
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
138
138
|
return numericConstants_1.ZERO;
|
|
139
139
|
}
|
|
140
140
|
return userPosition.quoteEntryAmount
|
|
141
|
-
.mul(numericConstants_1.
|
|
141
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
142
142
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
143
143
|
.div(userPosition.baseAssetAmount)
|
|
144
144
|
.abs();
|
|
@@ -147,14 +147,14 @@ exports.calculateEntryPrice = calculateEntryPrice;
|
|
|
147
147
|
/**
|
|
148
148
|
*
|
|
149
149
|
* @param userPosition
|
|
150
|
-
* @returns Precision:
|
|
150
|
+
* @returns Precision: PRICE_PRECISION (10^10)
|
|
151
151
|
*/
|
|
152
152
|
function calculateCostBasis(userPosition) {
|
|
153
153
|
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
154
154
|
return numericConstants_1.ZERO;
|
|
155
155
|
}
|
|
156
156
|
return userPosition.quoteAssetAmount
|
|
157
|
-
.mul(numericConstants_1.
|
|
157
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
158
158
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
159
159
|
.div(userPosition.baseAssetAmount)
|
|
160
160
|
.abs();
|
|
@@ -173,6 +173,6 @@ function positionCurrentDirection(userPosition) {
|
|
|
173
173
|
}
|
|
174
174
|
exports.positionCurrentDirection = positionCurrentDirection;
|
|
175
175
|
function isEmptyPosition(userPosition) {
|
|
176
|
-
return
|
|
176
|
+
return userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) && userPosition.openOrders === 0;
|
|
177
177
|
}
|
|
178
178
|
exports.isEmptyPosition = isEmptyPosition;
|
package/lib/math/repeg.js
CHANGED
|
@@ -18,13 +18,13 @@ function calculateAdjustKCost(amm, numerator, denomenator) {
|
|
|
18
18
|
const d = amm.netBaseAssetAmount;
|
|
19
19
|
const Q = amm.pegMultiplier;
|
|
20
20
|
const quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
|
|
21
|
-
const p = numerator.mul(numericConstants_1.
|
|
21
|
+
const p = numerator.mul(numericConstants_1.PRICE_PRECISION).div(denomenator);
|
|
22
22
|
const cost = quoteScale
|
|
23
23
|
.div(x.add(d))
|
|
24
24
|
.sub(quoteScale
|
|
25
25
|
.mul(p)
|
|
26
|
-
.div(numericConstants_1.
|
|
27
|
-
.div(x.mul(p).div(numericConstants_1.
|
|
26
|
+
.div(numericConstants_1.PRICE_PRECISION)
|
|
27
|
+
.div(x.mul(p).div(numericConstants_1.PRICE_PRECISION).add(d)))
|
|
28
28
|
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
29
29
|
.div(numericConstants_1.PEG_PRECISION);
|
|
30
30
|
return cost.mul(new anchor_1.BN(-1));
|
|
@@ -74,7 +74,8 @@ function calculateBudgetedKBN(x, y, budget, Q, d) {
|
|
|
74
74
|
// protocol is spending to increase k
|
|
75
75
|
if (C.lt(numericConstants_1.ZERO)) {
|
|
76
76
|
// thus denom1 is negative and solution is unstable
|
|
77
|
-
if (denom1.
|
|
77
|
+
if (denom1.abs().gt(denom2.abs())) {
|
|
78
|
+
console.log('denom1 > denom2', denom1.toString(), denom2.toString());
|
|
78
79
|
console.log('budget cost exceeds stable K solution');
|
|
79
80
|
return [new anchor_1.BN(10000), new anchor_1.BN(1)];
|
|
80
81
|
}
|
|
@@ -129,8 +130,8 @@ function calculateBudgetedPeg(amm, cost, targetPrice) {
|
|
|
129
130
|
if (deltaQuoteAssetReserves.eq(numericConstants_1.ZERO) || useTargetPeg) {
|
|
130
131
|
return targetPeg;
|
|
131
132
|
}
|
|
132
|
-
const deltaPegMultiplier = C.mul(numericConstants_1.
|
|
133
|
-
const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.
|
|
133
|
+
const deltaPegMultiplier = C.mul(numericConstants_1.PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
|
|
134
|
+
const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.PRICE_PRECISION));
|
|
134
135
|
return newPeg;
|
|
135
136
|
}
|
|
136
137
|
exports.calculateBudgetedPeg = calculateBudgetedPeg;
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -6,7 +6,7 @@ const anchor_1 = require("@project-serum/anchor");
|
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
7
|
const margin_1 = require("./margin");
|
|
8
8
|
function getBalance(tokenAmount, spotMarket, balanceType) {
|
|
9
|
-
const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(
|
|
9
|
+
const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(19 - spotMarket.decimals));
|
|
10
10
|
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
11
11
|
? spotMarket.cumulativeDepositInterest
|
|
12
12
|
: spotMarket.cumulativeBorrowInterest;
|
|
@@ -18,7 +18,7 @@ function getBalance(tokenAmount, spotMarket, balanceType) {
|
|
|
18
18
|
}
|
|
19
19
|
exports.getBalance = getBalance;
|
|
20
20
|
function getTokenAmount(balanceAmount, spotMarket, balanceType) {
|
|
21
|
-
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(
|
|
21
|
+
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(19 - spotMarket.decimals));
|
|
22
22
|
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
23
23
|
? spotMarket.cumulativeDepositInterest
|
|
24
24
|
: spotMarket.cumulativeBorrowInterest;
|
|
@@ -38,7 +38,7 @@ function getTokenValue(tokenAmount, spotDecimals, oraclePriceData) {
|
|
|
38
38
|
if (tokenAmount.eq(numericConstants_1.ZERO)) {
|
|
39
39
|
return numericConstants_1.ZERO;
|
|
40
40
|
}
|
|
41
|
-
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(
|
|
41
|
+
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(spotDecimals));
|
|
42
42
|
return tokenAmount.mul(oraclePriceData.price).div(precisionDecrease);
|
|
43
43
|
}
|
|
44
44
|
exports.getTokenValue = getTokenValue;
|
|
@@ -160,12 +160,12 @@ function calculateInterestAccumulated(bank, now) {
|
|
|
160
160
|
const borrowInterest = bank.cumulativeBorrowInterest
|
|
161
161
|
.mul(modifiedBorrowRate)
|
|
162
162
|
.div(numericConstants_1.ONE_YEAR)
|
|
163
|
-
.div(numericConstants_1.
|
|
163
|
+
.div(numericConstants_1.SPOT_MARKET_RATE_PRECISION)
|
|
164
164
|
.add(numericConstants_1.ONE);
|
|
165
165
|
const depositInterest = bank.cumulativeDepositInterest
|
|
166
166
|
.mul(modifiedDepositRate)
|
|
167
167
|
.div(numericConstants_1.ONE_YEAR)
|
|
168
|
-
.div(numericConstants_1.
|
|
168
|
+
.div(numericConstants_1.SPOT_MARKET_RATE_PRECISION);
|
|
169
169
|
return { borrowInterest, depositInterest };
|
|
170
170
|
}
|
|
171
171
|
exports.calculateInterestAccumulated = calculateInterestAccumulated;
|
package/lib/math/spotPosition.js
CHANGED
|
@@ -12,11 +12,11 @@ function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, oraclePriceDa
|
|
|
12
12
|
const tokenAmountAllBidsFill = tokenAmount.add(spotPosition.openBids);
|
|
13
13
|
const tokenAmountAllAsksFill = tokenAmount.add(spotPosition.openAsks);
|
|
14
14
|
if (tokenAmountAllAsksFill.abs().gt(tokenAmountAllBidsFill.abs())) {
|
|
15
|
-
const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.
|
|
15
|
+
const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.openAsks.neg(), spotMarketAccount.decimals, oraclePriceData);
|
|
16
16
|
return [tokenAmountAllBidsFill, worstCaseQuoteTokenAmount];
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
|
-
const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.
|
|
19
|
+
const worstCaseQuoteTokenAmount = (0, spotBalance_1.getTokenValue)(spotPosition.openBids.neg(), spotMarketAccount.decimals, oraclePriceData);
|
|
20
20
|
return [tokenAmountAllAsksFill, worstCaseQuoteTokenAmount];
|
|
21
21
|
}
|
|
22
22
|
}
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -13,13 +13,13 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
|
|
|
13
13
|
* @param useSpread whether to consider spread with calculating slippage
|
|
14
14
|
* @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
|
|
15
15
|
*
|
|
16
|
-
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision
|
|
16
|
+
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision PRICE_PRECISION
|
|
17
17
|
*
|
|
18
|
-
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision
|
|
18
|
+
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision PRICE_PRECISION
|
|
19
19
|
*
|
|
20
|
-
* 'entryPrice' => the average price of the trade : Precision
|
|
20
|
+
* 'entryPrice' => the average price of the trade : Precision PRICE_PRECISION
|
|
21
21
|
*
|
|
22
|
-
* 'newPrice' => the price of the asset after the trade : Precision
|
|
22
|
+
* 'newPrice' => the price of the asset after the trade : Precision PRICE_PRECISION
|
|
23
23
|
*/
|
|
24
24
|
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: PerpMarketAccount, inputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [BN, BN, BN, BN];
|
|
25
25
|
/**
|
|
@@ -47,8 +47,8 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
|
|
|
47
47
|
* [
|
|
48
48
|
* direction => direction of trade required, PositionDirection
|
|
49
49
|
* tradeSize => size of trade required, TODO-PRECISION
|
|
50
|
-
* entryPrice => the entry price for the trade,
|
|
51
|
-
* targetPrice => the target price
|
|
50
|
+
* entryPrice => the entry price for the trade, PRICE_PRECISION
|
|
51
|
+
* targetPrice => the target price PRICE_PRECISION
|
|
52
52
|
* ]
|
|
53
53
|
*/
|
|
54
54
|
export declare function calculateTargetPriceTrade(market: PerpMarketAccount, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [PositionDirection, BN, BN, BN];
|
package/lib/math/trade.js
CHANGED
|
@@ -19,13 +19,13 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
|
|
|
19
19
|
* @param useSpread whether to consider spread with calculating slippage
|
|
20
20
|
* @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
|
|
21
21
|
*
|
|
22
|
-
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision
|
|
22
|
+
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision PRICE_PRECISION
|
|
23
23
|
*
|
|
24
|
-
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision
|
|
24
|
+
* 'pctMaxSlippage' => the percentage change to maxPrice (highest est slippage in execution) : Precision PRICE_PRECISION
|
|
25
25
|
*
|
|
26
|
-
* 'entryPrice' => the average price of the trade : Precision
|
|
26
|
+
* 'entryPrice' => the average price of the trade : Precision PRICE_PRECISION
|
|
27
27
|
*
|
|
28
|
-
* 'newPrice' => the price of the asset after the trade : Precision
|
|
28
|
+
* 'newPrice' => the price of the asset after the trade : Precision PRICE_PRECISION
|
|
29
29
|
*/
|
|
30
30
|
function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
31
31
|
let oldPrice;
|
|
@@ -38,7 +38,7 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
|
-
oldPrice = (0, market_1.
|
|
41
|
+
oldPrice = (0, market_1.calculateReservePrice)(market, oraclePriceData);
|
|
42
42
|
}
|
|
43
43
|
if (amount.eq(numericConstants_1.ZERO)) {
|
|
44
44
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
|
|
@@ -46,7 +46,7 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
46
46
|
const [acquiredBaseReserve, acquiredQuoteReserve, acquiredQuoteAssetAmount] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, oraclePriceData, useSpread);
|
|
47
47
|
const entryPrice = acquiredQuoteAssetAmount
|
|
48
48
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
49
|
-
.mul(numericConstants_1.
|
|
49
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
50
50
|
.div(acquiredBaseReserve.abs());
|
|
51
51
|
let amm;
|
|
52
52
|
if (useSpread && market.amm.baseSpread > 0) {
|
|
@@ -70,12 +70,12 @@ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quo
|
|
|
70
70
|
}
|
|
71
71
|
const pctMaxSlippage = newPrice
|
|
72
72
|
.sub(oldPrice)
|
|
73
|
-
.mul(numericConstants_1.
|
|
73
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
74
74
|
.div(oldPrice)
|
|
75
75
|
.abs();
|
|
76
76
|
const pctAvgSlippage = entryPrice
|
|
77
77
|
.sub(oldPrice)
|
|
78
|
-
.mul(numericConstants_1.
|
|
78
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
79
79
|
.div(oldPrice)
|
|
80
80
|
.abs();
|
|
81
81
|
return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice];
|
|
@@ -130,15 +130,15 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
|
130
130
|
* [
|
|
131
131
|
* direction => direction of trade required, PositionDirection
|
|
132
132
|
* tradeSize => size of trade required, TODO-PRECISION
|
|
133
|
-
* entryPrice => the entry price for the trade,
|
|
134
|
-
* targetPrice => the target price
|
|
133
|
+
* entryPrice => the entry price for the trade, PRICE_PRECISION
|
|
134
|
+
* targetPrice => the target price PRICE_PRECISION
|
|
135
135
|
* ]
|
|
136
136
|
*/
|
|
137
137
|
function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', oraclePriceData, useSpread = true) {
|
|
138
138
|
(0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
|
|
139
139
|
(0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
|
|
140
140
|
(0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
|
|
141
|
-
const markPriceBefore = (0, market_1.
|
|
141
|
+
const markPriceBefore = (0, market_1.calculateReservePrice)(market, oraclePriceData);
|
|
142
142
|
const bidPriceBefore = (0, market_1.calculateBidPrice)(market, oraclePriceData);
|
|
143
143
|
const askPriceBefore = (0, market_1.calculateAskPrice)(market, oraclePriceData);
|
|
144
144
|
let direction;
|
|
@@ -170,7 +170,7 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
170
170
|
quoteAssetReserveBefore = market.amm.quoteAssetReserve;
|
|
171
171
|
}
|
|
172
172
|
const invariant = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
173
|
-
const k = invariant.mul(numericConstants_1.
|
|
173
|
+
const k = invariant.mul(numericConstants_1.PRICE_PRECISION);
|
|
174
174
|
let baseAssetReserveAfter;
|
|
175
175
|
let quoteAssetReserveAfter;
|
|
176
176
|
const biasModifier = new anchor_1.BN(1);
|
|
@@ -191,9 +191,7 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
191
191
|
else if (markPriceBefore.gt(targetPrice)) {
|
|
192
192
|
// overestimate y2
|
|
193
193
|
baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
|
|
194
|
-
quoteAssetReserveAfter = k
|
|
195
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
196
|
-
.div(baseAssetReserveAfter);
|
|
194
|
+
quoteAssetReserveAfter = k.div(numericConstants_1.PRICE_PRECISION).div(baseAssetReserveAfter);
|
|
197
195
|
markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
|
|
198
196
|
direction = types_1.PositionDirection.SHORT;
|
|
199
197
|
tradeSize = quoteAssetReserveBefore
|
|
@@ -206,9 +204,7 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
206
204
|
else if (markPriceBefore.lt(targetPrice)) {
|
|
207
205
|
// underestimate y2
|
|
208
206
|
baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).add(biasModifier)).add(new anchor_1.BN(1));
|
|
209
|
-
quoteAssetReserveAfter = k
|
|
210
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
211
|
-
.div(baseAssetReserveAfter);
|
|
207
|
+
quoteAssetReserveAfter = k.div(numericConstants_1.PRICE_PRECISION).div(baseAssetReserveAfter);
|
|
212
208
|
markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
|
|
213
209
|
direction = types_1.PositionDirection.LONG;
|
|
214
210
|
tradeSize = quoteAssetReserveAfter
|
|
@@ -234,7 +230,7 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
234
230
|
}
|
|
235
231
|
const entryPrice = tradeSize
|
|
236
232
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
237
|
-
.mul(numericConstants_1.
|
|
233
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
238
234
|
.div(baseSize.abs());
|
|
239
235
|
(0, assert_1.assert)(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
|
|
240
236
|
(0, assert_1.assert)(tp2.lte(tp1) || tp2.sub(tp1).abs() < 100000, 'Target Price Calculation incorrect' +
|