@drift-labs/sdk 0.1.11 → 0.1.15
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 +2 -2
- package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts +1 -0
- package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +1 -1
- package/lib/accounts/defaultClearingHouseAccountSubscriber.js +17 -0
- package/lib/accounts/defaultUserAccountSubscriber.d.ts +2 -0
- package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +1 -1
- package/lib/accounts/defaultUserAccountSubscriber.js +16 -0
- package/lib/accounts/types.d.ts +3 -21
- package/lib/accounts/types.d.ts.map +1 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +2 -0
- package/lib/accounts/webSocketAccountSubscriber.d.ts.map +1 -1
- package/lib/accounts/webSocketAccountSubscriber.js +13 -3
- package/lib/clearingHouse.d.ts +4 -0
- package/lib/clearingHouse.d.ts.map +1 -1
- package/lib/clearingHouse.js +8 -0
- package/lib/clearingHouseUser.d.ts +33 -5
- package/lib/clearingHouseUser.d.ts.map +1 -1
- package/lib/clearingHouseUser.js +224 -78
- package/lib/constants/markets.d.ts.map +1 -1
- package/lib/constants/markets.js +21 -0
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.d.ts.map +1 -1
- package/lib/constants/numericConstants.js +2 -1
- package/lib/examples/makeTradeExample.d.ts.map +1 -1
- package/lib/examples/makeTradeExample.js +14 -13
- package/lib/idl/clearing_house.json +94 -42
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -1
- package/lib/math/amm.d.ts +26 -1
- package/lib/math/amm.d.ts.map +1 -1
- package/lib/math/amm.js +85 -10
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.d.ts.map +1 -1
- package/lib/math/funding.js +69 -25
- package/lib/math/insuranceFund.d.ts +15 -0
- package/lib/math/insuranceFund.d.ts.map +1 -0
- package/lib/math/insuranceFund.js +36 -0
- package/lib/math/position.d.ts +1 -1
- package/lib/math/position.d.ts.map +1 -1
- package/lib/math/position.js +15 -23
- package/lib/math/trade.d.ts +1 -1
- package/lib/math/trade.d.ts.map +1 -1
- package/lib/math/trade.js +9 -4
- package/lib/types.d.ts +0 -50
- package/lib/types.d.ts.map +1 -1
- package/lib/util/computeUnits.d.ts +3 -0
- package/lib/util/computeUnits.d.ts.map +1 -0
- package/lib/util/computeUnits.js +27 -0
- package/lib/util/tps.d.ts +3 -0
- package/lib/util/tps.d.ts.map +1 -0
- package/lib/util/tps.js +27 -0
- package/lib/wallet.d.ts +10 -0
- package/lib/wallet.d.ts.map +1 -0
- package/lib/wallet.js +35 -0
- package/package.json +3 -13
- package/src/accounts/defaultClearingHouseAccountSubscriber.ts +18 -0
- package/src/accounts/defaultUserAccountSubscriber.ts +18 -0
- package/src/accounts/types.ts +3 -28
- package/src/accounts/webSocketAccountSubscriber.ts +16 -6
- package/src/clearingHouse.ts +9 -3
- package/src/clearingHouseUser.ts +325 -107
- package/src/constants/markets.ts +21 -0
- package/src/constants/numericConstants.ts +2 -0
- package/src/examples/makeTradeExample.ts +2 -1
- package/src/idl/clearing_house.json +94 -42
- package/src/index.ts +4 -1
- package/src/math/amm.ts +120 -13
- package/src/math/funding.ts +109 -51
- package/src/math/insuranceFund.ts +29 -0
- package/src/math/position.ts +16 -28
- package/src/math/trade.ts +9 -5
- package/src/types.ts +0 -54
- package/src/util/computeUnits.ts +21 -0
- package/src/util/tps.ts +27 -0
- package/src/wallet.ts +22 -0
- package/.eslintrc.json +0 -36
- package/.prettierignore +0 -1
- package/.prettierrc.js +0 -9
- package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -29
- package/lib/accounts/defaultHistoryAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
- package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -179
package/lib/clearingHouseUser.js
CHANGED
|
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.ClearingHouseUser = void 0;
|
|
16
16
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
17
|
+
const position_1 = require("./math/position");
|
|
17
18
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
18
19
|
const defaultUserAccountSubscriber_1 = require("./accounts/defaultUserAccountSubscriber");
|
|
19
20
|
const _1 = require(".");
|
|
@@ -42,6 +43,14 @@ class ClearingHouseUser {
|
|
|
42
43
|
return this.isSubscribed;
|
|
43
44
|
});
|
|
44
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Forces the accountSubscriber to fetch account updates from rpc
|
|
48
|
+
*/
|
|
49
|
+
fetchAccounts() {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
yield this.accountSubscriber.fetch();
|
|
52
|
+
});
|
|
53
|
+
}
|
|
45
54
|
unsubscribe() {
|
|
46
55
|
return __awaiter(this, void 0, void 0, function* () {
|
|
47
56
|
yield this.accountSubscriber.unsubscribe();
|
|
@@ -55,18 +64,20 @@ class ClearingHouseUser {
|
|
|
55
64
|
return this.accountSubscriber.getUserPositionsAccount();
|
|
56
65
|
}
|
|
57
66
|
/**
|
|
58
|
-
* Gets the user's current position for a given market
|
|
67
|
+
* Gets the user's current position for a given market. If the user has no position returns undefined
|
|
59
68
|
* @param marketIndex
|
|
60
69
|
* @returns userPosition
|
|
61
70
|
*/
|
|
62
71
|
getUserPosition(marketIndex) {
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
return this.getUserPositionsAccount().positions.find((position) => position.marketIndex.eq(marketIndex));
|
|
73
|
+
}
|
|
74
|
+
getEmptyPosition(marketIndex) {
|
|
75
|
+
return {
|
|
65
76
|
baseAssetAmount: numericConstants_1.ZERO,
|
|
66
77
|
lastCumulativeFundingRate: numericConstants_1.ZERO,
|
|
67
78
|
marketIndex,
|
|
68
79
|
quoteAssetAmount: numericConstants_1.ZERO,
|
|
69
|
-
}
|
|
80
|
+
};
|
|
70
81
|
}
|
|
71
82
|
getUserAccountPublicKey() {
|
|
72
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -106,8 +117,10 @@ class ClearingHouseUser {
|
|
|
106
117
|
* calculates unrealized position price pnl
|
|
107
118
|
* @returns : Precision QUOTE_PRECISION
|
|
108
119
|
*/
|
|
109
|
-
getUnrealizedPNL(withFunding) {
|
|
110
|
-
return this.getUserPositionsAccount()
|
|
120
|
+
getUnrealizedPNL(withFunding, marketIndex) {
|
|
121
|
+
return this.getUserPositionsAccount()
|
|
122
|
+
.positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
|
|
123
|
+
.reduce((pnl, marketPosition) => {
|
|
111
124
|
const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
112
125
|
return pnl.add(_1.calculatePositionPNL(market, marketPosition, withFunding));
|
|
113
126
|
}, numericConstants_1.ZERO);
|
|
@@ -116,8 +129,10 @@ class ClearingHouseUser {
|
|
|
116
129
|
* calculates unrealized funding payment pnl
|
|
117
130
|
* @returns : Precision QUOTE_PRECISION
|
|
118
131
|
*/
|
|
119
|
-
getUnrealizedFundingPNL() {
|
|
120
|
-
return this.getUserPositionsAccount()
|
|
132
|
+
getUnrealizedFundingPNL(marketIndex) {
|
|
133
|
+
return this.getUserPositionsAccount()
|
|
134
|
+
.positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
|
|
135
|
+
.reduce((pnl, marketPosition) => {
|
|
121
136
|
const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
122
137
|
return pnl.add(_1.calculatePositionFundingPNL(market, marketPosition));
|
|
123
138
|
}, numericConstants_1.ZERO);
|
|
@@ -145,7 +160,7 @@ class ClearingHouseUser {
|
|
|
145
160
|
* @returns : Precision QUOTE_PRECISION
|
|
146
161
|
*/
|
|
147
162
|
getPositionValue(marketIndex) {
|
|
148
|
-
const userPosition = this.getUserPosition(marketIndex);
|
|
163
|
+
const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
|
|
149
164
|
const market = this.clearingHouse.getMarket(userPosition.marketIndex);
|
|
150
165
|
return _1.calculateBaseAssetValue(market, userPosition);
|
|
151
166
|
}
|
|
@@ -164,11 +179,12 @@ class ClearingHouseUser {
|
|
|
164
179
|
* calculates average exit price for closing 100% of position
|
|
165
180
|
* @returns : Precision MARK_PRICE_PRECISION
|
|
166
181
|
*/
|
|
167
|
-
|
|
182
|
+
getPositionEstimatedExitPriceAndPnl(position, amountToClose) {
|
|
168
183
|
const market = this.clearingHouse.getMarket(position.marketIndex);
|
|
184
|
+
const entryPrice = position_1.calculateEntryPrice(position);
|
|
169
185
|
if (amountToClose) {
|
|
170
186
|
if (amountToClose.eq(numericConstants_1.ZERO)) {
|
|
171
|
-
return _1.calculateMarkPrice(market);
|
|
187
|
+
return [_1.calculateMarkPrice(market), numericConstants_1.ZERO];
|
|
172
188
|
}
|
|
173
189
|
position = {
|
|
174
190
|
baseAssetAmount: amountToClose,
|
|
@@ -179,12 +195,18 @@ class ClearingHouseUser {
|
|
|
179
195
|
}
|
|
180
196
|
const baseAssetValue = _1.calculateBaseAssetValue(market, position);
|
|
181
197
|
if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
182
|
-
return numericConstants_1.ZERO;
|
|
198
|
+
return [numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
183
199
|
}
|
|
184
|
-
|
|
200
|
+
const exitPrice = baseAssetValue
|
|
185
201
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
186
202
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
187
203
|
.div(position.baseAssetAmount.abs());
|
|
204
|
+
const pnlPerBase = exitPrice.sub(entryPrice);
|
|
205
|
+
const pnl = pnlPerBase
|
|
206
|
+
.mul(position.baseAssetAmount)
|
|
207
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
208
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
209
|
+
return [exitPrice, pnl];
|
|
188
210
|
}
|
|
189
211
|
/**
|
|
190
212
|
* calculates current user leverage across all positions
|
|
@@ -265,7 +287,7 @@ class ClearingHouseUser {
|
|
|
265
287
|
* @param partial
|
|
266
288
|
* @returns Precision : MARK_PRICE_PRECISION
|
|
267
289
|
*/
|
|
268
|
-
|
|
290
|
+
liquidationPriceOld(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
|
|
269
291
|
// +/-(margin_ratio-liq_ratio) * price_now = price_liq
|
|
270
292
|
// todo: margin_ratio is not symmetric on price action (both numer and denom change)
|
|
271
293
|
// margin_ratio = collateral / base_asset_value
|
|
@@ -282,10 +304,9 @@ class ClearingHouseUser {
|
|
|
282
304
|
const totalCollateralUSDC = this.getTotalCollateral();
|
|
283
305
|
// calculate the total position value ignoring any value from the target market of the trade
|
|
284
306
|
const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
|
|
285
|
-
const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
: numericConstants_1.ZERO;
|
|
307
|
+
const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
|
|
308
|
+
this.getEmptyPosition(targetMarket.marketIndex);
|
|
309
|
+
const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
|
|
289
310
|
// calculate position for current market after trade
|
|
290
311
|
const proposedMarketPosition = {
|
|
291
312
|
marketIndex: targetMarket.marketIndex,
|
|
@@ -297,23 +318,28 @@ class ClearingHouseUser {
|
|
|
297
318
|
const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
|
|
298
319
|
// total position value after trade
|
|
299
320
|
const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
|
|
321
|
+
let totalFreeCollateralUSDC = this.getTotalCollateral().sub(this.getTotalPositionValue()
|
|
322
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
323
|
+
.div(this.getMaxLeverage('Maintenance')));
|
|
324
|
+
if (partial) {
|
|
325
|
+
totalFreeCollateralUSDC = this.getTotalCollateral().sub(this.getTotalPositionValue()
|
|
326
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
327
|
+
.div(this.getMaxLeverage('Partial')));
|
|
328
|
+
}
|
|
300
329
|
// if the position value after the trade is less than total collateral, there is no liq price
|
|
301
|
-
if (targetTotalPositionValueUSDC.lte(
|
|
330
|
+
if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
|
|
331
|
+
proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
302
332
|
return new bn_js_1.default(-1);
|
|
303
333
|
}
|
|
304
|
-
// proportion of proposed market position to overall position
|
|
305
|
-
// const marketProportion = proposedMarketPositionValueUSDC
|
|
306
|
-
// .mul(TEN_THOUSAND)
|
|
307
|
-
// .div(targetTotalPositionValueUSDC);
|
|
308
334
|
// get current margin ratio based on current collateral and proposed total position value
|
|
309
335
|
let marginRatio;
|
|
310
|
-
if (
|
|
336
|
+
if (proposedMarketPositionValueUSDC.eq(numericConstants_1.ZERO)) {
|
|
311
337
|
marginRatio = numericConstants_1.BN_MAX;
|
|
312
338
|
}
|
|
313
339
|
else {
|
|
314
340
|
marginRatio = totalCollateralUSDC
|
|
315
341
|
.mul(numericConstants_1.TEN_THOUSAND)
|
|
316
|
-
.div(
|
|
342
|
+
.div(proposedMarketPositionValueUSDC);
|
|
317
343
|
}
|
|
318
344
|
let liqRatio = numericConstants_1.FULL_LIQUIDATION_RATIO;
|
|
319
345
|
if (partial) {
|
|
@@ -321,27 +347,6 @@ class ClearingHouseUser {
|
|
|
321
347
|
}
|
|
322
348
|
// sign of position in current market after the trade
|
|
323
349
|
const baseAssetSignIsNeg = proposedMarketPosition.baseAssetAmount.isNeg();
|
|
324
|
-
// console.log(
|
|
325
|
-
// convertToNumber(currentPrice),
|
|
326
|
-
// convertToNumber(liqRatio),
|
|
327
|
-
// convertToNumber(marginRatio),
|
|
328
|
-
// convertToNumber(marketProportion),
|
|
329
|
-
// );
|
|
330
|
-
// // if the user is long, then the liq price is the currentPrice multiplied by liqRatio/marginRatio (how many multiples lower does the current marginRatio have to go to reach the liqRatio), multiplied by the fraction of the proposed total position value that this market will take up
|
|
331
|
-
// if (!baseAssetSignIsNeg) {
|
|
332
|
-
// liqPrice = currentPrice
|
|
333
|
-
// .mul(liqRatio)
|
|
334
|
-
// .div(marginRatio)
|
|
335
|
-
// .mul(marketProportion)
|
|
336
|
-
// .div(TEN_THOUSAND);
|
|
337
|
-
// } else {
|
|
338
|
-
// // if the user is short, it's the reciprocal of the above
|
|
339
|
-
// liqPrice = currentPrice
|
|
340
|
-
// .mul(marginRatio)
|
|
341
|
-
// .div(liqRatio)
|
|
342
|
-
// .mul(TEN_THOUSAND)
|
|
343
|
-
// .div(marketProportion);
|
|
344
|
-
// }
|
|
345
350
|
let pctChange = marginRatio.abs().sub(liqRatio);
|
|
346
351
|
// if user is short, higher price is liq
|
|
347
352
|
if (baseAssetSignIsNeg) {
|
|
@@ -358,6 +363,93 @@ class ClearingHouseUser {
|
|
|
358
363
|
const liqPrice = currentPrice.mul(pctChange).div(numericConstants_1.TEN_THOUSAND);
|
|
359
364
|
return liqPrice;
|
|
360
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Calculate the liquidation price of a position, with optional parameter to calculate the liquidation price after a trade
|
|
368
|
+
* @param targetMarket
|
|
369
|
+
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
370
|
+
* @param partial
|
|
371
|
+
* @returns Precision : MARK_PRICE_PRECISION
|
|
372
|
+
*/
|
|
373
|
+
liquidationPrice(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
|
|
374
|
+
// solves formula for example calc below
|
|
375
|
+
/* example: assume BTC price is $40k (examine 10% up/down)
|
|
376
|
+
|
|
377
|
+
if 10k deposit and levered 10x short BTC => BTC up $400 means:
|
|
378
|
+
1. higher base_asset_value (+$4k)
|
|
379
|
+
2. lower collateral (-$4k)
|
|
380
|
+
3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
|
|
381
|
+
|
|
382
|
+
for 10x long, BTC down $400:
|
|
383
|
+
3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
|
|
384
|
+
const tc = this.getTotalCollateral();
|
|
385
|
+
const tpv = this.getTotalPositionValue();
|
|
386
|
+
const partialLev = 16;
|
|
387
|
+
const maintLev = 20;
|
|
388
|
+
const thisLev = partial ? new bn_js_1.default(partialLev) : new bn_js_1.default(maintLev);
|
|
389
|
+
// calculate the total position value ignoring any value from the target market of the trade
|
|
390
|
+
const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
|
|
391
|
+
const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
|
|
392
|
+
this.getEmptyPosition(targetMarket.marketIndex);
|
|
393
|
+
const currentMarketPositionBaseSize = currentMarketPosition.baseAssetAmount;
|
|
394
|
+
const proposedBaseAssetAmount = currentMarketPositionBaseSize.add(positionBaseSizeChange);
|
|
395
|
+
// calculate position for current market after trade
|
|
396
|
+
const proposedMarketPosition = {
|
|
397
|
+
marketIndex: targetMarket.marketIndex,
|
|
398
|
+
baseAssetAmount: proposedBaseAssetAmount,
|
|
399
|
+
lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
|
|
400
|
+
quoteAssetAmount: new bn_js_1.default(0),
|
|
401
|
+
};
|
|
402
|
+
const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
|
|
403
|
+
const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
|
|
404
|
+
// total position value after trade
|
|
405
|
+
const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
|
|
406
|
+
let totalFreeCollateralUSDC = tc.sub(totalCurrentPositionValueIgnoringTargetUSDC
|
|
407
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
408
|
+
.div(this.getMaxLeverage('Maintenance')));
|
|
409
|
+
if (partial) {
|
|
410
|
+
totalFreeCollateralUSDC = tc.sub(totalCurrentPositionValueIgnoringTargetUSDC
|
|
411
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
412
|
+
.div(this.getMaxLeverage('Partial')));
|
|
413
|
+
}
|
|
414
|
+
let priceDelt;
|
|
415
|
+
if (proposedBaseAssetAmount.lt(numericConstants_1.ZERO)) {
|
|
416
|
+
priceDelt = (tc
|
|
417
|
+
.mul(thisLev)
|
|
418
|
+
.sub(tpv))
|
|
419
|
+
.mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
|
|
420
|
+
.div(thisLev.add(new bn_js_1.default(1)));
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
priceDelt = (tc
|
|
424
|
+
.mul(thisLev)
|
|
425
|
+
.sub(tpv))
|
|
426
|
+
.mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
|
|
427
|
+
.div(thisLev.sub(new bn_js_1.default(1)));
|
|
428
|
+
}
|
|
429
|
+
let currentPrice;
|
|
430
|
+
if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
|
|
431
|
+
currentPrice = _1.calculateMarkPrice(this.clearingHouse.getMarket(targetMarket.marketIndex));
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
const direction = positionBaseSizeChange.gt(numericConstants_1.ZERO) ? _1.PositionDirection.LONG : _1.PositionDirection.SHORT;
|
|
435
|
+
currentPrice = _1.calculateTradeSlippage(direction, positionBaseSizeChange.abs(), this.clearingHouse.getMarket(targetMarket.marketIndex), 'base')[3]; // newPrice after swap
|
|
436
|
+
}
|
|
437
|
+
// if the position value after the trade is less than total collateral, there is no liq price
|
|
438
|
+
if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
|
|
439
|
+
proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
440
|
+
return new bn_js_1.default(-1);
|
|
441
|
+
}
|
|
442
|
+
if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
|
|
443
|
+
return new bn_js_1.default(-1);
|
|
444
|
+
const eatMargin2 = priceDelt
|
|
445
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
446
|
+
.div(proposedBaseAssetAmount);
|
|
447
|
+
if (eatMargin2.gt(currentPrice)) {
|
|
448
|
+
return new bn_js_1.default(-1);
|
|
449
|
+
}
|
|
450
|
+
const liqPrice = currentPrice.sub(eatMargin2);
|
|
451
|
+
return liqPrice;
|
|
452
|
+
}
|
|
361
453
|
/**
|
|
362
454
|
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
|
|
363
455
|
* @param positionMarketIndex
|
|
@@ -365,7 +457,8 @@ class ClearingHouseUser {
|
|
|
365
457
|
* @returns : Precision MARK_PRICE_PRECISION
|
|
366
458
|
*/
|
|
367
459
|
liquidationPriceAfterClose(positionMarketIndex, closeQuoteAmount) {
|
|
368
|
-
const currentPosition = this.getUserPosition(positionMarketIndex)
|
|
460
|
+
const currentPosition = this.getUserPosition(positionMarketIndex) ||
|
|
461
|
+
this.getEmptyPosition(positionMarketIndex);
|
|
369
462
|
const closeBaseAmount = currentPosition.baseAssetAmount
|
|
370
463
|
.mul(closeQuoteAmount)
|
|
371
464
|
.div(currentPosition.quoteAssetAmount)
|
|
@@ -379,31 +472,42 @@ class ClearingHouseUser {
|
|
|
379
472
|
}
|
|
380
473
|
/**
|
|
381
474
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
475
|
+
*
|
|
476
|
+
* To Calculate Max Quote Available:
|
|
477
|
+
*
|
|
478
|
+
* Case 1: SameSide
|
|
479
|
+
* => Remaining quote to get to maxLeverage
|
|
480
|
+
*
|
|
481
|
+
* Case 2: NOT SameSide && currentLeverage <= maxLeverage
|
|
482
|
+
* => Current opposite position x2 + remaining to get to maxLeverage
|
|
483
|
+
*
|
|
484
|
+
* Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
|
|
485
|
+
* => strictly reduce current position size
|
|
486
|
+
*
|
|
487
|
+
* Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
|
|
488
|
+
* => current position + remaining to get to maxLeverage
|
|
489
|
+
*
|
|
382
490
|
* @param marketIndex
|
|
383
491
|
* @param tradeSide
|
|
384
492
|
* @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
|
|
385
493
|
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
386
494
|
*/
|
|
387
495
|
getMaxTradeSizeUSDC(targetMarketIndex, tradeSide, userMaxLeverageSetting) {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
};
|
|
402
|
-
const currentPosition = this.getUserPosition(targetMarketIndex);
|
|
496
|
+
const currentPosition = this.getUserPosition(targetMarketIndex) ||
|
|
497
|
+
this.getEmptyPosition(targetMarketIndex);
|
|
498
|
+
const targetSide = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
|
|
499
|
+
const currentPositionSide = (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())
|
|
500
|
+
? 'short'
|
|
501
|
+
: 'long';
|
|
502
|
+
const targettingSameSide = !currentPosition
|
|
503
|
+
? true
|
|
504
|
+
: targetSide === currentPositionSide;
|
|
505
|
+
// add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
|
|
506
|
+
const oppositeSizeValueUSDC = targettingSameSide
|
|
507
|
+
? numericConstants_1.ZERO
|
|
508
|
+
: this.getPositionValue(targetMarketIndex);
|
|
403
509
|
// get current leverage
|
|
404
510
|
const currentLeverage = this.getLeverage();
|
|
405
|
-
// remaining leverage
|
|
406
|
-
// let remainingLeverage = userMaxLeverageSetting;
|
|
407
511
|
const remainingLeverage = bn_js_1.default.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
|
|
408
512
|
// get total collateral
|
|
409
513
|
const totalCollateral = this.getTotalCollateral();
|
|
@@ -411,9 +515,43 @@ class ClearingHouseUser {
|
|
|
411
515
|
let maxPositionSize = remainingLeverage
|
|
412
516
|
.mul(totalCollateral)
|
|
413
517
|
.div(numericConstants_1.TEN_THOUSAND);
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
518
|
+
if (userMaxLeverageSetting.sub(currentLeverage).gte(numericConstants_1.ZERO)) {
|
|
519
|
+
if (oppositeSizeValueUSDC.eq(numericConstants_1.ZERO)) {
|
|
520
|
+
// case 1 : Regular trade where current total position less than max, and no opposite position to account for
|
|
521
|
+
// do nothing
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
// case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
|
|
525
|
+
maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
// current leverage is greater than max leverage - can only reduce position size
|
|
530
|
+
if (!targettingSameSide) {
|
|
531
|
+
const currentPositionQuoteSize = this.getPositionValue(targetMarketIndex);
|
|
532
|
+
const currentTotalQuoteSize = currentLeverage
|
|
533
|
+
.mul(totalCollateral)
|
|
534
|
+
.div(numericConstants_1.TEN_THOUSAND);
|
|
535
|
+
const otherPositionsTotalQuoteSize = currentTotalQuoteSize.sub(currentPositionQuoteSize);
|
|
536
|
+
const quoteValueOfMaxLeverage = userMaxLeverageSetting
|
|
537
|
+
.mul(totalCollateral)
|
|
538
|
+
.div(numericConstants_1.TEN_THOUSAND);
|
|
539
|
+
if (otherPositionsTotalQuoteSize
|
|
540
|
+
.sub(currentPositionQuoteSize)
|
|
541
|
+
.gte(quoteValueOfMaxLeverage)) {
|
|
542
|
+
// case 3: Can only reduce the current position because it will still be greater than max leverage
|
|
543
|
+
maxPositionSize = currentPositionQuoteSize;
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
// case 4: Can reduce the position, and then take extra remaining quote to get to max leverage
|
|
547
|
+
const allowedQuoteSizeAfterClosingCurrentPosition = quoteValueOfMaxLeverage.sub(otherPositionsTotalQuoteSize);
|
|
548
|
+
maxPositionSize = currentPositionQuoteSize.add(allowedQuoteSizeAfterClosingCurrentPosition);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
// do nothing if targetting same side
|
|
553
|
+
}
|
|
554
|
+
}
|
|
417
555
|
// subtract oneMillionth of maxPositionSize
|
|
418
556
|
// => to avoid rounding errors when taking max leverage
|
|
419
557
|
const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
|
|
@@ -428,9 +566,10 @@ class ClearingHouseUser {
|
|
|
428
566
|
* @returns leverageRatio : Precision TEN_THOUSAND
|
|
429
567
|
*/
|
|
430
568
|
accountLeverageRatioAfterTrade(targetMarketIndex, tradeQuoteAmount, tradeSide) {
|
|
431
|
-
const currentPosition = this.getUserPosition(targetMarketIndex)
|
|
432
|
-
|
|
433
|
-
|
|
569
|
+
const currentPosition = this.getUserPosition(targetMarketIndex) ||
|
|
570
|
+
this.getEmptyPosition(targetMarketIndex);
|
|
571
|
+
let currentPositionQuoteAmount = this.getPositionValue(targetMarketIndex);
|
|
572
|
+
const currentSide = currentPosition && currentPosition.baseAssetAmount.isNeg()
|
|
434
573
|
? _1.PositionDirection.SHORT
|
|
435
574
|
: _1.PositionDirection.LONG;
|
|
436
575
|
if (currentSide === _1.PositionDirection.SHORT)
|
|
@@ -441,11 +580,18 @@ class ClearingHouseUser {
|
|
|
441
580
|
.add(tradeQuoteAmount)
|
|
442
581
|
.abs();
|
|
443
582
|
const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPositionValueExcludingMarket(targetMarketIndex);
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
583
|
+
const totalCollateral = this.getTotalCollateral();
|
|
584
|
+
if (totalCollateral.gt(numericConstants_1.ZERO)) {
|
|
585
|
+
const newLeverage = currentMarketPositionAfterTrade
|
|
586
|
+
.add(totalPositionAfterTradeExcludingTargetMarket)
|
|
587
|
+
.abs()
|
|
588
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
589
|
+
.div(totalCollateral);
|
|
590
|
+
return newLeverage;
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
return new bn_js_1.default(0);
|
|
594
|
+
}
|
|
449
595
|
}
|
|
450
596
|
/**
|
|
451
597
|
* Calculates how much fee will be taken for a given sized trade
|
|
@@ -464,11 +610,11 @@ class ClearingHouseUser {
|
|
|
464
610
|
* @returns positionValue : Precision QUOTE_PRECISION
|
|
465
611
|
*/
|
|
466
612
|
getTotalPositionValueExcludingMarket(marketToIgnore) {
|
|
467
|
-
const currentMarketPosition = this.getUserPosition(marketToIgnore)
|
|
613
|
+
const currentMarketPosition = this.getUserPosition(marketToIgnore) ||
|
|
614
|
+
this.getEmptyPosition(marketToIgnore);
|
|
468
615
|
let currentMarketPositionValueUSDC = numericConstants_1.ZERO;
|
|
469
616
|
if (currentMarketPosition) {
|
|
470
|
-
|
|
471
|
-
currentMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, currentMarketPosition);
|
|
617
|
+
currentMarketPositionValueUSDC = this.getPositionValue(marketToIgnore);
|
|
472
618
|
}
|
|
473
619
|
return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
|
|
474
620
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markets.d.ts","sourceRoot":"","sources":["../../src/constants/markets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,aAAK,MAAM,GAAG;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,EAAE,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"markets.d.ts","sourceRoot":"","sources":["../../src/constants/markets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,aAAK,MAAM,GAAG;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,EAAE,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,EAyD3B,CAAC"}
|
package/lib/constants/markets.js
CHANGED
|
@@ -41,4 +41,25 @@ exports.Markets = [
|
|
|
41
41
|
devnetPythOracle: 'FVb5h1VmHPfVb1RfqZckchq18GxRv4iKt8T4eVTQAqdz',
|
|
42
42
|
mainnetPythOracle: 'Ax9ujW5B9oqcv59N8m6f1BpTBq2rGeGaBcpKjC5UYsXU',
|
|
43
43
|
},
|
|
44
|
+
{
|
|
45
|
+
symbol: 'BNB-PERP',
|
|
46
|
+
baseAssetSymbol: 'BNB',
|
|
47
|
+
marketIndex: new bn_js_1.default(5),
|
|
48
|
+
devnetPythOracle: 'GwzBgrXb4PG59zjce24SF2b9JXbLEjJJTBkmytuEZj1b',
|
|
49
|
+
mainnetPythOracle: '4CkQJBxhU8EZ2UjhigbtdaPbpTe6mqf811fipYBFbSYN',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
symbol: 'MATIC-PERP',
|
|
53
|
+
baseAssetSymbol: 'MATIC',
|
|
54
|
+
marketIndex: new bn_js_1.default(6),
|
|
55
|
+
devnetPythOracle: 'FBirwuDFuRAu4iSGc7RGxN5koHB7EJM1wbCmyPuQoGur',
|
|
56
|
+
mainnetPythOracle: '7KVswB9vkCgeM3SHP7aGDijvdRAHK8P5wi9JXViCrtYh',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
symbol: 'ATOM-PERP',
|
|
60
|
+
baseAssetSymbol: 'ATOM',
|
|
61
|
+
marketIndex: new bn_js_1.default(7),
|
|
62
|
+
devnetPythOracle: '7YAze8qFUMkBnyLVdKT4TFUUFui99EwS5gfRArMcrvFk',
|
|
63
|
+
mainnetPythOracle: 'CrCpTerNqtZvqLcKqz1k13oVeXV9WkMD2zA9hBKXrsbN',
|
|
64
|
+
},
|
|
44
65
|
];
|
|
@@ -13,4 +13,5 @@ export declare const PEG_PRECISION: BN;
|
|
|
13
13
|
export declare const AMM_RESERVE_PRECISION: BN;
|
|
14
14
|
export declare const AMM_TO_QUOTE_PRECISION_RATIO: BN;
|
|
15
15
|
export declare const PRICE_TO_QUOTE_PRECISION: BN;
|
|
16
|
+
export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
|
|
16
17
|
//# sourceMappingURL=numericConstants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numericConstants.d.ts","sourceRoot":"","sources":["../../src/constants/numericConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,eAAO,MAAM,IAAI,IAAY,CAAC;AAC9B,eAAO,MAAM,GAAG,IAAY,CAAC;AAC7B,eAAO,MAAM,YAAY,IAAgB,CAAC;AAC1C,eAAO,MAAM,MAAM,IAAkC,CAAC;AAEtD,eAAO,MAAM,YAAY,IAAY,CAAC;AACtC,eAAO,MAAM,sBAAsB,IAAc,CAAC;AAClD,eAAO,MAAM,yBAAyB,IAAc,CAAC;AAErD,eAAO,MAAM,eAAe,IAAkB,CAAC;AAC/C,eAAO,MAAM,oBAAoB,IAAmB,CAAC;AACrD,eAAO,MAAM,yBAAyB,IAAgB,CAAC;AACvD,eAAO,MAAM,aAAa,IAAe,CAAC;AAE1C,eAAO,MAAM,qBAAqB,IAAmB,CAAC;AACtD,eAAO,MAAM,4BAA4B,IACE,CAAC;AAC5C,eAAO,MAAM,wBAAwB,IACK,CAAC"}
|
|
1
|
+
{"version":3,"file":"numericConstants.d.ts","sourceRoot":"","sources":["../../src/constants/numericConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,eAAO,MAAM,IAAI,IAAY,CAAC;AAC9B,eAAO,MAAM,GAAG,IAAY,CAAC;AAC7B,eAAO,MAAM,YAAY,IAAgB,CAAC;AAC1C,eAAO,MAAM,MAAM,IAAkC,CAAC;AAEtD,eAAO,MAAM,YAAY,IAAY,CAAC;AACtC,eAAO,MAAM,sBAAsB,IAAc,CAAC;AAClD,eAAO,MAAM,yBAAyB,IAAc,CAAC;AAErD,eAAO,MAAM,eAAe,IAAkB,CAAC;AAC/C,eAAO,MAAM,oBAAoB,IAAmB,CAAC;AACrD,eAAO,MAAM,yBAAyB,IAAgB,CAAC;AACvD,eAAO,MAAM,aAAa,IAAe,CAAC;AAE1C,eAAO,MAAM,qBAAqB,IAAmB,CAAC;AACtD,eAAO,MAAM,4BAA4B,IACE,CAAC;AAC5C,eAAO,MAAM,wBAAwB,IACK,CAAC;AAC3C,eAAO,MAAM,sCAAsC,IACW,CAAC"}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.PARTIAL_LIQUIDATION_RATIO = exports.FULL_LIQUIDATION_RATIO = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.ONE = exports.ZERO = void 0;
|
|
6
|
+
exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.PARTIAL_LIQUIDATION_RATIO = exports.FULL_LIQUIDATION_RATIO = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.ONE = exports.ZERO = void 0;
|
|
7
7
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
8
8
|
exports.ZERO = new bn_js_1.default(0);
|
|
9
9
|
exports.ONE = new bn_js_1.default(1);
|
|
@@ -19,3 +19,4 @@ exports.PEG_PRECISION = new bn_js_1.default(1000);
|
|
|
19
19
|
exports.AMM_RESERVE_PRECISION = new bn_js_1.default(Math.pow(10, 13));
|
|
20
20
|
exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.div(exports.QUOTE_PRECISION); // 10^7
|
|
21
21
|
exports.PRICE_TO_QUOTE_PRECISION = exports.MARK_PRICE_PRECISION.div(exports.QUOTE_PRECISION);
|
|
22
|
+
exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.mul(exports.PEG_PRECISION).div(exports.QUOTE_PRECISION); // 10^10
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeTradeExample.d.ts","sourceRoot":"","sources":["../../src/examples/makeTradeExample.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"makeTradeExample.d.ts","sourceRoot":"","sources":["../../src/examples/makeTradeExample.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAcjE,eAAO,MAAM,eAAe,gBACd,MAAM,cACP,MAAM,KAChB,QAAQ,SAAS,CAOnB,CAAC"}
|
|
@@ -11,20 +11,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.getTokenAddress = void 0;
|
|
13
13
|
const anchor_1 = require("@project-serum/anchor");
|
|
14
|
+
const __1 = require("..");
|
|
14
15
|
const spl_token_1 = require("@solana/spl-token");
|
|
15
16
|
const web3_js_1 = require("@solana/web3.js");
|
|
16
|
-
const
|
|
17
|
+
const __2 = require("..");
|
|
17
18
|
const getTokenAddress = (mintAddress, userPubKey) => {
|
|
18
19
|
return spl_token_1.Token.getAssociatedTokenAddress(new web3_js_1.PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`), spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
|
|
19
20
|
};
|
|
20
21
|
exports.getTokenAddress = getTokenAddress;
|
|
21
22
|
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
23
|
// Initialize Drift SDK
|
|
23
|
-
const sdkConfig =
|
|
24
|
+
const sdkConfig = __2.initialize({ env: 'devnet' });
|
|
24
25
|
// Set up the Wallet and Provider
|
|
25
26
|
const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
|
|
26
27
|
const keypair = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(JSON.parse(privateKey)));
|
|
27
|
-
const wallet = new
|
|
28
|
+
const wallet = new __1.Wallet(keypair);
|
|
28
29
|
// Set up the Connection
|
|
29
30
|
const rpcAddress = process.env.RPC_ADDRESS; // can use: https://api.devnet.solana.com for devnet; https://api.mainnet-beta.solana.com for mainnet;
|
|
30
31
|
const connection = new web3_js_1.Connection(rpcAddress);
|
|
@@ -37,35 +38,35 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
37
38
|
const usdcTokenAddress = yield exports.getTokenAddress(sdkConfig.USDC_MINT_ADDRESS, wallet.publicKey.toString());
|
|
38
39
|
// Set up the Drift Clearing House
|
|
39
40
|
const clearingHousePublicKey = new web3_js_1.PublicKey(sdkConfig.CLEARING_HOUSE_PROGRAM_ID);
|
|
40
|
-
const clearingHouse =
|
|
41
|
+
const clearingHouse = __2.ClearingHouse.from(connection, provider.wallet, clearingHousePublicKey);
|
|
41
42
|
yield clearingHouse.subscribe();
|
|
42
43
|
// Set up Clearing House user client
|
|
43
|
-
const user =
|
|
44
|
+
const user = __2.ClearingHouseUser.from(clearingHouse, wallet.publicKey);
|
|
44
45
|
//// Check if clearing house account exists for the current wallet
|
|
45
46
|
const userAccountExists = yield user.exists();
|
|
46
47
|
if (!userAccountExists) {
|
|
47
48
|
//// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
|
|
48
|
-
const depositAmount = new anchor_1.BN(10000).mul(
|
|
49
|
+
const depositAmount = new anchor_1.BN(10000).mul(__2.QUOTE_PRECISION);
|
|
49
50
|
yield clearingHouse.initializeUserAccountAndDepositCollateral(depositAmount, yield exports.getTokenAddress(usdcTokenAddress.toString(), wallet.publicKey.toString()));
|
|
50
51
|
}
|
|
51
52
|
yield user.subscribe();
|
|
52
53
|
// Get current price
|
|
53
|
-
const solMarketInfo =
|
|
54
|
-
const currentMarketPrice =
|
|
55
|
-
const formattedPrice =
|
|
54
|
+
const solMarketInfo = __2.Markets.find((market) => market.baseAssetSymbol === 'SOL');
|
|
55
|
+
const currentMarketPrice = __2.calculateMarkPrice(clearingHouse.getMarket(solMarketInfo.marketIndex));
|
|
56
|
+
const formattedPrice = __2.convertToNumber(currentMarketPrice, __2.QUOTE_PRECISION);
|
|
56
57
|
console.log(`Current Market Price is $${formattedPrice}`);
|
|
57
58
|
// Estimate the slippage for a $5000 LONG trade
|
|
58
59
|
const solMarketAccount = clearingHouse.getMarket(solMarketInfo.marketIndex);
|
|
59
|
-
const slippage =
|
|
60
|
+
const slippage = __2.convertToNumber(__2.calculateTradeSlippage(__2.PositionDirection.LONG, new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION), solMarketAccount)[0], __2.MARK_PRICE_PRECISION);
|
|
60
61
|
console.log(`Slippage for a $5000 LONG on the SOL market would be $${slippage}`);
|
|
61
62
|
// Make a $5000 LONG trade
|
|
62
|
-
yield clearingHouse.openPosition(
|
|
63
|
+
yield clearingHouse.openPosition(__2.PositionDirection.LONG, new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION), solMarketInfo.marketIndex);
|
|
63
64
|
console.log(`LONGED $5000 SOL`);
|
|
64
65
|
// Make a $5000 LONG trade
|
|
65
|
-
yield clearingHouse.openPosition(
|
|
66
|
+
yield clearingHouse.openPosition(__2.PositionDirection.LONG, new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION), solMarketInfo.marketIndex);
|
|
66
67
|
console.log(`LONGED $5000 worth of SOL`);
|
|
67
68
|
// Reduce the position by $2000
|
|
68
|
-
yield clearingHouse.openPosition(
|
|
69
|
+
yield clearingHouse.openPosition(__2.PositionDirection.SHORT, new anchor_1.BN(2000).mul(__2.QUOTE_PRECISION), solMarketInfo.marketIndex);
|
|
69
70
|
// Close the rest of the position
|
|
70
71
|
yield clearingHouse.closePosition(solMarketInfo.marketIndex);
|
|
71
72
|
});
|