@drift-labs/sdk 2.37.1-beta.2 → 2.37.1-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/lib/user.d.ts +6 -0
- package/lib/user.js +69 -52
- package/package.json +1 -1
- package/src/user.ts +132 -91
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.37.1-beta.
|
|
1
|
+
2.37.1-beta.3
|
package/lib/user.d.ts
CHANGED
|
@@ -153,6 +153,12 @@ export declare class User {
|
|
|
153
153
|
* @returns : number (value from [0, 100])
|
|
154
154
|
*/
|
|
155
155
|
getHealth(): number;
|
|
156
|
+
calculateWeightedPerpPositionValue(perpPosition: PerpPosition, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
|
|
157
|
+
/**
|
|
158
|
+
* calculates position value of a single perp market in margin system
|
|
159
|
+
* @returns : Precision QUOTE_PRECISION
|
|
160
|
+
*/
|
|
161
|
+
getPerpMarketLiabilityValue(marketIndex: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
|
|
156
162
|
/**
|
|
157
163
|
* calculates sum of position value across all positions in margin system
|
|
158
164
|
* @returns : Precision QUOTE_PRECISION
|
package/lib/user.js
CHANGED
|
@@ -660,64 +660,81 @@ class User {
|
|
|
660
660
|
}
|
|
661
661
|
return health;
|
|
662
662
|
}
|
|
663
|
+
calculateWeightedPerpPositionValue(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
664
|
+
const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
|
|
665
|
+
if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
|
|
666
|
+
// is an lp, clone so we dont mutate the position
|
|
667
|
+
perpPosition = this.getPerpPositionWithLPSettle(market.marketIndex, this.getClonedPosition(perpPosition), !!marginCategory)[0];
|
|
668
|
+
}
|
|
669
|
+
let valuationPrice = this.getOracleDataForPerpMarket(market.marketIndex).price;
|
|
670
|
+
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
671
|
+
valuationPrice = market.expiryPrice;
|
|
672
|
+
}
|
|
673
|
+
const baseAssetAmount = includeOpenOrders
|
|
674
|
+
? (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition)
|
|
675
|
+
: perpPosition.baseAssetAmount;
|
|
676
|
+
let baseAssetValue = baseAssetAmount
|
|
677
|
+
.abs()
|
|
678
|
+
.mul(valuationPrice)
|
|
679
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.PRICE_PRECISION));
|
|
680
|
+
if (marginCategory) {
|
|
681
|
+
let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory));
|
|
682
|
+
if (marginCategory === 'Initial') {
|
|
683
|
+
marginRatio = _1.BN.max(marginRatio, new _1.BN(this.getUserAccount().maxMarginRatio));
|
|
684
|
+
}
|
|
685
|
+
if (liquidationBuffer !== undefined) {
|
|
686
|
+
marginRatio = marginRatio.add(liquidationBuffer);
|
|
687
|
+
}
|
|
688
|
+
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
689
|
+
marginRatio = numericConstants_1.ZERO;
|
|
690
|
+
}
|
|
691
|
+
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
|
|
692
|
+
const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(quoteSpotMarket.oracle).data;
|
|
693
|
+
let quotePrice;
|
|
694
|
+
if (strict) {
|
|
695
|
+
quotePrice = _1.BN.max(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min);
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
quotePrice = quoteOraclePriceData.price;
|
|
699
|
+
}
|
|
700
|
+
baseAssetValue = baseAssetValue
|
|
701
|
+
.mul(quotePrice)
|
|
702
|
+
.div(numericConstants_1.PRICE_PRECISION)
|
|
703
|
+
.mul(marginRatio)
|
|
704
|
+
.div(numericConstants_1.MARGIN_PRECISION);
|
|
705
|
+
if (includeOpenOrders) {
|
|
706
|
+
baseAssetValue = baseAssetValue.add(new _1.BN(perpPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
|
|
707
|
+
if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
|
|
708
|
+
baseAssetValue = baseAssetValue.add(_1.BN.max(numericConstants_1.QUOTE_PRECISION, valuationPrice
|
|
709
|
+
.mul(market.amm.orderStepSize)
|
|
710
|
+
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
711
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
712
|
+
.div(numericConstants_1.PRICE_PRECISION)));
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return baseAssetValue;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* calculates position value of a single perp market in margin system
|
|
720
|
+
* @returns : Precision QUOTE_PRECISION
|
|
721
|
+
*/
|
|
722
|
+
getPerpMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
723
|
+
const perpPosition = this.getPerpPosition(marketIndex);
|
|
724
|
+
if (!perpPosition) {
|
|
725
|
+
return numericConstants_1.ZERO;
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
return this.calculateWeightedPerpPositionValue(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
663
731
|
/**
|
|
664
732
|
* calculates sum of position value across all positions in margin system
|
|
665
733
|
* @returns : Precision QUOTE_PRECISION
|
|
666
734
|
*/
|
|
667
735
|
getTotalPerpPositionValue(marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
668
736
|
return this.getActivePerpPositions().reduce((totalPerpValue, perpPosition) => {
|
|
669
|
-
const
|
|
670
|
-
if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
|
|
671
|
-
// is an lp, clone so we dont mutate the position
|
|
672
|
-
perpPosition = this.getPerpPositionWithLPSettle(market.marketIndex, this.getClonedPosition(perpPosition), !!marginCategory)[0];
|
|
673
|
-
}
|
|
674
|
-
let valuationPrice = this.getOracleDataForPerpMarket(market.marketIndex).price;
|
|
675
|
-
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
676
|
-
valuationPrice = market.expiryPrice;
|
|
677
|
-
}
|
|
678
|
-
const baseAssetAmount = includeOpenOrders
|
|
679
|
-
? (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition)
|
|
680
|
-
: perpPosition.baseAssetAmount;
|
|
681
|
-
let baseAssetValue = baseAssetAmount
|
|
682
|
-
.abs()
|
|
683
|
-
.mul(valuationPrice)
|
|
684
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.PRICE_PRECISION));
|
|
685
|
-
if (marginCategory) {
|
|
686
|
-
let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory));
|
|
687
|
-
if (marginCategory === 'Initial') {
|
|
688
|
-
marginRatio = _1.BN.max(marginRatio, new _1.BN(this.getUserAccount().maxMarginRatio));
|
|
689
|
-
}
|
|
690
|
-
if (liquidationBuffer !== undefined) {
|
|
691
|
-
marginRatio = marginRatio.add(liquidationBuffer);
|
|
692
|
-
}
|
|
693
|
-
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
694
|
-
marginRatio = numericConstants_1.ZERO;
|
|
695
|
-
}
|
|
696
|
-
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
|
|
697
|
-
const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(quoteSpotMarket.oracle).data;
|
|
698
|
-
let quotePrice;
|
|
699
|
-
if (strict) {
|
|
700
|
-
quotePrice = _1.BN.max(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min);
|
|
701
|
-
}
|
|
702
|
-
else {
|
|
703
|
-
quotePrice = quoteOraclePriceData.price;
|
|
704
|
-
}
|
|
705
|
-
baseAssetValue = baseAssetValue
|
|
706
|
-
.mul(quotePrice)
|
|
707
|
-
.div(numericConstants_1.PRICE_PRECISION)
|
|
708
|
-
.mul(marginRatio)
|
|
709
|
-
.div(numericConstants_1.MARGIN_PRECISION);
|
|
710
|
-
if (includeOpenOrders) {
|
|
711
|
-
baseAssetValue = baseAssetValue.add(new _1.BN(perpPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
|
|
712
|
-
if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
|
|
713
|
-
baseAssetValue = baseAssetValue.add(_1.BN.max(numericConstants_1.QUOTE_PRECISION, valuationPrice
|
|
714
|
-
.mul(market.amm.orderStepSize)
|
|
715
|
-
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
716
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
717
|
-
.div(numericConstants_1.PRICE_PRECISION)));
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
}
|
|
737
|
+
const baseAssetValue = this.calculateWeightedPerpPositionValue(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict);
|
|
721
738
|
return totalPerpValue.add(baseAssetValue);
|
|
722
739
|
}, numericConstants_1.ZERO);
|
|
723
740
|
}
|
package/package.json
CHANGED
package/src/user.ts
CHANGED
|
@@ -1196,116 +1196,157 @@ export class User {
|
|
|
1196
1196
|
return health;
|
|
1197
1197
|
}
|
|
1198
1198
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
* @returns : Precision QUOTE_PRECISION
|
|
1202
|
-
*/
|
|
1203
|
-
getTotalPerpPositionValue(
|
|
1199
|
+
calculateWeightedPerpPositionValue(
|
|
1200
|
+
perpPosition: PerpPosition,
|
|
1204
1201
|
marginCategory?: MarginCategory,
|
|
1205
1202
|
liquidationBuffer?: BN,
|
|
1206
1203
|
includeOpenOrders?: boolean,
|
|
1207
1204
|
strict = false
|
|
1208
1205
|
): BN {
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
perpPosition.marketIndex
|
|
1213
|
-
);
|
|
1206
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
1207
|
+
perpPosition.marketIndex
|
|
1208
|
+
);
|
|
1214
1209
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1210
|
+
if (perpPosition.lpShares.gt(ZERO)) {
|
|
1211
|
+
// is an lp, clone so we dont mutate the position
|
|
1212
|
+
perpPosition = this.getPerpPositionWithLPSettle(
|
|
1213
|
+
market.marketIndex,
|
|
1214
|
+
this.getClonedPosition(perpPosition),
|
|
1215
|
+
!!marginCategory
|
|
1216
|
+
)[0];
|
|
1217
|
+
}
|
|
1223
1218
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1219
|
+
let valuationPrice = this.getOracleDataForPerpMarket(
|
|
1220
|
+
market.marketIndex
|
|
1221
|
+
).price;
|
|
1227
1222
|
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1223
|
+
if (isVariant(market.status, 'settlement')) {
|
|
1224
|
+
valuationPrice = market.expiryPrice;
|
|
1225
|
+
}
|
|
1231
1226
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1227
|
+
const baseAssetAmount = includeOpenOrders
|
|
1228
|
+
? calculateWorstCaseBaseAssetAmount(perpPosition)
|
|
1229
|
+
: perpPosition.baseAssetAmount;
|
|
1235
1230
|
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
if (marginCategory) {
|
|
1242
|
-
let marginRatio = new BN(
|
|
1243
|
-
calculateMarketMarginRatio(
|
|
1244
|
-
market,
|
|
1245
|
-
baseAssetAmount.abs(),
|
|
1246
|
-
marginCategory
|
|
1247
|
-
)
|
|
1248
|
-
);
|
|
1231
|
+
let baseAssetValue = baseAssetAmount
|
|
1232
|
+
.abs()
|
|
1233
|
+
.mul(valuationPrice)
|
|
1234
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO.mul(PRICE_PRECISION));
|
|
1249
1235
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1236
|
+
if (marginCategory) {
|
|
1237
|
+
let marginRatio = new BN(
|
|
1238
|
+
calculateMarketMarginRatio(
|
|
1239
|
+
market,
|
|
1240
|
+
baseAssetAmount.abs(),
|
|
1241
|
+
marginCategory
|
|
1242
|
+
)
|
|
1243
|
+
);
|
|
1256
1244
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1245
|
+
if (marginCategory === 'Initial') {
|
|
1246
|
+
marginRatio = BN.max(
|
|
1247
|
+
marginRatio,
|
|
1248
|
+
new BN(this.getUserAccount().maxMarginRatio)
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1260
1251
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1252
|
+
if (liquidationBuffer !== undefined) {
|
|
1253
|
+
marginRatio = marginRatio.add(liquidationBuffer);
|
|
1254
|
+
}
|
|
1264
1255
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1256
|
+
if (isVariant(market.status, 'settlement')) {
|
|
1257
|
+
marginRatio = ZERO;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(
|
|
1261
|
+
market.quoteSpotMarketIndex
|
|
1262
|
+
);
|
|
1263
|
+
const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(
|
|
1264
|
+
quoteSpotMarket.oracle
|
|
1265
|
+
).data;
|
|
1266
|
+
|
|
1267
|
+
let quotePrice;
|
|
1268
|
+
if (strict) {
|
|
1269
|
+
quotePrice = BN.max(
|
|
1270
|
+
quoteOraclePriceData.price,
|
|
1271
|
+
quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min
|
|
1272
|
+
);
|
|
1273
|
+
} else {
|
|
1274
|
+
quotePrice = quoteOraclePriceData.price;
|
|
1275
|
+
}
|
|
1282
1276
|
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1277
|
+
baseAssetValue = baseAssetValue
|
|
1278
|
+
.mul(quotePrice)
|
|
1279
|
+
.div(PRICE_PRECISION)
|
|
1280
|
+
.mul(marginRatio)
|
|
1281
|
+
.div(MARGIN_PRECISION);
|
|
1288
1282
|
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1283
|
+
if (includeOpenOrders) {
|
|
1284
|
+
baseAssetValue = baseAssetValue.add(
|
|
1285
|
+
new BN(perpPosition.openOrders).mul(OPEN_ORDER_MARGIN_REQUIREMENT)
|
|
1286
|
+
);
|
|
1293
1287
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1288
|
+
if (perpPosition.lpShares.gt(ZERO)) {
|
|
1289
|
+
baseAssetValue = baseAssetValue.add(
|
|
1290
|
+
BN.max(
|
|
1291
|
+
QUOTE_PRECISION,
|
|
1292
|
+
valuationPrice
|
|
1293
|
+
.mul(market.amm.orderStepSize)
|
|
1294
|
+
.mul(QUOTE_PRECISION)
|
|
1295
|
+
.div(AMM_RESERVE_PRECISION)
|
|
1296
|
+
.div(PRICE_PRECISION)
|
|
1297
|
+
)
|
|
1298
|
+
);
|
|
1307
1299
|
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
return baseAssetValue;
|
|
1304
|
+
}
|
|
1308
1305
|
|
|
1306
|
+
/**
|
|
1307
|
+
* calculates position value of a single perp market in margin system
|
|
1308
|
+
* @returns : Precision QUOTE_PRECISION
|
|
1309
|
+
*/
|
|
1310
|
+
public getPerpMarketLiabilityValue(
|
|
1311
|
+
marketIndex: number,
|
|
1312
|
+
marginCategory?: MarginCategory,
|
|
1313
|
+
liquidationBuffer?: BN,
|
|
1314
|
+
includeOpenOrders?: boolean,
|
|
1315
|
+
strict = false
|
|
1316
|
+
): BN {
|
|
1317
|
+
const perpPosition = this.getPerpPosition(marketIndex);
|
|
1318
|
+
if (!perpPosition) {
|
|
1319
|
+
return ZERO;
|
|
1320
|
+
} else {
|
|
1321
|
+
return this.calculateWeightedPerpPositionValue(
|
|
1322
|
+
perpPosition,
|
|
1323
|
+
marginCategory,
|
|
1324
|
+
liquidationBuffer,
|
|
1325
|
+
includeOpenOrders,
|
|
1326
|
+
strict
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* calculates sum of position value across all positions in margin system
|
|
1333
|
+
* @returns : Precision QUOTE_PRECISION
|
|
1334
|
+
*/
|
|
1335
|
+
getTotalPerpPositionValue(
|
|
1336
|
+
marginCategory?: MarginCategory,
|
|
1337
|
+
liquidationBuffer?: BN,
|
|
1338
|
+
includeOpenOrders?: boolean,
|
|
1339
|
+
strict = false
|
|
1340
|
+
): BN {
|
|
1341
|
+
return this.getActivePerpPositions().reduce(
|
|
1342
|
+
(totalPerpValue, perpPosition) => {
|
|
1343
|
+
const baseAssetValue = this.calculateWeightedPerpPositionValue(
|
|
1344
|
+
perpPosition,
|
|
1345
|
+
marginCategory,
|
|
1346
|
+
liquidationBuffer,
|
|
1347
|
+
includeOpenOrders,
|
|
1348
|
+
strict
|
|
1349
|
+
);
|
|
1309
1350
|
return totalPerpValue.add(baseAssetValue);
|
|
1310
1351
|
},
|
|
1311
1352
|
ZERO
|