@drift-labs/sdk 0.1.18-master.0 → 0.1.18-orders.1
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/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts +7 -4
- package/lib/accounts/defaultClearingHouseAccountSubscriber.js +27 -2
- package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +28 -0
- package/lib/accounts/defaultHistoryAccountSubscriber.js +110 -0
- package/lib/accounts/defaultUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/defaultUserAccountSubscriber.js +12 -1
- package/lib/accounts/types.d.ts +31 -5
- package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
- package/lib/addresses.d.ts +4 -1
- package/lib/addresses.js +28 -1
- package/lib/admin.d.ts +10 -5
- package/lib/admin.js +53 -30
- package/lib/assert/assert.d.ts +0 -1
- package/lib/clearingHouse.d.ts +22 -3
- package/lib/clearingHouse.js +246 -15
- package/lib/clearingHouseUser.d.ts +10 -17
- package/lib/clearingHouseUser.js +111 -97
- package/lib/config.d.ts +0 -1
- package/lib/config.js +1 -1
- package/lib/constants/markets.d.ts +0 -1
- package/lib/constants/numericConstants.d.ts +0 -1
- package/lib/examples/makeTradeExample.d.ts +0 -1
- package/lib/examples/makeTradeExample.js +6 -6
- package/lib/idl/clearing_house.json +895 -132
- package/lib/index.d.ts +4 -1
- package/lib/index.js +4 -0
- package/lib/math/amm.d.ts +1 -1
- package/lib/math/amm.js +38 -15
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/conversion.js +1 -1
- package/lib/math/funding.d.ts +0 -1
- package/lib/math/funding.js +1 -1
- package/lib/math/insuranceFund.d.ts +0 -1
- package/lib/math/market.d.ts +2 -2
- package/lib/math/market.js +12 -2
- package/lib/math/orders.d.ts +3 -0
- package/lib/math/orders.js +30 -0
- package/lib/math/position.d.ts +4 -2
- package/lib/math/position.js +19 -5
- package/lib/math/trade.d.ts +0 -1
- package/lib/math/trade.js +16 -16
- package/lib/math/utils.d.ts +0 -1
- package/lib/mockUSDCFaucet.d.ts +0 -1
- package/lib/orderParams.d.ts +7 -0
- package/lib/orderParams.js +88 -0
- package/lib/orders.d.ts +5 -0
- package/lib/orders.js +136 -0
- package/lib/pythClient.d.ts +0 -1
- package/lib/pythClient.js +1 -1
- package/lib/tx/defaultTxSender.d.ts +0 -1
- package/lib/tx/types.d.ts +0 -1
- package/lib/tx/utils.d.ts +0 -1
- package/lib/types.d.ts +140 -7
- package/lib/types.js +36 -1
- package/lib/util/computeUnits.d.ts +0 -1
- package/lib/util/tps.d.ts +0 -1
- package/lib/wallet.d.ts +0 -1
- package/package.json +1 -1
- package/src/accounts/defaultClearingHouseAccountSubscriber.ts +52 -5
- package/src/accounts/defaultHistoryAccountSubscriber.ts +176 -0
- package/src/accounts/defaultUserAccountSubscriber.ts +29 -2
- package/src/accounts/types.ts +41 -4
- package/src/addresses.ts +35 -0
- package/src/admin.ts +86 -33
- package/src/clearingHouse.ts +340 -7
- package/src/clearingHouseUser.ts +154 -102
- package/src/config.ts +1 -1
- package/src/idl/clearing_house.json +895 -132
- package/src/index.ts +4 -0
- package/src/math/amm.ts +47 -14
- package/src/math/market.ts +28 -2
- package/src/math/orders.ts +39 -0
- package/src/math/position.ts +23 -3
- package/src/orderParams.ts +128 -0
- package/src/orders.ts +230 -0
- package/src/types.ts +124 -6
- package/tsconfig.json +0 -1
- package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/types.d.ts.map +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
- package/lib/addresses.d.ts.map +0 -1
- package/lib/admin.d.ts.map +0 -1
- package/lib/assert/assert.d.ts.map +0 -1
- package/lib/clearingHouse.d.ts.map +0 -1
- package/lib/clearingHouseUser.d.ts.map +0 -1
- package/lib/config.d.ts.map +0 -1
- package/lib/constants/markets.d.ts.map +0 -1
- package/lib/constants/numericConstants.d.ts.map +0 -1
- package/lib/examples/makeTradeExample.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/math/amm.d.ts.map +0 -1
- package/lib/math/conversion.d.ts.map +0 -1
- package/lib/math/funding.d.ts.map +0 -1
- package/lib/math/insuranceFund.d.ts.map +0 -1
- package/lib/math/market.d.ts.map +0 -1
- package/lib/math/position.d.ts.map +0 -1
- package/lib/math/trade.d.ts.map +0 -1
- package/lib/math/utils.d.ts.map +0 -1
- package/lib/mockUSDCFaucet.d.ts.map +0 -1
- package/lib/pythClient.d.ts.map +0 -1
- package/lib/tx/defaultTxSender.d.ts.map +0 -1
- package/lib/tx/types.d.ts.map +0 -1
- package/lib/tx/utils.d.ts.map +0 -1
- package/lib/types.d.ts.map +0 -1
- package/lib/util/computeUnits.d.ts.map +0 -1
- package/lib/util/tps.d.ts.map +0 -1
- package/lib/wallet.d.ts.map +0 -1
package/lib/clearingHouseUser.js
CHANGED
|
@@ -63,6 +63,9 @@ class ClearingHouseUser {
|
|
|
63
63
|
getUserPositionsAccount() {
|
|
64
64
|
return this.accountSubscriber.getUserPositionsAccount();
|
|
65
65
|
}
|
|
66
|
+
getUserOrdersAccount() {
|
|
67
|
+
return this.accountSubscriber.getUserOrdersAccount();
|
|
68
|
+
}
|
|
66
69
|
/**
|
|
67
70
|
* Gets the user's current position for a given market. If the user has no position returns undefined
|
|
68
71
|
* @param marketIndex
|
|
@@ -77,17 +80,34 @@ class ClearingHouseUser {
|
|
|
77
80
|
lastCumulativeFundingRate: numericConstants_1.ZERO,
|
|
78
81
|
marketIndex,
|
|
79
82
|
quoteAssetAmount: numericConstants_1.ZERO,
|
|
83
|
+
openOrders: numericConstants_1.ZERO,
|
|
80
84
|
};
|
|
81
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* @param orderId
|
|
88
|
+
* @returns Order
|
|
89
|
+
*/
|
|
90
|
+
getOrder(orderId) {
|
|
91
|
+
return this.getUserOrdersAccount().orders.find((order) => order.orderId.eq(orderId));
|
|
92
|
+
}
|
|
82
93
|
getUserAccountPublicKey() {
|
|
83
94
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
95
|
if (this.userAccountPublicKey) {
|
|
85
96
|
return this.userAccountPublicKey;
|
|
86
97
|
}
|
|
87
|
-
this.userAccountPublicKey = yield
|
|
98
|
+
this.userAccountPublicKey = yield addresses_1.getUserAccountPublicKey(this.clearingHouse.program.programId, this.authority);
|
|
88
99
|
return this.userAccountPublicKey;
|
|
89
100
|
});
|
|
90
101
|
}
|
|
102
|
+
getUserOrdersAccountPublicKey() {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
if (this.userOrdersAccountPublicKey) {
|
|
105
|
+
return this.userOrdersAccountPublicKey;
|
|
106
|
+
}
|
|
107
|
+
this.userOrdersAccountPublicKey = yield _1.getUserOrdersAccountPublicKey(this.clearingHouse.program.programId, this.authority);
|
|
108
|
+
return this.userOrdersAccountPublicKey;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
91
111
|
exists() {
|
|
92
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
113
|
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
@@ -122,7 +142,7 @@ class ClearingHouseUser {
|
|
|
122
142
|
.positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
|
|
123
143
|
.reduce((pnl, marketPosition) => {
|
|
124
144
|
const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
125
|
-
return pnl.add(
|
|
145
|
+
return pnl.add(_1.calculatePositionPNL(market, marketPosition, withFunding));
|
|
126
146
|
}, numericConstants_1.ZERO);
|
|
127
147
|
}
|
|
128
148
|
/**
|
|
@@ -134,7 +154,7 @@ class ClearingHouseUser {
|
|
|
134
154
|
.positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
|
|
135
155
|
.reduce((pnl, marketPosition) => {
|
|
136
156
|
const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
137
|
-
return pnl.add(
|
|
157
|
+
return pnl.add(_1.calculatePositionFundingPNL(market, marketPosition));
|
|
138
158
|
}, numericConstants_1.ZERO);
|
|
139
159
|
}
|
|
140
160
|
/**
|
|
@@ -152,7 +172,7 @@ class ClearingHouseUser {
|
|
|
152
172
|
getTotalPositionValue() {
|
|
153
173
|
return this.getUserPositionsAccount().positions.reduce((positionValue, marketPosition) => {
|
|
154
174
|
const market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
155
|
-
return positionValue.add(
|
|
175
|
+
return positionValue.add(_1.calculateBaseAssetValue(market, marketPosition));
|
|
156
176
|
}, numericConstants_1.ZERO);
|
|
157
177
|
}
|
|
158
178
|
/**
|
|
@@ -162,7 +182,7 @@ class ClearingHouseUser {
|
|
|
162
182
|
getPositionValue(marketIndex) {
|
|
163
183
|
const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
|
|
164
184
|
const market = this.clearingHouse.getMarket(userPosition.marketIndex);
|
|
165
|
-
return
|
|
185
|
+
return _1.calculateBaseAssetValue(market, userPosition);
|
|
166
186
|
}
|
|
167
187
|
getPositionSide(currentPosition) {
|
|
168
188
|
if (currentPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
@@ -181,10 +201,10 @@ class ClearingHouseUser {
|
|
|
181
201
|
*/
|
|
182
202
|
getPositionEstimatedExitPriceAndPnl(position, amountToClose) {
|
|
183
203
|
const market = this.clearingHouse.getMarket(position.marketIndex);
|
|
184
|
-
const entryPrice =
|
|
204
|
+
const entryPrice = position_1.calculateEntryPrice(position);
|
|
185
205
|
if (amountToClose) {
|
|
186
206
|
if (amountToClose.eq(numericConstants_1.ZERO)) {
|
|
187
|
-
return [
|
|
207
|
+
return [_1.calculateMarkPrice(market), numericConstants_1.ZERO];
|
|
188
208
|
}
|
|
189
209
|
position = {
|
|
190
210
|
baseAssetAmount: amountToClose,
|
|
@@ -193,7 +213,7 @@ class ClearingHouseUser {
|
|
|
193
213
|
quoteAssetAmount: position.quoteAssetAmount,
|
|
194
214
|
};
|
|
195
215
|
}
|
|
196
|
-
const baseAssetValue =
|
|
216
|
+
const baseAssetValue = _1.calculateBaseAssetValue(market, position);
|
|
197
217
|
if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
198
218
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
199
219
|
}
|
|
@@ -300,7 +320,7 @@ class ClearingHouseUser {
|
|
|
300
320
|
|
|
301
321
|
for 10x long, BTC down $400:
|
|
302
322
|
3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
|
|
303
|
-
const currentPrice =
|
|
323
|
+
const currentPrice = _1.calculateMarkPrice(this.clearingHouse.getMarket(targetMarket.marketIndex));
|
|
304
324
|
const totalCollateralUSDC = this.getTotalCollateral();
|
|
305
325
|
// calculate the total position value ignoring any value from the target market of the trade
|
|
306
326
|
const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
|
|
@@ -313,9 +333,10 @@ class ClearingHouseUser {
|
|
|
313
333
|
baseAssetAmount: currentMarketPositionBaseSize.add(positionBaseSizeChange),
|
|
314
334
|
lastCumulativeFundingRate: new bn_js_1.default(0),
|
|
315
335
|
quoteAssetAmount: new bn_js_1.default(0),
|
|
336
|
+
openOrders: new bn_js_1.default(0),
|
|
316
337
|
};
|
|
317
338
|
const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
|
|
318
|
-
const proposedMarketPositionValueUSDC =
|
|
339
|
+
const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
|
|
319
340
|
// total position value after trade
|
|
320
341
|
const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
|
|
321
342
|
let totalFreeCollateralUSDC = this.getTotalCollateral().sub(this.getTotalPositionValue()
|
|
@@ -373,14 +394,14 @@ class ClearingHouseUser {
|
|
|
373
394
|
liquidationPrice(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
|
|
374
395
|
// solves formula for example calc below
|
|
375
396
|
/* example: assume BTC price is $40k (examine 10% up/down)
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
397
|
+
|
|
398
|
+
if 10k deposit and levered 10x short BTC => BTC up $400 means:
|
|
399
|
+
1. higher base_asset_value (+$4k)
|
|
400
|
+
2. lower collateral (-$4k)
|
|
401
|
+
3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
|
|
402
|
+
|
|
403
|
+
for 10x long, BTC down $400:
|
|
404
|
+
3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
|
|
384
405
|
const tc = this.getTotalCollateral();
|
|
385
406
|
const tpv = this.getTotalPositionValue();
|
|
386
407
|
const partialLev = 16;
|
|
@@ -398,9 +419,10 @@ class ClearingHouseUser {
|
|
|
398
419
|
baseAssetAmount: proposedBaseAssetAmount,
|
|
399
420
|
lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
|
|
400
421
|
quoteAssetAmount: new bn_js_1.default(0),
|
|
422
|
+
openOrders: new bn_js_1.default(0),
|
|
401
423
|
};
|
|
402
424
|
const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
|
|
403
|
-
const proposedMarketPositionValueUSDC =
|
|
425
|
+
const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
|
|
404
426
|
// total position value after trade
|
|
405
427
|
const targetTotalPositionValueUSDC = totalCurrentPositionValueIgnoringTargetUSDC.add(proposedMarketPositionValueUSDC);
|
|
406
428
|
let totalFreeCollateralUSDC = tc.sub(totalCurrentPositionValueIgnoringTargetUSDC
|
|
@@ -428,13 +450,13 @@ class ClearingHouseUser {
|
|
|
428
450
|
}
|
|
429
451
|
let currentPrice;
|
|
430
452
|
if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
|
|
431
|
-
currentPrice =
|
|
453
|
+
currentPrice = _1.calculateMarkPrice(this.clearingHouse.getMarket(targetMarket.marketIndex));
|
|
432
454
|
}
|
|
433
455
|
else {
|
|
434
456
|
const direction = positionBaseSizeChange.gt(numericConstants_1.ZERO)
|
|
435
457
|
? _1.PositionDirection.LONG
|
|
436
458
|
: _1.PositionDirection.SHORT;
|
|
437
|
-
currentPrice =
|
|
459
|
+
currentPrice = _1.calculateTradeSlippage(direction, positionBaseSizeChange.abs(), this.clearingHouse.getMarket(targetMarket.marketIndex), 'base')[3]; // newPrice after swap
|
|
438
460
|
}
|
|
439
461
|
// if the position value after the trade is less than total collateral, there is no liq price
|
|
440
462
|
if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
|
|
@@ -474,42 +496,32 @@ class ClearingHouseUser {
|
|
|
474
496
|
}
|
|
475
497
|
/**
|
|
476
498
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
477
|
-
*
|
|
478
|
-
* To Calculate Max Quote Available:
|
|
479
|
-
*
|
|
480
|
-
* Case 1: SameSide
|
|
481
|
-
* => Remaining quote to get to maxLeverage
|
|
482
|
-
*
|
|
483
|
-
* Case 2: NOT SameSide && currentLeverage <= maxLeverage
|
|
484
|
-
* => Current opposite position x2 + remaining to get to maxLeverage
|
|
485
|
-
*
|
|
486
|
-
* Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
|
|
487
|
-
* => strictly reduce current position size
|
|
488
|
-
*
|
|
489
|
-
* Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
|
|
490
|
-
* => current position + remaining to get to maxLeverage
|
|
491
|
-
*
|
|
492
499
|
* @param marketIndex
|
|
493
500
|
* @param tradeSide
|
|
494
501
|
* @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
|
|
495
502
|
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
496
503
|
*/
|
|
497
504
|
getMaxTradeSizeUSDC(targetMarketIndex, tradeSide, userMaxLeverageSetting) {
|
|
505
|
+
// inline function which get's the current position size on the opposite side of the target trade
|
|
506
|
+
const getOppositePositionValueUSDC = () => {
|
|
507
|
+
if (!currentPosition)
|
|
508
|
+
return numericConstants_1.ZERO;
|
|
509
|
+
const side = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
|
|
510
|
+
if (side === 'long' && (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())) {
|
|
511
|
+
return this.getPositionValue(targetMarketIndex);
|
|
512
|
+
}
|
|
513
|
+
else if (side === 'short' &&
|
|
514
|
+
!(currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())) {
|
|
515
|
+
return this.getPositionValue(targetMarketIndex);
|
|
516
|
+
}
|
|
517
|
+
return numericConstants_1.ZERO;
|
|
518
|
+
};
|
|
498
519
|
const currentPosition = this.getUserPosition(targetMarketIndex) ||
|
|
499
520
|
this.getEmptyPosition(targetMarketIndex);
|
|
500
|
-
const targetSide = tradeSide === _1.PositionDirection.SHORT ? 'short' : 'long';
|
|
501
|
-
const currentPositionSide = (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())
|
|
502
|
-
? 'short'
|
|
503
|
-
: 'long';
|
|
504
|
-
const targettingSameSide = !currentPosition
|
|
505
|
-
? true
|
|
506
|
-
: targetSide === currentPositionSide;
|
|
507
|
-
// 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.
|
|
508
|
-
const oppositeSizeValueUSDC = targettingSameSide
|
|
509
|
-
? numericConstants_1.ZERO
|
|
510
|
-
: this.getPositionValue(targetMarketIndex);
|
|
511
521
|
// get current leverage
|
|
512
522
|
const currentLeverage = this.getLeverage();
|
|
523
|
+
// remaining leverage
|
|
524
|
+
// let remainingLeverage = userMaxLeverageSetting;
|
|
513
525
|
const remainingLeverage = bn_js_1.default.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
|
|
514
526
|
// get total collateral
|
|
515
527
|
const totalCollateral = this.getTotalCollateral();
|
|
@@ -517,43 +529,9 @@ class ClearingHouseUser {
|
|
|
517
529
|
let maxPositionSize = remainingLeverage
|
|
518
530
|
.mul(totalCollateral)
|
|
519
531
|
.div(numericConstants_1.TEN_THOUSAND);
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
// do nothing
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
// case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
|
|
527
|
-
maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
else {
|
|
531
|
-
// current leverage is greater than max leverage - can only reduce position size
|
|
532
|
-
if (!targettingSameSide) {
|
|
533
|
-
const currentPositionQuoteSize = this.getPositionValue(targetMarketIndex);
|
|
534
|
-
const currentTotalQuoteSize = currentLeverage
|
|
535
|
-
.mul(totalCollateral)
|
|
536
|
-
.div(numericConstants_1.TEN_THOUSAND);
|
|
537
|
-
const otherPositionsTotalQuoteSize = currentTotalQuoteSize.sub(currentPositionQuoteSize);
|
|
538
|
-
const quoteValueOfMaxLeverage = userMaxLeverageSetting
|
|
539
|
-
.mul(totalCollateral)
|
|
540
|
-
.div(numericConstants_1.TEN_THOUSAND);
|
|
541
|
-
if (otherPositionsTotalQuoteSize
|
|
542
|
-
.sub(currentPositionQuoteSize)
|
|
543
|
-
.gte(quoteValueOfMaxLeverage)) {
|
|
544
|
-
// case 3: Can only reduce the current position because it will still be greater than max leverage
|
|
545
|
-
maxPositionSize = currentPositionQuoteSize;
|
|
546
|
-
}
|
|
547
|
-
else {
|
|
548
|
-
// case 4: Can reduce the position, and then take extra remaining quote to get to max leverage
|
|
549
|
-
const allowedQuoteSizeAfterClosingCurrentPosition = quoteValueOfMaxLeverage.sub(otherPositionsTotalQuoteSize);
|
|
550
|
-
maxPositionSize = currentPositionQuoteSize.add(allowedQuoteSizeAfterClosingCurrentPosition);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
else {
|
|
554
|
-
// do nothing if targetting same side
|
|
555
|
-
}
|
|
556
|
-
}
|
|
532
|
+
// 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.
|
|
533
|
+
const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
|
|
534
|
+
maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
|
|
557
535
|
// subtract oneMillionth of maxPositionSize
|
|
558
536
|
// => to avoid rounding errors when taking max leverage
|
|
559
537
|
const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
|
|
@@ -582,18 +560,12 @@ class ClearingHouseUser {
|
|
|
582
560
|
.add(tradeQuoteAmount)
|
|
583
561
|
.abs();
|
|
584
562
|
const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPositionValueExcludingMarket(targetMarketIndex);
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
.div(totalCollateral);
|
|
592
|
-
return newLeverage;
|
|
593
|
-
}
|
|
594
|
-
else {
|
|
595
|
-
return new bn_js_1.default(0);
|
|
596
|
-
}
|
|
563
|
+
const newLeverage = currentMarketPositionAfterTrade
|
|
564
|
+
.add(totalPositionAfterTradeExcludingTargetMarket)
|
|
565
|
+
.abs()
|
|
566
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
567
|
+
.div(this.getTotalCollateral());
|
|
568
|
+
return newLeverage;
|
|
597
569
|
}
|
|
598
570
|
/**
|
|
599
571
|
* Calculates how much fee will be taken for a given sized trade
|
|
@@ -616,9 +588,51 @@ class ClearingHouseUser {
|
|
|
616
588
|
this.getEmptyPosition(marketToIgnore);
|
|
617
589
|
let currentMarketPositionValueUSDC = numericConstants_1.ZERO;
|
|
618
590
|
if (currentMarketPosition) {
|
|
619
|
-
|
|
591
|
+
const market = this.clearingHouse.getMarket(currentMarketPosition.marketIndex);
|
|
592
|
+
currentMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, currentMarketPosition);
|
|
620
593
|
}
|
|
621
594
|
return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
|
|
622
595
|
}
|
|
596
|
+
canFillOrder(order) {
|
|
597
|
+
const userAccount = this.getUserAccount();
|
|
598
|
+
const userPositionsAccount = this.getUserPositionsAccount();
|
|
599
|
+
const userPosition = this.getUserPosition(order.marketIndex);
|
|
600
|
+
const market = this.clearingHouse.getMarket(order.marketIndex);
|
|
601
|
+
if (position_1.isEmptyPosition(userPosition)) {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
const newState = _1.calculateNewStateAfterOrder(userAccount, userPosition, market, order);
|
|
605
|
+
if (newState === null) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
const [userAccountAfter, userPositionAfter, marketAfter] = newState;
|
|
609
|
+
const totalPositionValue = userPositionsAccount.positions.reduce((positionValue, marketPosition) => {
|
|
610
|
+
let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
611
|
+
if (marketPosition.marketIndex.eq(order.marketIndex)) {
|
|
612
|
+
market = marketAfter;
|
|
613
|
+
marketPosition = userPositionAfter;
|
|
614
|
+
}
|
|
615
|
+
return positionValue.add(_1.calculateBaseAssetValue(market, marketPosition));
|
|
616
|
+
}, numericConstants_1.ZERO);
|
|
617
|
+
if (totalPositionValue.eq(numericConstants_1.ZERO)) {
|
|
618
|
+
return true;
|
|
619
|
+
}
|
|
620
|
+
const unrealizedPnL = userPositionsAccount.positions.reduce((pnl, marketPosition) => {
|
|
621
|
+
let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
622
|
+
pnl = pnl.add(_1.calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION));
|
|
623
|
+
if (marketPosition.marketIndex.eq(order.marketIndex)) {
|
|
624
|
+
market = marketAfter;
|
|
625
|
+
marketPosition = userPositionAfter;
|
|
626
|
+
}
|
|
627
|
+
// update
|
|
628
|
+
return pnl.add(_1.calculatePositionPNL(market, marketPosition, false));
|
|
629
|
+
}, numericConstants_1.ZERO);
|
|
630
|
+
const totalCollateral = userAccountAfter.collateral.add(unrealizedPnL);
|
|
631
|
+
const marginRatioAfter = totalCollateral
|
|
632
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
633
|
+
.div(totalPositionValue);
|
|
634
|
+
const marginRatioInitial = this.clearingHouse.getStateAccount().marginRatioInitial;
|
|
635
|
+
return marginRatioAfter.gte(marginRatioInitial);
|
|
636
|
+
}
|
|
623
637
|
}
|
|
624
638
|
exports.ClearingHouseUser = ClearingHouseUser;
|
package/lib/config.d.ts
CHANGED
package/lib/config.js
CHANGED
|
@@ -5,7 +5,7 @@ exports.configs = {
|
|
|
5
5
|
devnet: {
|
|
6
6
|
ENV: 'devnet',
|
|
7
7
|
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
8
|
-
CLEARING_HOUSE_PROGRAM_ID: '
|
|
8
|
+
CLEARING_HOUSE_PROGRAM_ID: 'HiZ8CnfEE9LrBZTfc8hBneWrPg1Cbsn8Wdy6SPLfae9V',
|
|
9
9
|
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
10
10
|
},
|
|
11
11
|
'mainnet-beta': {
|
|
@@ -14,4 +14,3 @@ 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
16
|
export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
|
|
17
|
-
//# sourceMappingURL=numericConstants.d.ts.map
|
|
@@ -21,7 +21,7 @@ const getTokenAddress = (mintAddress, userPubKey) => {
|
|
|
21
21
|
exports.getTokenAddress = getTokenAddress;
|
|
22
22
|
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
23
|
// Initialize Drift SDK
|
|
24
|
-
const sdkConfig =
|
|
24
|
+
const sdkConfig = __2.initialize({ env: 'devnet' });
|
|
25
25
|
// Set up the Wallet and Provider
|
|
26
26
|
const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
|
|
27
27
|
const keypair = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(JSON.parse(privateKey)));
|
|
@@ -35,7 +35,7 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
35
35
|
const lamportsBalance = yield connection.getBalance(wallet.publicKey);
|
|
36
36
|
console.log('SOL balance:', lamportsBalance / Math.pow(10, 9));
|
|
37
37
|
// Misc. other things to set up
|
|
38
|
-
const usdcTokenAddress = yield
|
|
38
|
+
const usdcTokenAddress = yield exports.getTokenAddress(sdkConfig.USDC_MINT_ADDRESS, wallet.publicKey.toString());
|
|
39
39
|
// Set up the Drift Clearing House
|
|
40
40
|
const clearingHousePublicKey = new web3_js_1.PublicKey(sdkConfig.CLEARING_HOUSE_PROGRAM_ID);
|
|
41
41
|
const clearingHouse = __2.ClearingHouse.from(connection, provider.wallet, clearingHousePublicKey);
|
|
@@ -47,18 +47,18 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
47
47
|
if (!userAccountExists) {
|
|
48
48
|
//// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
|
|
49
49
|
const depositAmount = new anchor_1.BN(10000).mul(__2.QUOTE_PRECISION);
|
|
50
|
-
yield clearingHouse.initializeUserAccountAndDepositCollateral(depositAmount, yield
|
|
50
|
+
yield clearingHouse.initializeUserAccountAndDepositCollateral(depositAmount, yield exports.getTokenAddress(usdcTokenAddress.toString(), wallet.publicKey.toString()));
|
|
51
51
|
}
|
|
52
52
|
yield user.subscribe();
|
|
53
53
|
// Get current price
|
|
54
54
|
const solMarketInfo = __2.Markets.find((market) => market.baseAssetSymbol === 'SOL');
|
|
55
|
-
const currentMarketPrice =
|
|
56
|
-
const formattedPrice =
|
|
55
|
+
const currentMarketPrice = __2.calculateMarkPrice(clearingHouse.getMarket(solMarketInfo.marketIndex));
|
|
56
|
+
const formattedPrice = __2.convertToNumber(currentMarketPrice, __2.QUOTE_PRECISION);
|
|
57
57
|
console.log(`Current Market Price is $${formattedPrice}`);
|
|
58
58
|
// Estimate the slippage for a $5000 LONG trade
|
|
59
59
|
const solMarketAccount = clearingHouse.getMarket(solMarketInfo.marketIndex);
|
|
60
60
|
const longAmount = new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION);
|
|
61
|
-
const slippage =
|
|
61
|
+
const slippage = __2.convertToNumber(__2.calculateTradeSlippage(__2.PositionDirection.LONG, longAmount, solMarketAccount)[0], __2.MARK_PRICE_PRECISION);
|
|
62
62
|
console.log(`Slippage for a $5000 LONG on the SOL market would be $${slippage}`);
|
|
63
63
|
// Make a $5000 LONG trade
|
|
64
64
|
yield clearingHouse.openPosition(__2.PositionDirection.LONG, longAmount, solMarketInfo.marketIndex);
|