@drift-labs/sdk 2.37.1-beta.2 → 2.37.1-beta.4
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/events/eventSubscriber.js +3 -3
- package/lib/events/fetchLogs.js +3 -3
- package/lib/events/types.d.ts +0 -1
- package/lib/math/auction.js +1 -1
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -0
- package/lib/user.d.ts +6 -0
- package/lib/user.js +69 -52
- package/package.json +1 -1
- package/src/events/eventSubscriber.ts +3 -3
- package/src/events/fetchLogs.ts +3 -3
- package/src/events/types.ts +1 -1
- package/src/math/auction.ts +1 -1
- package/src/types.ts +1 -0
- package/src/user.ts +132 -91
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.37.1-beta.
|
|
1
|
+
2.37.1-beta.4
|
|
@@ -101,7 +101,7 @@ class EventSubscriber {
|
|
|
101
101
|
const records = [];
|
|
102
102
|
// @ts-ignore
|
|
103
103
|
const events = (0, parse_1.parseLogs)(this.program, slot, logs);
|
|
104
|
-
let
|
|
104
|
+
let _runningEventIndex = 0;
|
|
105
105
|
for (const event of events) {
|
|
106
106
|
// @ts-ignore
|
|
107
107
|
const expectRecordType = this.eventListMap.has(event.name);
|
|
@@ -109,10 +109,10 @@ class EventSubscriber {
|
|
|
109
109
|
event.data.txSig = txSig;
|
|
110
110
|
event.data.slot = slot;
|
|
111
111
|
event.data.eventType = event.name;
|
|
112
|
-
event.data.txSigIndex =
|
|
112
|
+
//event.data.txSigIndex = _runningEventIndex;
|
|
113
113
|
records.push(event.data);
|
|
114
114
|
}
|
|
115
|
-
|
|
115
|
+
_runningEventIndex++;
|
|
116
116
|
}
|
|
117
117
|
return records;
|
|
118
118
|
}
|
package/lib/events/fetchLogs.js
CHANGED
|
@@ -83,14 +83,14 @@ class LogParser {
|
|
|
83
83
|
const records = [];
|
|
84
84
|
// @ts-ignore
|
|
85
85
|
const eventGenerator = this.program._events._eventParser.parseLogs(event.logs, false);
|
|
86
|
-
let
|
|
86
|
+
let _runningEventIndex = 0;
|
|
87
87
|
for (const eventLog of eventGenerator) {
|
|
88
88
|
eventLog.data.txSig = event.txSig;
|
|
89
89
|
eventLog.data.slot = event.slot;
|
|
90
90
|
eventLog.data.eventType = eventLog.name;
|
|
91
|
-
eventLog.data.txSigIndex =
|
|
91
|
+
//eventLog.data.txSigIndex = _runningEventIndex;
|
|
92
92
|
records.push(eventLog.data);
|
|
93
|
-
|
|
93
|
+
_runningEventIndex++;
|
|
94
94
|
}
|
|
95
95
|
return records;
|
|
96
96
|
}
|
package/lib/events/types.d.ts
CHANGED
|
@@ -17,7 +17,6 @@ export type EventSubscriptionOrderDirection = 'asc' | 'desc';
|
|
|
17
17
|
export type Event<T> = T & {
|
|
18
18
|
txSig: TransactionSignature;
|
|
19
19
|
slot: number;
|
|
20
|
-
txSigIndex: number;
|
|
21
20
|
};
|
|
22
21
|
export type WrappedEvent<Type extends EventType> = EventMap[Type] & {
|
|
23
22
|
eventType: Type;
|
package/lib/math/auction.js
CHANGED
|
@@ -64,7 +64,7 @@ function getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice) {
|
|
|
64
64
|
const deltaDenominator = new _1.BN(order.auctionDuration);
|
|
65
65
|
const deltaNumerator = _1.BN.min(slotsElapsed, deltaDenominator);
|
|
66
66
|
if (deltaDenominator.eq(_1.ZERO)) {
|
|
67
|
-
return
|
|
67
|
+
return oraclePrice.add(order.auctionEndPrice);
|
|
68
68
|
}
|
|
69
69
|
let priceOffsetDelta;
|
|
70
70
|
if ((0, types_1.isVariant)(order.direction, 'long')) {
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
|
@@ -33,6 +33,7 @@ exports.UserStatus = UserStatus;
|
|
|
33
33
|
UserStatus.ACTIVE = { active: {} };
|
|
34
34
|
UserStatus.BEING_LIQUIDATED = { beingLiquidated: {} };
|
|
35
35
|
UserStatus.BANKRUPT = { bankrupt: {} };
|
|
36
|
+
UserStatus.REDUCE_ONLY = { reduceOnly: {} };
|
|
36
37
|
class ContractType {
|
|
37
38
|
}
|
|
38
39
|
exports.ContractType = ContractType;
|
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
|
@@ -168,7 +168,7 @@ export class EventSubscriber {
|
|
|
168
168
|
const records = [];
|
|
169
169
|
// @ts-ignore
|
|
170
170
|
const events = parseLogs(this.program, slot, logs);
|
|
171
|
-
let
|
|
171
|
+
let _runningEventIndex = 0;
|
|
172
172
|
for (const event of events) {
|
|
173
173
|
// @ts-ignore
|
|
174
174
|
const expectRecordType = this.eventListMap.has(event.name);
|
|
@@ -176,10 +176,10 @@ export class EventSubscriber {
|
|
|
176
176
|
event.data.txSig = txSig;
|
|
177
177
|
event.data.slot = slot;
|
|
178
178
|
event.data.eventType = event.name;
|
|
179
|
-
event.data.txSigIndex =
|
|
179
|
+
//event.data.txSigIndex = _runningEventIndex;
|
|
180
180
|
records.push(event.data);
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
_runningEventIndex++;
|
|
183
183
|
}
|
|
184
184
|
return records;
|
|
185
185
|
}
|
package/src/events/fetchLogs.ts
CHANGED
|
@@ -155,14 +155,14 @@ export class LogParser {
|
|
|
155
155
|
event.logs,
|
|
156
156
|
false
|
|
157
157
|
);
|
|
158
|
-
let
|
|
158
|
+
let _runningEventIndex = 0;
|
|
159
159
|
for (const eventLog of eventGenerator) {
|
|
160
160
|
eventLog.data.txSig = event.txSig;
|
|
161
161
|
eventLog.data.slot = event.slot;
|
|
162
162
|
eventLog.data.eventType = eventLog.name;
|
|
163
|
-
eventLog.data.txSigIndex =
|
|
163
|
+
//eventLog.data.txSigIndex = _runningEventIndex;
|
|
164
164
|
records.push(eventLog.data);
|
|
165
|
-
|
|
165
|
+
_runningEventIndex++;
|
|
166
166
|
}
|
|
167
167
|
return records;
|
|
168
168
|
}
|
package/src/events/types.ts
CHANGED
|
@@ -64,7 +64,7 @@ export type EventSubscriptionOrderDirection = 'asc' | 'desc';
|
|
|
64
64
|
export type Event<T> = T & {
|
|
65
65
|
txSig: TransactionSignature;
|
|
66
66
|
slot: number;
|
|
67
|
-
txSigIndex: number; // Unique index for each event inside a tx
|
|
67
|
+
//txSigIndex: number; // Unique index for each event inside a tx
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
export type WrappedEvent<Type extends EventType> = EventMap[Type] & {
|
package/src/math/auction.ts
CHANGED
|
@@ -79,7 +79,7 @@ export function getAuctionPriceForOracleOffsetAuction(
|
|
|
79
79
|
const deltaNumerator = BN.min(slotsElapsed, deltaDenominator);
|
|
80
80
|
|
|
81
81
|
if (deltaDenominator.eq(ZERO)) {
|
|
82
|
-
return
|
|
82
|
+
return oraclePrice.add(order.auctionEndPrice);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
let priceOffsetDelta;
|
package/src/types.ts
CHANGED
|
@@ -31,6 +31,7 @@ export class UserStatus {
|
|
|
31
31
|
static readonly ACTIVE = { active: {} };
|
|
32
32
|
static readonly BEING_LIQUIDATED = { beingLiquidated: {} };
|
|
33
33
|
static readonly BANKRUPT = { bankrupt: {} };
|
|
34
|
+
static readonly REDUCE_ONLY = { reduceOnly: {} };
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export class ContractType {
|
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
|