@drift-labs/sdk 2.92.0-beta.2 → 2.92.0-beta.3
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/VERSION +1 -1
- package/bun.lockb +0 -0
- package/lib/adminClient.d.ts +2 -0
- package/lib/adminClient.js +17 -0
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +2 -1
- package/lib/dlob/orderBookLevels.js +1 -1
- package/lib/driftClient.js +1 -0
- package/lib/idl/drift.json +26 -0
- package/lib/math/amm.d.ts +5 -4
- package/lib/math/amm.js +35 -8
- package/lib/math/margin.d.ts +14 -1
- package/lib/math/margin.js +45 -7
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -0
- package/lib/user.d.ts +15 -6
- package/lib/user.js +118 -75
- package/package.json +1 -1
- package/src/adminClient.ts +30 -0
- package/src/constants/numericConstants.ts +2 -0
- package/src/dlob/orderBookLevels.ts +2 -1
- package/src/driftClient.ts +1 -0
- package/src/idl/drift.json +26 -0
- package/src/math/amm.ts +55 -7
- package/src/math/margin.ts +70 -5
- package/src/types.ts +1 -0
- package/src/user.ts +201 -92
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.92.0-beta.
|
|
1
|
+
2.92.0-beta.3
|
package/bun.lockb
CHANGED
|
Binary file
|
package/lib/adminClient.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare class AdminClient extends DriftClient {
|
|
|
21
21
|
getInitializeOpenbookV2FulfillmentConfigIx(marketIndex: number, openbookMarket: PublicKey): Promise<TransactionInstruction>;
|
|
22
22
|
initializePerpMarket(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, contractTier?: ContractTier, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, ifLiquidatorFee?: number, imfFactor?: number, activeStatus?: boolean, baseSpread?: number, maxSpread?: number, maxOpenInterest?: BN, maxRevenueWithdrawPerPeriod?: BN, quoteMaxInsurance?: BN, orderStepSize?: BN, orderTickSize?: BN, minOrderSize?: BN, concentrationCoefScale?: BN, curveUpdateIntensity?: number, ammJitIntensity?: number, name?: string): Promise<TransactionSignature>;
|
|
23
23
|
getInitializePerpMarketIx(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, contractTier?: ContractTier, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, ifLiquidatorFee?: number, imfFactor?: number, activeStatus?: boolean, baseSpread?: number, maxSpread?: number, maxOpenInterest?: BN, maxRevenueWithdrawPerPeriod?: BN, quoteMaxInsurance?: BN, orderStepSize?: BN, orderTickSize?: BN, minOrderSize?: BN, concentrationCoefScale?: BN, curveUpdateIntensity?: number, ammJitIntensity?: number, name?: string): Promise<TransactionInstruction>;
|
|
24
|
+
initializePredictionMarket(perpMarketIndex: number): Promise<TransactionSignature>;
|
|
25
|
+
getInitializePredictionMarketIx(perpMarketIndex: number): Promise<TransactionInstruction>;
|
|
24
26
|
deleteInitializedPerpMarket(marketIndex: number): Promise<TransactionSignature>;
|
|
25
27
|
getDeleteInitializedPerpMarketIx(marketIndex: number): Promise<TransactionInstruction>;
|
|
26
28
|
moveAmmPrice(perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN): Promise<TransactionSignature>;
|
package/lib/adminClient.js
CHANGED
|
@@ -236,6 +236,23 @@ class AdminClient extends driftClient_1.DriftClient {
|
|
|
236
236
|
},
|
|
237
237
|
});
|
|
238
238
|
}
|
|
239
|
+
async initializePredictionMarket(perpMarketIndex) {
|
|
240
|
+
const updatePerpMarketConcentrationCoefIx = await this.getInitializePredictionMarketIx(perpMarketIndex);
|
|
241
|
+
const tx = await this.buildTransaction(updatePerpMarketConcentrationCoefIx);
|
|
242
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
243
|
+
return txSig;
|
|
244
|
+
}
|
|
245
|
+
async getInitializePredictionMarketIx(perpMarketIndex) {
|
|
246
|
+
return await this.program.instruction.initializePredictionMarket({
|
|
247
|
+
accounts: {
|
|
248
|
+
state: await this.getStatePublicKey(),
|
|
249
|
+
admin: this.isSubscribed
|
|
250
|
+
? this.getStateAccount().admin
|
|
251
|
+
: this.wallet.publicKey,
|
|
252
|
+
perpMarket: await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex),
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
}
|
|
239
256
|
async deleteInitializedPerpMarket(marketIndex) {
|
|
240
257
|
const deleteInitializeMarketIx = await this.getDeleteInitializedPerpMarketIx(marketIndex);
|
|
241
258
|
const tx = await this.buildTransaction(deleteInitializeMarketIx);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE_ORDER_SIZE = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
4
|
-
exports.FUEL_START_TS = exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.GOV_SPOT_MARKET_INDEX = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
|
|
4
|
+
exports.MAX_PREDICTION_PRICE = exports.FUEL_START_TS = exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.GOV_SPOT_MARKET_INDEX = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
|
|
5
5
|
const web3_js_1 = require("@solana/web3.js");
|
|
6
6
|
const __1 = require("../");
|
|
7
7
|
exports.ZERO = new __1.BN(0);
|
|
@@ -72,3 +72,4 @@ exports.SLOT_TIME_ESTIMATE_MS = 400;
|
|
|
72
72
|
exports.DUST_POSITION_SIZE = exports.QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
|
|
73
73
|
exports.FUEL_WINDOW = new __1.BN(60 * 60 * 24 * 28); // 28 days
|
|
74
74
|
exports.FUEL_START_TS = new __1.BN(1723147200); // unix timestamp
|
|
75
|
+
exports.MAX_PREDICTION_PRICE = exports.PRICE_PRECISION;
|
|
@@ -104,7 +104,7 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, to
|
|
|
104
104
|
openAsks = __1.ZERO;
|
|
105
105
|
}
|
|
106
106
|
now = now !== null && now !== void 0 ? now : new __1.BN(Date.now() / 1000);
|
|
107
|
-
const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now);
|
|
107
|
+
const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now, (0, __1.isVariant)(marketAccount.contractType, 'prediction'));
|
|
108
108
|
let numBids = 0;
|
|
109
109
|
let topOfBookBidSize = __1.ZERO;
|
|
110
110
|
let bidSize = openBids.div(new __1.BN(numBaseOrders));
|
package/lib/driftClient.js
CHANGED
|
@@ -3980,6 +3980,7 @@ class DriftClient {
|
|
|
3980
3980
|
}
|
|
3981
3981
|
const [pullIx, _responses, success] = await feedAccount.fetchUpdateIx({
|
|
3982
3982
|
numSignatures,
|
|
3983
|
+
// @ts-ignore :: TODO someone needs to look at this
|
|
3983
3984
|
feedConfigs: this.sbProgramFeedConfigs.get(feed.toString()),
|
|
3984
3985
|
});
|
|
3985
3986
|
if (!success) {
|
package/lib/idl/drift.json
CHANGED
|
@@ -3403,6 +3403,27 @@
|
|
|
3403
3403
|
}
|
|
3404
3404
|
]
|
|
3405
3405
|
},
|
|
3406
|
+
{
|
|
3407
|
+
"name": "initializePredictionMarket",
|
|
3408
|
+
"accounts": [
|
|
3409
|
+
{
|
|
3410
|
+
"name": "admin",
|
|
3411
|
+
"isMut": false,
|
|
3412
|
+
"isSigner": true
|
|
3413
|
+
},
|
|
3414
|
+
{
|
|
3415
|
+
"name": "state",
|
|
3416
|
+
"isMut": false,
|
|
3417
|
+
"isSigner": false
|
|
3418
|
+
},
|
|
3419
|
+
{
|
|
3420
|
+
"name": "perpMarket",
|
|
3421
|
+
"isMut": true,
|
|
3422
|
+
"isSigner": false
|
|
3423
|
+
}
|
|
3424
|
+
],
|
|
3425
|
+
"args": []
|
|
3426
|
+
},
|
|
3406
3427
|
{
|
|
3407
3428
|
"name": "deleteInitializedPerpMarket",
|
|
3408
3429
|
"accounts": [
|
|
@@ -12906,6 +12927,11 @@
|
|
|
12906
12927
|
"code": 6283,
|
|
12907
12928
|
"name": "LiquidationOrderFailedToFill",
|
|
12908
12929
|
"msg": "Liquidation order failed to fill"
|
|
12930
|
+
},
|
|
12931
|
+
{
|
|
12932
|
+
"code": 6284,
|
|
12933
|
+
"name": "InvalidPredictionMarketOrder",
|
|
12934
|
+
"msg": "Invalid prediction market order"
|
|
12909
12935
|
}
|
|
12910
12936
|
],
|
|
12911
12937
|
"metadata": {
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -6,13 +6,13 @@ export declare function calculatePegFromTargetPrice(targetPrice: BN, baseAssetRe
|
|
|
6
6
|
export declare function calculateOptimalPegAndBudget(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN, BN, boolean];
|
|
7
7
|
export declare function calculateNewAmm(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN, BN, BN];
|
|
8
8
|
export declare function calculateUpdatedAMM(amm: AMM, oraclePriceData: OraclePriceData): AMM;
|
|
9
|
-
export declare function calculateUpdatedAMMSpreadReserves(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData): {
|
|
9
|
+
export declare function calculateUpdatedAMMSpreadReserves(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData, isPrediction?: boolean): {
|
|
10
10
|
baseAssetReserve: BN;
|
|
11
11
|
quoteAssetReserve: BN;
|
|
12
12
|
sqrtK: BN;
|
|
13
13
|
newPeg: BN;
|
|
14
14
|
};
|
|
15
|
-
export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePriceData, withUpdate?: boolean): [BN, BN];
|
|
15
|
+
export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePriceData, withUpdate?: boolean, isPrediction?: boolean): [BN, BN];
|
|
16
16
|
/**
|
|
17
17
|
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
18
18
|
*
|
|
@@ -64,7 +64,8 @@ export declare function calculateSpreadBN(baseSpread: number, lastOracleReserveP
|
|
|
64
64
|
shortSpread: number;
|
|
65
65
|
};
|
|
66
66
|
export declare function calculateSpread(amm: AMM, oraclePriceData: OraclePriceData, now?: BN, reservePrice?: BN): [number, number];
|
|
67
|
-
export declare function
|
|
67
|
+
export declare function getQuoteAssetReservePredictionMarketBounds(amm: AMM, direction: PositionDirection): [BN, BN];
|
|
68
|
+
export declare function calculateSpreadReserves(amm: AMM, oraclePriceData: OraclePriceData, now?: BN, isPrediction?: boolean): {
|
|
68
69
|
baseAssetReserve: any;
|
|
69
70
|
quoteAssetReserve: any;
|
|
70
71
|
}[];
|
|
@@ -92,6 +93,6 @@ export declare function getSwapDirection(inputAssetType: AssetType, positionDire
|
|
|
92
93
|
* @returns cost : Precision PRICE_PRECISION
|
|
93
94
|
*/
|
|
94
95
|
export declare function calculateTerminalPrice(market: PerpMarketAccount): BN;
|
|
95
|
-
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData, now?: BN): [BN, PositionDirection];
|
|
96
|
+
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData, now?: BN, isPrediction?: boolean): [BN, PositionDirection];
|
|
96
97
|
export declare function calculateQuoteAssetAmountSwapped(quoteAssetReserves: BN, pegMultiplier: BN, swapDirection: SwapDirection): BN;
|
|
97
98
|
export declare function calculateMaxBaseAssetAmountFillable(amm: AMM, orderDirection: PositionDirection): BN;
|
package/lib/math/amm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateVolSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateReferencePriceOffset = exports.calculateInventoryScale = exports.calculateInventoryLiquidityRatio = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
3
|
+
exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.getQuoteAssetReservePredictionMarketBounds = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateVolSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateReferencePriceOffset = exports.calculateInventoryScale = exports.calculateInventoryLiquidityRatio = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
4
4
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
@@ -103,9 +103,9 @@ function calculateUpdatedAMM(amm, oraclePriceData) {
|
|
|
103
103
|
return newAmm;
|
|
104
104
|
}
|
|
105
105
|
exports.calculateUpdatedAMM = calculateUpdatedAMM;
|
|
106
|
-
function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
|
|
106
|
+
function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData, isPrediction = false) {
|
|
107
107
|
const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
108
|
-
const [shortReserves, longReserves] = calculateSpreadReserves(newAmm, oraclePriceData);
|
|
108
|
+
const [shortReserves, longReserves] = calculateSpreadReserves(newAmm, oraclePriceData, undefined, isPrediction);
|
|
109
109
|
const dirReserves = (0, types_1.isVariant)(direction, 'long')
|
|
110
110
|
? longReserves
|
|
111
111
|
: shortReserves;
|
|
@@ -118,7 +118,7 @@ function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
|
|
|
118
118
|
return result;
|
|
119
119
|
}
|
|
120
120
|
exports.calculateUpdatedAMMSpreadReserves = calculateUpdatedAMMSpreadReserves;
|
|
121
|
-
function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true) {
|
|
121
|
+
function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true, isPrediction = false) {
|
|
122
122
|
let newAmm;
|
|
123
123
|
if (withUpdate) {
|
|
124
124
|
newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
@@ -126,7 +126,7 @@ function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true) {
|
|
|
126
126
|
else {
|
|
127
127
|
newAmm = amm;
|
|
128
128
|
}
|
|
129
|
-
const [bidReserves, askReserves] = calculateSpreadReserves(newAmm, oraclePriceData);
|
|
129
|
+
const [bidReserves, askReserves] = calculateSpreadReserves(newAmm, oraclePriceData, undefined, isPrediction);
|
|
130
130
|
const askPrice = calculatePrice(askReserves.baseAssetReserve, askReserves.quoteAssetReserve, newAmm.pegMultiplier);
|
|
131
131
|
const bidPrice = calculatePrice(bidReserves.baseAssetReserve, bidReserves.quoteAssetReserve, newAmm.pegMultiplier);
|
|
132
132
|
return [bidPrice, askPrice];
|
|
@@ -442,7 +442,30 @@ function calculateSpread(amm, oraclePriceData, now, reservePrice) {
|
|
|
442
442
|
return [longSpread, shortSpread];
|
|
443
443
|
}
|
|
444
444
|
exports.calculateSpread = calculateSpread;
|
|
445
|
-
function
|
|
445
|
+
function getQuoteAssetReservePredictionMarketBounds(amm, direction) {
|
|
446
|
+
let quoteAssetReserveLowerBound = numericConstants_1.ZERO;
|
|
447
|
+
const pegSqrt = (0, __1.squareRootBN)(amm.pegMultiplier.mul(numericConstants_1.PEG_PRECISION).addn(1)).addn(1);
|
|
448
|
+
let quoteAssetReserveUpperBound = amm.sqrtK
|
|
449
|
+
.mul(pegSqrt)
|
|
450
|
+
.div(amm.pegMultiplier);
|
|
451
|
+
if (direction === types_1.PositionDirection.LONG) {
|
|
452
|
+
quoteAssetReserveLowerBound = this.amm.sqrtK
|
|
453
|
+
.muln(22361)
|
|
454
|
+
.mul(pegSqrt)
|
|
455
|
+
.divn(100000)
|
|
456
|
+
.div(amm.pegMultiplier);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
quoteAssetReserveUpperBound = amm.sqrtK
|
|
460
|
+
.muln(97467)
|
|
461
|
+
.mul(pegSqrt)
|
|
462
|
+
.divn(100000)
|
|
463
|
+
.div(amm.pegMultiplier);
|
|
464
|
+
}
|
|
465
|
+
return [quoteAssetReserveLowerBound, quoteAssetReserveUpperBound];
|
|
466
|
+
}
|
|
467
|
+
exports.getQuoteAssetReservePredictionMarketBounds = getQuoteAssetReservePredictionMarketBounds;
|
|
468
|
+
function calculateSpreadReserves(amm, oraclePriceData, now, isPrediction = false) {
|
|
446
469
|
function calculateSpreadReserve(spread, direction, amm) {
|
|
447
470
|
if (spread === 0) {
|
|
448
471
|
return {
|
|
@@ -463,6 +486,10 @@ function calculateSpreadReserves(amm, oraclePriceData, now) {
|
|
|
463
486
|
else {
|
|
464
487
|
quoteAssetReserve = amm.quoteAssetReserve.sub(quoteAssetReserveDelta.abs());
|
|
465
488
|
}
|
|
489
|
+
if (isPrediction) {
|
|
490
|
+
const [qarLower, qarUpper] = getQuoteAssetReservePredictionMarketBounds(amm, direction);
|
|
491
|
+
quoteAssetReserve = (0, __1.clampBN)(quoteAssetReserve, qarLower, qarUpper);
|
|
492
|
+
}
|
|
466
493
|
const baseAssetReserve = amm.sqrtK.mul(amm.sqrtK).div(quoteAssetReserve);
|
|
467
494
|
return {
|
|
468
495
|
baseAssetReserve,
|
|
@@ -542,7 +569,7 @@ function calculateTerminalPrice(market) {
|
|
|
542
569
|
return terminalPrice;
|
|
543
570
|
}
|
|
544
571
|
exports.calculateTerminalPrice = calculateTerminalPrice;
|
|
545
|
-
function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData, now) {
|
|
572
|
+
function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData, now, isPrediction = false) {
|
|
546
573
|
const invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
547
574
|
const newBaseAssetReserveSquared = invariant
|
|
548
575
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
@@ -550,7 +577,7 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oracleP
|
|
|
550
577
|
.div(limit_price)
|
|
551
578
|
.div(numericConstants_1.PEG_PRECISION);
|
|
552
579
|
const newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
|
|
553
|
-
const [shortSpreadReserves, longSpreadReserves] = calculateSpreadReserves(amm, oraclePriceData, now);
|
|
580
|
+
const [shortSpreadReserves, longSpreadReserves] = calculateSpreadReserves(amm, oraclePriceData, now, isPrediction);
|
|
554
581
|
const baseAssetReserveBefore = (0, types_1.isVariant)(direction, 'long')
|
|
555
582
|
? longSpreadReserves.baseAssetReserve
|
|
556
583
|
: shortSpreadReserves.baseAssetReserve;
|
package/lib/math/margin.d.ts
CHANGED
|
@@ -7,5 +7,18 @@ imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
|
|
|
7
7
|
export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
8
8
|
imfFactor: BN, assetWeight: BN): BN;
|
|
9
9
|
export declare function calculateOraclePriceForPerpMargin(perpPosition: PerpPosition, market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
10
|
+
/**
|
|
11
|
+
* This is _not_ the same as liability value as for prediction markets, the liability for the short in prediction market is (1 - oracle price) * base
|
|
12
|
+
* See {@link calculatePerpLiabilityValue} to get the liabiltiy value
|
|
13
|
+
* @param market
|
|
14
|
+
* @param perpPosition
|
|
15
|
+
* @param oraclePriceData
|
|
16
|
+
* @param includeOpenOrders
|
|
17
|
+
*/
|
|
10
18
|
export declare function calculateBaseAssetValueWithOracle(market: PerpMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
|
|
11
|
-
export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition): BN;
|
|
19
|
+
export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN): BN;
|
|
20
|
+
export declare function calculateWorstCasePerpLiabilityValue(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN): {
|
|
21
|
+
worstCaseBaseAssetAmount: BN;
|
|
22
|
+
worstCaseLiabilityValue: BN;
|
|
23
|
+
};
|
|
24
|
+
export declare function calculatePerpLiabilityValue(baseAssetAmount: BN, oraclePrice: BN, isPredictionMarket: boolean): BN;
|
package/lib/math/margin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
3
|
+
exports.calculatePerpLiabilityValue = exports.calculateWorstCasePerpLiabilityValue = exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
@@ -56,25 +56,63 @@ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData
|
|
|
56
56
|
return marginPrice;
|
|
57
57
|
}
|
|
58
58
|
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
59
|
+
/**
|
|
60
|
+
* This is _not_ the same as liability value as for prediction markets, the liability for the short in prediction market is (1 - oracle price) * base
|
|
61
|
+
* See {@link calculatePerpLiabilityValue} to get the liabiltiy value
|
|
62
|
+
* @param market
|
|
63
|
+
* @param perpPosition
|
|
64
|
+
* @param oraclePriceData
|
|
65
|
+
* @param includeOpenOrders
|
|
66
|
+
*/
|
|
59
67
|
function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData, includeOpenOrders = false) {
|
|
60
68
|
let price = oraclePriceData.price;
|
|
61
69
|
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
62
70
|
price = market.expiryPrice;
|
|
63
71
|
}
|
|
64
72
|
const baseAssetAmount = includeOpenOrders
|
|
65
|
-
? calculateWorstCaseBaseAssetAmount(perpPosition)
|
|
73
|
+
? calculateWorstCaseBaseAssetAmount(perpPosition, market, oraclePriceData.price)
|
|
66
74
|
: perpPosition.baseAssetAmount;
|
|
67
75
|
return baseAssetAmount.abs().mul(price).div(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
68
76
|
}
|
|
69
77
|
exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
|
|
70
|
-
function calculateWorstCaseBaseAssetAmount(perpPosition) {
|
|
78
|
+
function calculateWorstCaseBaseAssetAmount(perpPosition, perpMarket, oraclePrice) {
|
|
79
|
+
return calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice).worstCaseBaseAssetAmount;
|
|
80
|
+
}
|
|
81
|
+
exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
|
|
82
|
+
function calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice) {
|
|
71
83
|
const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
|
|
72
84
|
const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
const isPredictionMarket = (0, types_1.isVariant)(perpMarket.contractType, 'prediction');
|
|
86
|
+
const allBidsLiabilityValue = calculatePerpLiabilityValue(allBids, oraclePrice, isPredictionMarket);
|
|
87
|
+
const allAsksLiabilityValue = calculatePerpLiabilityValue(allAsks, oraclePrice, isPredictionMarket);
|
|
88
|
+
if (allAsksLiabilityValue.gte(allBidsLiabilityValue)) {
|
|
89
|
+
return {
|
|
90
|
+
worstCaseBaseAssetAmount: allAsks,
|
|
91
|
+
worstCaseLiabilityValue: allAsksLiabilityValue,
|
|
92
|
+
};
|
|
75
93
|
}
|
|
76
94
|
else {
|
|
77
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
worstCaseBaseAssetAmount: allBids,
|
|
97
|
+
worstCaseLiabilityValue: allBidsLiabilityValue,
|
|
98
|
+
};
|
|
78
99
|
}
|
|
79
100
|
}
|
|
80
|
-
exports.
|
|
101
|
+
exports.calculateWorstCasePerpLiabilityValue = calculateWorstCasePerpLiabilityValue;
|
|
102
|
+
function calculatePerpLiabilityValue(baseAssetAmount, oraclePrice, isPredictionMarket) {
|
|
103
|
+
if (isPredictionMarket) {
|
|
104
|
+
if (baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
105
|
+
return baseAssetAmount.mul(oraclePrice).div(numericConstants_1.BASE_PRECISION);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
return baseAssetAmount
|
|
109
|
+
.abs()
|
|
110
|
+
.mul(numericConstants_1.MAX_PREDICTION_PRICE.sub(oraclePrice))
|
|
111
|
+
.div(numericConstants_1.BASE_PRECISION);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return baseAssetAmount.abs().mul(oraclePrice).div(numericConstants_1.BASE_PRECISION);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.calculatePerpLiabilityValue = calculatePerpLiabilityValue;
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
|
@@ -63,6 +63,7 @@ class ContractType {
|
|
|
63
63
|
exports.ContractType = ContractType;
|
|
64
64
|
ContractType.PERPETUAL = { perpetual: {} };
|
|
65
65
|
ContractType.FUTURE = { future: {} };
|
|
66
|
+
ContractType.PREDICTION = { prediction: {} };
|
|
66
67
|
class ContractTier {
|
|
67
68
|
}
|
|
68
69
|
exports.ContractTier = ContractTier;
|
package/lib/user.d.ts
CHANGED
|
@@ -164,7 +164,7 @@ export declare class User {
|
|
|
164
164
|
* @returns : number (value from [0, 100])
|
|
165
165
|
*/
|
|
166
166
|
getHealth(): number;
|
|
167
|
-
|
|
167
|
+
calculateWeightedPerpPositionLiability(perpPosition: PerpPosition, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
|
|
168
168
|
/**
|
|
169
169
|
* calculates position value of a single perp market in margin system
|
|
170
170
|
* @returns : Precision QUOTE_PRECISION
|
|
@@ -174,12 +174,17 @@ export declare class User {
|
|
|
174
174
|
* calculates sum of position value across all positions in margin system
|
|
175
175
|
* @returns : Precision QUOTE_PRECISION
|
|
176
176
|
*/
|
|
177
|
-
|
|
177
|
+
getTotalPerpPositionLiability(marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
|
|
178
178
|
/**
|
|
179
|
-
* calculates position value
|
|
179
|
+
* calculates position value based on oracle
|
|
180
180
|
* @returns : Precision QUOTE_PRECISION
|
|
181
181
|
*/
|
|
182
182
|
getPerpPositionValue(marketIndex: number, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
|
|
183
|
+
/**
|
|
184
|
+
* calculates position liabiltiy value in margin system
|
|
185
|
+
* @returns : Precision QUOTE_PRECISION
|
|
186
|
+
*/
|
|
187
|
+
getPerpLiabilityValue(marketIndex: number, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
|
|
183
188
|
getPositionSide(currentPosition: Pick<PerpPosition, 'baseAssetAmount'>): PositionDirection | undefined;
|
|
184
189
|
/**
|
|
185
190
|
* calculates average exit price (optionally for closing up to 100% of position)
|
|
@@ -264,7 +269,7 @@ export declare class User {
|
|
|
264
269
|
*/
|
|
265
270
|
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN;
|
|
266
271
|
calculateEntriesEffectOnFreeCollateral(market: PerpMarketAccount, oraclePrice: BN, perpPosition: PerpPosition, positionBaseSizeChange: BN, estimatedEntryPrice: BN, includeOpenOrders: boolean): BN;
|
|
267
|
-
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN | undefined;
|
|
272
|
+
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, oraclePrice: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN | undefined;
|
|
268
273
|
calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN, marginCategory?: MarginCategory): BN;
|
|
269
274
|
/**
|
|
270
275
|
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
|
|
@@ -292,9 +297,13 @@ export declare class User {
|
|
|
292
297
|
*
|
|
293
298
|
* @param targetMarketIndex
|
|
294
299
|
* @param tradeSide
|
|
295
|
-
* @
|
|
300
|
+
* @param isLp
|
|
301
|
+
* @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION
|
|
296
302
|
*/
|
|
297
|
-
getMaxTradeSizeUSDCForPerp(targetMarketIndex: number, tradeSide: PositionDirection, isLp?: boolean):
|
|
303
|
+
getMaxTradeSizeUSDCForPerp(targetMarketIndex: number, tradeSide: PositionDirection, isLp?: boolean): {
|
|
304
|
+
tradeSize: BN;
|
|
305
|
+
oppositeSideTradeSize: BN;
|
|
306
|
+
};
|
|
298
307
|
/**
|
|
299
308
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
300
309
|
*
|