@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 CHANGED
@@ -1 +1 @@
1
- 2.37.1-beta.2
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 market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.37.1-beta.2",
3
+ "version": "2.37.1-beta.3",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
package/src/user.ts CHANGED
@@ -1196,116 +1196,157 @@ export class User {
1196
1196
  return health;
1197
1197
  }
1198
1198
 
1199
- /**
1200
- * calculates sum of position value across all positions in margin system
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
- return this.getActivePerpPositions().reduce(
1210
- (totalPerpValue, perpPosition) => {
1211
- const market = this.driftClient.getPerpMarketAccount(
1212
- perpPosition.marketIndex
1213
- );
1206
+ const market = this.driftClient.getPerpMarketAccount(
1207
+ perpPosition.marketIndex
1208
+ );
1214
1209
 
1215
- if (perpPosition.lpShares.gt(ZERO)) {
1216
- // is an lp, clone so we dont mutate the position
1217
- perpPosition = this.getPerpPositionWithLPSettle(
1218
- market.marketIndex,
1219
- this.getClonedPosition(perpPosition),
1220
- !!marginCategory
1221
- )[0];
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
- let valuationPrice = this.getOracleDataForPerpMarket(
1225
- market.marketIndex
1226
- ).price;
1219
+ let valuationPrice = this.getOracleDataForPerpMarket(
1220
+ market.marketIndex
1221
+ ).price;
1227
1222
 
1228
- if (isVariant(market.status, 'settlement')) {
1229
- valuationPrice = market.expiryPrice;
1230
- }
1223
+ if (isVariant(market.status, 'settlement')) {
1224
+ valuationPrice = market.expiryPrice;
1225
+ }
1231
1226
 
1232
- const baseAssetAmount = includeOpenOrders
1233
- ? calculateWorstCaseBaseAssetAmount(perpPosition)
1234
- : perpPosition.baseAssetAmount;
1227
+ const baseAssetAmount = includeOpenOrders
1228
+ ? calculateWorstCaseBaseAssetAmount(perpPosition)
1229
+ : perpPosition.baseAssetAmount;
1235
1230
 
1236
- let baseAssetValue = baseAssetAmount
1237
- .abs()
1238
- .mul(valuationPrice)
1239
- .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(PRICE_PRECISION));
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
- if (marginCategory === 'Initial') {
1251
- marginRatio = BN.max(
1252
- marginRatio,
1253
- new BN(this.getUserAccount().maxMarginRatio)
1254
- );
1255
- }
1236
+ if (marginCategory) {
1237
+ let marginRatio = new BN(
1238
+ calculateMarketMarginRatio(
1239
+ market,
1240
+ baseAssetAmount.abs(),
1241
+ marginCategory
1242
+ )
1243
+ );
1256
1244
 
1257
- if (liquidationBuffer !== undefined) {
1258
- marginRatio = marginRatio.add(liquidationBuffer);
1259
- }
1245
+ if (marginCategory === 'Initial') {
1246
+ marginRatio = BN.max(
1247
+ marginRatio,
1248
+ new BN(this.getUserAccount().maxMarginRatio)
1249
+ );
1250
+ }
1260
1251
 
1261
- if (isVariant(market.status, 'settlement')) {
1262
- marginRatio = ZERO;
1263
- }
1252
+ if (liquidationBuffer !== undefined) {
1253
+ marginRatio = marginRatio.add(liquidationBuffer);
1254
+ }
1264
1255
 
1265
- const quoteSpotMarket = this.driftClient.getSpotMarketAccount(
1266
- market.quoteSpotMarketIndex
1267
- );
1268
- const quoteOraclePriceData =
1269
- this.driftClient.getOraclePriceDataAndSlot(
1270
- quoteSpotMarket.oracle
1271
- ).data;
1272
-
1273
- let quotePrice;
1274
- if (strict) {
1275
- quotePrice = BN.max(
1276
- quoteOraclePriceData.price,
1277
- quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min
1278
- );
1279
- } else {
1280
- quotePrice = quoteOraclePriceData.price;
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
- baseAssetValue = baseAssetValue
1284
- .mul(quotePrice)
1285
- .div(PRICE_PRECISION)
1286
- .mul(marginRatio)
1287
- .div(MARGIN_PRECISION);
1277
+ baseAssetValue = baseAssetValue
1278
+ .mul(quotePrice)
1279
+ .div(PRICE_PRECISION)
1280
+ .mul(marginRatio)
1281
+ .div(MARGIN_PRECISION);
1288
1282
 
1289
- if (includeOpenOrders) {
1290
- baseAssetValue = baseAssetValue.add(
1291
- new BN(perpPosition.openOrders).mul(OPEN_ORDER_MARGIN_REQUIREMENT)
1292
- );
1283
+ if (includeOpenOrders) {
1284
+ baseAssetValue = baseAssetValue.add(
1285
+ new BN(perpPosition.openOrders).mul(OPEN_ORDER_MARGIN_REQUIREMENT)
1286
+ );
1293
1287
 
1294
- if (perpPosition.lpShares.gt(ZERO)) {
1295
- baseAssetValue = baseAssetValue.add(
1296
- BN.max(
1297
- QUOTE_PRECISION,
1298
- valuationPrice
1299
- .mul(market.amm.orderStepSize)
1300
- .mul(QUOTE_PRECISION)
1301
- .div(AMM_RESERVE_PRECISION)
1302
- .div(PRICE_PRECISION)
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