@drift-labs/common 1.0.59 → 1.0.61
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/_deprecated/common-math.d.ts +10 -0
- package/lib/_deprecated/common-math.js +9 -0
- package/lib/_deprecated/common-math.js.map +1 -0
- package/lib/_deprecated/common-ui-utils.d.ts +248 -0
- package/lib/_deprecated/common-ui-utils.js +59 -0
- package/lib/_deprecated/common-ui-utils.js.map +1 -0
- package/lib/_deprecated/equality-checks.d.ts +2 -0
- package/lib/_deprecated/equality-checks.js +7 -0
- package/lib/_deprecated/equality-checks.js.map +1 -0
- package/lib/{common-ui-utils/market.d.ts → _deprecated/market-utils.d.ts} +5 -7
- package/lib/_deprecated/market-utils.js +18 -0
- package/lib/_deprecated/market-utils.js.map +1 -0
- package/lib/_deprecated/order-utils.d.ts +12 -0
- package/lib/_deprecated/order-utils.js +18 -0
- package/lib/_deprecated/order-utils.js.map +1 -0
- package/lib/_deprecated/trading-utils.d.ts +52 -0
- package/lib/_deprecated/trading-utils.js +27 -0
- package/lib/_deprecated/trading-utils.js.map +1 -0
- package/lib/_deprecated/user-utils.d.ts +17 -0
- package/lib/_deprecated/user-utils.js +12 -0
- package/lib/_deprecated/user-utils.js.map +1 -0
- package/lib/_deprecated/utils.d.ts +40 -0
- package/lib/_deprecated/utils.js +47 -0
- package/lib/_deprecated/utils.js.map +1 -0
- package/lib/clients/tvFeed.js +2 -2
- package/lib/clients/tvFeed.js.map +1 -1
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js +8 -8
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js.map +1 -1
- package/lib/drift/Drift/clients/AuthorityDrift/index.js +9 -9
- package/lib/drift/Drift/clients/AuthorityDrift/index.js.map +1 -1
- package/lib/drift/Drift/clients/CentralServerDrift/index.js +5 -4
- package/lib/drift/Drift/clients/CentralServerDrift/index.js.map +1 -1
- package/lib/drift/base/actions/trade/editOrder.d.ts +1 -1
- package/lib/drift/base/actions/trade/editOrder.js.map +1 -1
- package/lib/drift/base/actions/trade/margin.js +4 -4
- package/lib/drift/base/actions/trade/margin.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/auction.d.ts +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/auction.js +4 -3
- package/lib/drift/base/actions/trade/openPerpOrder/auction.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/dlobServer/index.js +2 -2
- package/lib/drift/base/actions/trade/openPerpOrder/dlobServer/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/isolatedPositionDeposit.js +2 -2
- package/lib/drift/base/actions/trade/openPerpOrder/isolatedPositionDeposit.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.d.ts +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js +4 -4
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.d.ts +4 -4
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js +60 -32
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js +4 -3
- package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/positionMaxLeverage.js +2 -2
- package/lib/drift/base/actions/trade/openPerpOrder/positionMaxLeverage.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/types.d.ts +5 -0
- package/lib/drift/base/actions/trade/openPerpOrder/types.js.map +1 -1
- package/lib/drift/base/actions/user/create.js +2 -2
- package/lib/drift/base/actions/user/create.js.map +1 -1
- package/lib/drift/base/details/user/balances.js +2 -2
- package/lib/drift/base/details/user/balances.js.map +1 -1
- package/lib/drift/base/details/user/positions.js +2 -2
- package/lib/drift/base/details/user/positions.js.map +1 -1
- package/lib/index.d.ts +28 -28
- package/lib/index.js +44 -29
- package/lib/index.js.map +1 -1
- package/lib/utils/accounts/index.d.ts +6 -0
- package/lib/utils/accounts/index.js +23 -0
- package/lib/utils/accounts/index.js.map +1 -0
- package/lib/utils/accounts/init.d.ts +22 -0
- package/lib/utils/accounts/init.js +90 -0
- package/lib/utils/accounts/init.js.map +1 -0
- package/lib/utils/accounts/keys.d.ts +22 -0
- package/lib/utils/accounts/keys.js +36 -0
- package/lib/utils/accounts/keys.js.map +1 -0
- package/lib/utils/accounts/multiple.d.ts +14 -0
- package/lib/utils/accounts/multiple.js +45 -0
- package/lib/utils/accounts/multiple.js.map +1 -0
- package/lib/utils/accounts/signature.d.ts +6 -0
- package/lib/utils/accounts/signature.js +53 -0
- package/lib/utils/accounts/signature.js.map +1 -0
- package/lib/utils/accounts/subaccounts.d.ts +8 -0
- package/lib/utils/accounts/subaccounts.js +31 -0
- package/lib/utils/accounts/subaccounts.js.map +1 -0
- package/lib/utils/{WalletConnectionState.d.ts → accounts/wallet.d.ts} +7 -1
- package/lib/utils/{WalletConnectionState.js → accounts/wallet.js} +32 -2
- package/lib/utils/accounts/wallet.js.map +1 -0
- package/lib/utils/core/arrays.d.ts +2 -0
- package/lib/utils/core/arrays.js +25 -0
- package/lib/utils/core/arrays.js.map +1 -0
- package/lib/utils/core/async.d.ts +5 -0
- package/lib/utils/core/async.js +17 -0
- package/lib/utils/core/async.js.map +1 -0
- package/lib/utils/core/cache.d.ts +1 -0
- package/lib/utils/core/cache.js +40 -0
- package/lib/utils/core/cache.js.map +1 -0
- package/lib/utils/core/data-structures.d.ts +30 -0
- package/lib/utils/core/data-structures.js +84 -0
- package/lib/utils/core/data-structures.js.map +1 -0
- package/lib/utils/{equalityChecks.d.ts → core/equality.d.ts} +1 -1
- package/lib/utils/{equalityChecks.js → core/equality.js} +3 -3
- package/lib/utils/core/equality.js.map +1 -0
- package/lib/utils/core/fetch.js.map +1 -0
- package/lib/utils/core/index.d.ts +7 -0
- package/lib/utils/core/index.js +24 -0
- package/lib/utils/core/index.js.map +1 -0
- package/lib/utils/core/serialization.d.ts +30 -0
- package/lib/utils/core/serialization.js +92 -0
- package/lib/utils/core/serialization.js.map +1 -0
- package/lib/utils/{enum.js → enum/index.js} +1 -1
- package/lib/utils/enum/index.js.map +1 -0
- package/lib/utils/index.d.ts +11 -176
- package/lib/utils/index.js +25 -594
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/markets/balances.d.ts +6 -0
- package/lib/utils/markets/balances.js +29 -0
- package/lib/utils/markets/balances.js.map +1 -0
- package/lib/utils/markets/config.d.ts +5 -0
- package/lib/utils/markets/config.js +24 -0
- package/lib/utils/markets/config.js.map +1 -0
- package/lib/utils/markets/index.d.ts +6 -0
- package/lib/utils/markets/index.js +23 -0
- package/lib/utils/markets/index.js.map +1 -0
- package/lib/utils/markets/interest.d.ts +25 -0
- package/lib/utils/markets/interest.js +65 -0
- package/lib/utils/markets/interest.js.map +1 -0
- package/lib/utils/markets/leverage.d.ts +12 -0
- package/lib/utils/markets/leverage.js +60 -0
- package/lib/utils/markets/leverage.js.map +1 -0
- package/lib/utils/markets/operations.d.ts +21 -0
- package/lib/utils/markets/operations.js +59 -0
- package/lib/utils/markets/operations.js.map +1 -0
- package/lib/utils/math/bignum.d.ts +3 -0
- package/lib/utils/math/bignum.js +16 -0
- package/lib/utils/math/bignum.js.map +1 -0
- package/lib/utils/math/bn.d.ts +7 -0
- package/lib/utils/math/bn.js +58 -0
- package/lib/utils/math/bn.js.map +1 -0
- package/lib/utils/math/index.d.ts +7 -0
- package/lib/utils/math/index.js +24 -0
- package/lib/utils/math/index.js.map +1 -0
- package/lib/utils/math/numbers.d.ts +13 -0
- package/lib/utils/math/numbers.js +56 -0
- package/lib/utils/math/numbers.js.map +1 -0
- package/lib/utils/math/precision.d.ts +19 -0
- package/lib/utils/math/precision.js +73 -0
- package/lib/utils/math/precision.js.map +1 -0
- package/lib/utils/math/price.d.ts +12 -0
- package/lib/utils/math/price.js +45 -0
- package/lib/utils/math/price.js.map +1 -0
- package/lib/utils/math/sort.d.ts +13 -0
- package/lib/utils/math/sort.js +33 -0
- package/lib/utils/math/sort.js.map +1 -0
- package/lib/utils/math/spread.d.ts +8 -0
- package/lib/utils/math/spread.js +87 -0
- package/lib/utils/math/spread.js.map +1 -0
- package/lib/utils/orderbook/index.js +4 -4
- package/lib/utils/orderbook/index.js.map +1 -1
- package/lib/utils/orders/filters.d.ts +7 -0
- package/lib/utils/orders/filters.js +31 -0
- package/lib/utils/orders/filters.js.map +1 -0
- package/lib/utils/orders/flags.d.ts +12 -0
- package/lib/utils/orders/flags.js +44 -0
- package/lib/utils/orders/flags.js.map +1 -0
- package/lib/utils/orders/index.d.ts +6 -0
- package/lib/utils/orders/index.js +23 -0
- package/lib/utils/orders/index.js.map +1 -0
- package/lib/utils/orders/labels.d.ts +4 -0
- package/lib/utils/orders/labels.js +122 -0
- package/lib/utils/orders/labels.js.map +1 -0
- package/lib/utils/orders/misc.d.ts +11 -0
- package/lib/utils/orders/misc.js +27 -0
- package/lib/utils/orders/misc.js.map +1 -0
- package/lib/utils/orders/oracle.d.ts +5 -0
- package/lib/utils/orders/oracle.js +23 -0
- package/lib/utils/orders/oracle.js.map +1 -0
- package/lib/utils/orders/sort.d.ts +38 -0
- package/lib/utils/orders/sort.js +83 -0
- package/lib/utils/orders/sort.js.map +1 -0
- package/lib/utils/positions/index.d.ts +2 -0
- package/lib/{common-ui-utils → utils/positions}/index.js +1 -5
- package/lib/utils/positions/index.js.map +1 -0
- package/lib/utils/positions/open.d.ts +4 -0
- package/lib/{common-ui-utils/user.js → utils/positions/open.js} +10 -81
- package/lib/utils/positions/open.js.map +1 -0
- package/lib/utils/positions/user.d.ts +37 -0
- package/lib/utils/positions/user.js +74 -0
- package/lib/utils/positions/user.js.map +1 -0
- package/lib/utils/settings/settings.js.map +1 -0
- package/lib/utils/strings/convert.d.ts +11 -0
- package/lib/utils/{strings.js → strings/convert.js} +2 -51
- package/lib/utils/strings/convert.js.map +1 -0
- package/lib/utils/strings/format.d.ts +14 -0
- package/lib/utils/strings/format.js +61 -0
- package/lib/utils/strings/format.js.map +1 -0
- package/lib/utils/strings/index.d.ts +4 -0
- package/lib/utils/strings/index.js +21 -0
- package/lib/utils/strings/index.js.map +1 -0
- package/lib/utils/strings/parse.d.ts +4 -0
- package/lib/utils/strings/parse.js +25 -0
- package/lib/utils/strings/parse.js.map +1 -0
- package/lib/utils/strings/status.d.ts +15 -0
- package/lib/utils/strings/status.js +21 -0
- package/lib/utils/strings/status.js.map +1 -0
- package/lib/utils/token/account.d.ts +16 -0
- package/lib/utils/token/account.js +36 -0
- package/lib/utils/token/account.js.map +1 -0
- package/lib/utils/{token.d.ts → token/address.d.ts} +2 -7
- package/lib/utils/token/address.js +30 -0
- package/lib/utils/token/address.js.map +1 -0
- package/lib/utils/token/index.d.ts +3 -0
- package/lib/utils/token/index.js +20 -0
- package/lib/utils/token/index.js.map +1 -0
- package/lib/utils/token/instructions.d.ts +3 -0
- package/lib/utils/token/instructions.js +17 -0
- package/lib/utils/token/instructions.js.map +1 -0
- package/lib/utils/trading/auction.d.ts +82 -0
- package/lib/utils/trading/auction.js +208 -0
- package/lib/utils/trading/auction.js.map +1 -0
- package/lib/utils/trading/index.d.ts +7 -0
- package/lib/utils/trading/index.js +24 -0
- package/lib/utils/trading/index.js.map +1 -0
- package/lib/utils/trading/leverage.d.ts +18 -0
- package/lib/utils/trading/leverage.js +79 -0
- package/lib/utils/trading/leverage.js.map +1 -0
- package/lib/utils/trading/liquidation.d.ts +22 -0
- package/lib/utils/trading/liquidation.js +67 -0
- package/lib/utils/trading/liquidation.js.map +1 -0
- package/lib/utils/trading/lp.d.ts +4 -0
- package/lib/utils/trading/lp.js +20 -0
- package/lib/utils/trading/lp.js.map +1 -0
- package/lib/utils/trading/pnl.d.ts +34 -0
- package/lib/utils/trading/pnl.js +88 -0
- package/lib/utils/trading/pnl.js.map +1 -0
- package/lib/utils/trading/price.d.ts +12 -0
- package/lib/utils/trading/price.js +36 -0
- package/lib/utils/trading/price.js.map +1 -0
- package/lib/utils/trading/size.d.ts +27 -0
- package/lib/utils/trading/size.js +83 -0
- package/lib/utils/trading/size.js.map +1 -0
- package/lib/utils/{validation.d.ts → validation/address.d.ts} +1 -2
- package/lib/utils/{validation.js → validation/address.js} +4 -6
- package/lib/utils/validation/address.js.map +1 -0
- package/lib/utils/validation/index.d.ts +3 -0
- package/lib/utils/validation/index.js +20 -0
- package/lib/utils/validation/index.js.map +1 -0
- package/lib/utils/validation/input.d.ts +3 -0
- package/lib/utils/validation/input.js +33 -0
- package/lib/utils/validation/input.js.map +1 -0
- package/lib/utils/validation/notional.d.ts +2 -0
- package/lib/utils/validation/notional.js +8 -0
- package/lib/utils/validation/notional.js.map +1 -0
- package/package.json +90 -3
- package/lib/common-ui-utils/commonUiUtils.d.ts +0 -251
- package/lib/common-ui-utils/commonUiUtils.js +0 -647
- package/lib/common-ui-utils/commonUiUtils.js.map +0 -1
- package/lib/common-ui-utils/index.d.ts +0 -6
- package/lib/common-ui-utils/index.js.map +0 -1
- package/lib/common-ui-utils/market.js +0 -134
- package/lib/common-ui-utils/market.js.map +0 -1
- package/lib/common-ui-utils/order.d.ts +0 -25
- package/lib/common-ui-utils/order.js +0 -191
- package/lib/common-ui-utils/order.js.map +0 -1
- package/lib/common-ui-utils/settings/settings.js.map +0 -1
- package/lib/common-ui-utils/trading.d.ts +0 -79
- package/lib/common-ui-utils/trading.js +0 -313
- package/lib/common-ui-utils/trading.js.map +0 -1
- package/lib/common-ui-utils/user.d.ts +0 -18
- package/lib/common-ui-utils/user.js.map +0 -1
- package/lib/utils/WalletConnectionState.js.map +0 -1
- package/lib/utils/enum.js.map +0 -1
- package/lib/utils/equalityChecks.js.map +0 -1
- package/lib/utils/fetch.js.map +0 -1
- package/lib/utils/math.d.ts +0 -31
- package/lib/utils/math.js +0 -181
- package/lib/utils/math.js.map +0 -1
- package/lib/utils/strings.d.ts +0 -34
- package/lib/utils/strings.js.map +0 -1
- package/lib/utils/token.js +0 -45
- package/lib/utils/token.js.map +0 -1
- package/lib/utils/validation.js.map +0 -1
- /package/lib/utils/{fetch.d.ts → core/fetch.d.ts} +0 -0
- /package/lib/utils/{fetch.js → core/fetch.js} +0 -0
- /package/lib/utils/{enum.d.ts → enum/index.d.ts} +0 -0
- /package/lib/{common-ui-utils → utils}/settings/settings.d.ts +0 -0
- /package/lib/{common-ui-utils → utils}/settings/settings.js +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./auction"), exports);
|
|
18
|
+
__exportStar(require("./leverage"), exports);
|
|
19
|
+
__exportStar(require("./liquidation"), exports);
|
|
20
|
+
__exportStar(require("./lp"), exports);
|
|
21
|
+
__exportStar(require("./pnl"), exports);
|
|
22
|
+
__exportStar(require("./price"), exports);
|
|
23
|
+
__exportStar(require("./size"), exports);
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/trading/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,6CAA2B;AAC3B,gDAA8B;AAC9B,uCAAqB;AACrB,wCAAsB;AACtB,0CAAwB;AACxB,yCAAuB","sourcesContent":["export * from './auction';\nexport * from './leverage';\nexport * from './liquidation';\nexport * from './lp';\nexport * from './pnl';\nexport * from './price';\nexport * from './size';\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BN, User } from '@drift-labs/sdk';
|
|
2
|
+
declare const convertLeverageToMarginRatio: (leverage: number) => number | undefined;
|
|
3
|
+
declare const convertMarginRatioToLeverage: (marginRatio: number, decimals?: number) => number | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Calculate the margin used for a specific perp position
|
|
6
|
+
* Returns the minimum of user's total collateral or the position's weighted value
|
|
7
|
+
*/
|
|
8
|
+
declare const getMarginUsedForPosition: (user: User, marketIndex: number, includeOpenOrders?: boolean) => BN | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Validate if a leverage change would exceed the user's free collateral
|
|
11
|
+
* Returns true if the change is valid (doesn't exceed free collateral), false otherwise
|
|
12
|
+
*/
|
|
13
|
+
declare const validateLeverageChange: ({ user, marketIndex, newLeverage, }: {
|
|
14
|
+
user: User;
|
|
15
|
+
marketIndex: number;
|
|
16
|
+
newLeverage: number;
|
|
17
|
+
}) => boolean;
|
|
18
|
+
export { convertLeverageToMarginRatio, convertMarginRatioToLeverage, getMarginUsedForPosition, validateLeverageChange, };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateLeverageChange = exports.getMarginUsedForPosition = exports.convertMarginRatioToLeverage = exports.convertLeverageToMarginRatio = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const convertLeverageToMarginRatio = (leverage) => {
|
|
6
|
+
if (!leverage)
|
|
7
|
+
return undefined;
|
|
8
|
+
return Math.round((1 / leverage) * sdk_1.MARGIN_PRECISION.toNumber());
|
|
9
|
+
};
|
|
10
|
+
exports.convertLeverageToMarginRatio = convertLeverageToMarginRatio;
|
|
11
|
+
const convertMarginRatioToLeverage = (marginRatio, decimals) => {
|
|
12
|
+
if (!marginRatio)
|
|
13
|
+
return undefined;
|
|
14
|
+
const leverage = 1 / (marginRatio / sdk_1.MARGIN_PRECISION.toNumber());
|
|
15
|
+
return decimals
|
|
16
|
+
? parseFloat(leverage.toFixed(decimals))
|
|
17
|
+
: Math.round(leverage);
|
|
18
|
+
};
|
|
19
|
+
exports.convertMarginRatioToLeverage = convertMarginRatioToLeverage;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate the margin used for a specific perp position
|
|
22
|
+
* Returns the minimum of user's total collateral or the position's weighted value
|
|
23
|
+
*/
|
|
24
|
+
const getMarginUsedForPosition = (user, marketIndex, includeOpenOrders = true) => {
|
|
25
|
+
const perpPosition = user.getPerpPosition(marketIndex);
|
|
26
|
+
if (!perpPosition)
|
|
27
|
+
return undefined;
|
|
28
|
+
const hc = user.getPerpPositionHealth({
|
|
29
|
+
marginCategory: 'Initial',
|
|
30
|
+
perpPosition,
|
|
31
|
+
includeOpenOrders,
|
|
32
|
+
});
|
|
33
|
+
const userCollateral = user.getTotalCollateral();
|
|
34
|
+
return userCollateral.lt(hc.weightedValue)
|
|
35
|
+
? userCollateral
|
|
36
|
+
: hc.weightedValue;
|
|
37
|
+
};
|
|
38
|
+
exports.getMarginUsedForPosition = getMarginUsedForPosition;
|
|
39
|
+
/**
|
|
40
|
+
* Validate if a leverage change would exceed the user's free collateral
|
|
41
|
+
* Returns true if the change is valid (doesn't exceed free collateral), false otherwise
|
|
42
|
+
*/
|
|
43
|
+
const validateLeverageChange = ({ user, marketIndex, newLeverage, }) => {
|
|
44
|
+
try {
|
|
45
|
+
// Convert leverage to margin ratio
|
|
46
|
+
const newMarginRatio = convertLeverageToMarginRatio(newLeverage);
|
|
47
|
+
if (!newMarginRatio)
|
|
48
|
+
return true;
|
|
49
|
+
// Get the perp position from the user
|
|
50
|
+
const perpPosition = user.getPerpPosition(marketIndex);
|
|
51
|
+
if (!perpPosition)
|
|
52
|
+
return true;
|
|
53
|
+
// Get current position weighted value
|
|
54
|
+
const currentPositionWeightedValue = user.getPerpPositionHealth({
|
|
55
|
+
marginCategory: 'Initial',
|
|
56
|
+
perpPosition,
|
|
57
|
+
}).weightedValue;
|
|
58
|
+
// Create a modified version of the position with new maxMarginRatio
|
|
59
|
+
const modifiedPosition = {
|
|
60
|
+
...perpPosition,
|
|
61
|
+
maxMarginRatio: newMarginRatio,
|
|
62
|
+
};
|
|
63
|
+
// Calculate new weighted value with the modified position
|
|
64
|
+
const newPositionWeightedValue = user.getPerpPositionHealth({
|
|
65
|
+
marginCategory: 'Initial',
|
|
66
|
+
perpPosition: modifiedPosition,
|
|
67
|
+
}).weightedValue;
|
|
68
|
+
const perpPositionWeightedValueDelta = newPositionWeightedValue.sub(currentPositionWeightedValue);
|
|
69
|
+
const freeCollateral = user.getFreeCollateral();
|
|
70
|
+
// Check if weighted value delta exceeds free collateral
|
|
71
|
+
return perpPositionWeightedValueDelta.lte(freeCollateral);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.warn('Error validating leverage change:', error);
|
|
75
|
+
return true; // Allow change if validation fails
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
exports.validateLeverageChange = validateLeverageChange;
|
|
79
|
+
//# sourceMappingURL=leverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leverage.js","sourceRoot":"","sources":["../../../src/utils/trading/leverage.ts"],"names":[],"mappings":"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","sourcesContent":["import { BN, MARGIN_PRECISION, User } from '@drift-labs/sdk';\n\nconst convertLeverageToMarginRatio = (leverage: number): number | undefined => {\n\tif (!leverage) return undefined;\n\treturn Math.round((1 / leverage) * MARGIN_PRECISION.toNumber());\n};\n\nconst convertMarginRatioToLeverage = (\n\tmarginRatio: number,\n\tdecimals?: number\n): number | undefined => {\n\tif (!marginRatio) return undefined;\n\n\tconst leverage = 1 / (marginRatio / MARGIN_PRECISION.toNumber());\n\n\treturn decimals\n\t\t? parseFloat(leverage.toFixed(decimals))\n\t\t: Math.round(leverage);\n};\n\n/**\n * Calculate the margin used for a specific perp position\n * Returns the minimum of user's total collateral or the position's weighted value\n */\nconst getMarginUsedForPosition = (\n\tuser: User,\n\tmarketIndex: number,\n\tincludeOpenOrders = true\n): BN | undefined => {\n\tconst perpPosition = user.getPerpPosition(marketIndex);\n\tif (!perpPosition) return undefined;\n\n\tconst hc = user.getPerpPositionHealth({\n\t\tmarginCategory: 'Initial',\n\t\tperpPosition,\n\t\tincludeOpenOrders,\n\t});\n\tconst userCollateral = user.getTotalCollateral();\n\treturn userCollateral.lt(hc.weightedValue)\n\t\t? userCollateral\n\t\t: hc.weightedValue;\n};\n\n/**\n * Validate if a leverage change would exceed the user's free collateral\n * Returns true if the change is valid (doesn't exceed free collateral), false otherwise\n */\nconst validateLeverageChange = ({\n\tuser,\n\tmarketIndex,\n\tnewLeverage,\n}: {\n\tuser: User;\n\tmarketIndex: number;\n\tnewLeverage: number;\n}): boolean => {\n\ttry {\n\t\t// Convert leverage to margin ratio\n\t\tconst newMarginRatio = convertLeverageToMarginRatio(newLeverage);\n\t\tif (!newMarginRatio) return true;\n\n\t\t// Get the perp position from the user\n\t\tconst perpPosition = user.getPerpPosition(marketIndex);\n\t\tif (!perpPosition) return true;\n\n\t\t// Get current position weighted value\n\t\tconst currentPositionWeightedValue = user.getPerpPositionHealth({\n\t\t\tmarginCategory: 'Initial',\n\t\t\tperpPosition,\n\t\t}).weightedValue;\n\n\t\t// Create a modified version of the position with new maxMarginRatio\n\t\tconst modifiedPosition = {\n\t\t\t...perpPosition,\n\t\t\tmaxMarginRatio: newMarginRatio,\n\t\t};\n\n\t\t// Calculate new weighted value with the modified position\n\t\tconst newPositionWeightedValue = user.getPerpPositionHealth({\n\t\t\tmarginCategory: 'Initial',\n\t\t\tperpPosition: modifiedPosition,\n\t\t}).weightedValue;\n\n\t\tconst perpPositionWeightedValueDelta = newPositionWeightedValue.sub(\n\t\t\tcurrentPositionWeightedValue\n\t\t);\n\n\t\tconst freeCollateral = user.getFreeCollateral();\n\n\t\t// Check if weighted value delta exceeds free collateral\n\t\treturn perpPositionWeightedValueDelta.lte(freeCollateral);\n\t} catch (error) {\n\t\tconsole.warn('Error validating leverage change:', error);\n\t\treturn true; // Allow change if validation fails\n\t}\n};\n\nexport {\n\tconvertLeverageToMarginRatio,\n\tconvertMarginRatioToLeverage,\n\tgetMarginUsedForPosition,\n\tvalidateLeverageChange,\n};\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BN, User } from '@drift-labs/sdk';
|
|
2
|
+
import { UIOrderType } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Calculate the liquidation price of a position after a trade. Requires DriftClient to be subscribed.
|
|
5
|
+
* If the order type is limit order, a limit price must be provided.
|
|
6
|
+
*/
|
|
7
|
+
declare const calculateLiquidationPriceAfterPerpTrade: ({ estEntryPrice, orderType, perpMarketIndex, tradeBaseSize, isLong, userClient, oraclePrice, limitPrice, offsetCollateral, precision, isEnteringHighLeverageMode, capLiqPrice, marginType, }: {
|
|
8
|
+
estEntryPrice: BN;
|
|
9
|
+
orderType: UIOrderType;
|
|
10
|
+
perpMarketIndex: number;
|
|
11
|
+
tradeBaseSize: BN;
|
|
12
|
+
isLong: boolean;
|
|
13
|
+
userClient: User;
|
|
14
|
+
oraclePrice: BN;
|
|
15
|
+
limitPrice?: BN;
|
|
16
|
+
offsetCollateral?: BN;
|
|
17
|
+
precision?: number;
|
|
18
|
+
isEnteringHighLeverageMode?: boolean;
|
|
19
|
+
capLiqPrice?: boolean;
|
|
20
|
+
marginType?: 'Cross' | 'Isolated';
|
|
21
|
+
}) => number;
|
|
22
|
+
export { calculateLiquidationPriceAfterPerpTrade };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateLiquidationPriceAfterPerpTrade = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
/**
|
|
6
|
+
* Calculate the liquidation price of a position after a trade. Requires DriftClient to be subscribed.
|
|
7
|
+
* If the order type is limit order, a limit price must be provided.
|
|
8
|
+
*/
|
|
9
|
+
const calculateLiquidationPriceAfterPerpTrade = ({ estEntryPrice, orderType, perpMarketIndex, tradeBaseSize, isLong, userClient, oraclePrice, limitPrice, offsetCollateral, precision = 2, isEnteringHighLeverageMode, capLiqPrice, marginType, }) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const ALLOWED_ORDER_TYPES = [
|
|
12
|
+
'limit',
|
|
13
|
+
'market',
|
|
14
|
+
'oracle',
|
|
15
|
+
'stopMarket',
|
|
16
|
+
'stopLimit',
|
|
17
|
+
'oracleLimit',
|
|
18
|
+
];
|
|
19
|
+
if (!ALLOWED_ORDER_TYPES.includes(orderType)) {
|
|
20
|
+
console.error('Invalid order type for perp trade liquidation price calculation', orderType);
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
if (orderType === 'limit' && !limitPrice) {
|
|
24
|
+
console.error('Limit order must have a limit price for perp trade liquidation price calculation');
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
const signedBaseSize = isLong ? tradeBaseSize : tradeBaseSize.neg();
|
|
28
|
+
const priceToUse = [
|
|
29
|
+
'limit',
|
|
30
|
+
'stopMarket',
|
|
31
|
+
'stopLimit',
|
|
32
|
+
'oracleLimit',
|
|
33
|
+
].includes(orderType)
|
|
34
|
+
? limitPrice
|
|
35
|
+
: estEntryPrice;
|
|
36
|
+
const liqPriceBn = userClient.liquidationPrice(perpMarketIndex, signedBaseSize, priceToUse, undefined, undefined, // we can exclude open orders since open orders will be cancelled first (which results in reducing account leverage) before actual liquidation
|
|
37
|
+
offsetCollateral, isEnteringHighLeverageMode, marginType === 'Isolated' ? 'Isolated' : undefined);
|
|
38
|
+
if (liqPriceBn.isNeg()) {
|
|
39
|
+
// means no liquidation price
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
// Check if user has a spot position using the same oracle as the perp market
|
|
43
|
+
// If so, force capLiqPrice to be false to avoid incorrect price capping
|
|
44
|
+
// Technically in this case, liq price could be lower for a short or higher for a long
|
|
45
|
+
const perpMarketOracle = (_b = (_a = userClient.driftClient.getPerpMarketAccount(perpMarketIndex)) === null || _a === void 0 ? void 0 : _a.amm) === null || _b === void 0 ? void 0 : _b.oracle;
|
|
46
|
+
const spotMarketWithSameOracle = userClient.driftClient
|
|
47
|
+
.getSpotMarketAccounts()
|
|
48
|
+
.find((market) => market.oracle.equals(perpMarketOracle));
|
|
49
|
+
let hasSpotPositionWithSameOracle = false;
|
|
50
|
+
if (spotMarketWithSameOracle) {
|
|
51
|
+
const spotPosition = userClient.getSpotPosition(spotMarketWithSameOracle.marketIndex);
|
|
52
|
+
hasSpotPositionWithSameOracle = !!spotPosition;
|
|
53
|
+
}
|
|
54
|
+
const effectiveCapLiqPrice = hasSpotPositionWithSameOracle
|
|
55
|
+
? false
|
|
56
|
+
: capLiqPrice;
|
|
57
|
+
const cappedLiqPriceBn = effectiveCapLiqPrice
|
|
58
|
+
? isLong
|
|
59
|
+
? sdk_1.BN.min(liqPriceBn, oraclePrice)
|
|
60
|
+
: sdk_1.BN.max(liqPriceBn, oraclePrice)
|
|
61
|
+
: liqPriceBn;
|
|
62
|
+
const liqPriceBigNum = sdk_1.BigNum.from(cappedLiqPriceBn, sdk_1.PRICE_PRECISION_EXP);
|
|
63
|
+
const liqPriceNum = Math.round(liqPriceBigNum.toNum() * 10 ** precision) / 10 ** precision;
|
|
64
|
+
return liqPriceNum;
|
|
65
|
+
};
|
|
66
|
+
exports.calculateLiquidationPriceAfterPerpTrade = calculateLiquidationPriceAfterPerpTrade;
|
|
67
|
+
//# sourceMappingURL=liquidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liquidation.js","sourceRoot":"","sources":["../../../src/utils/trading/liquidation.ts"],"names":[],"mappings":"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","sourcesContent":["import { BN, BigNum, PRICE_PRECISION_EXP, User } from '@drift-labs/sdk';\nimport { UIOrderType } from '../../types';\n\n/**\n * Calculate the liquidation price of a position after a trade. Requires DriftClient to be subscribed.\n * If the order type is limit order, a limit price must be provided.\n */\nconst calculateLiquidationPriceAfterPerpTrade = ({\n\testEntryPrice,\n\torderType,\n\tperpMarketIndex,\n\ttradeBaseSize,\n\tisLong,\n\tuserClient,\n\toraclePrice,\n\tlimitPrice,\n\toffsetCollateral,\n\tprecision = 2,\n\tisEnteringHighLeverageMode,\n\tcapLiqPrice,\n\tmarginType,\n}: {\n\testEntryPrice: BN;\n\torderType: UIOrderType;\n\tperpMarketIndex: number;\n\ttradeBaseSize: BN;\n\tisLong: boolean;\n\tuserClient: User;\n\toraclePrice: BN;\n\tlimitPrice?: BN;\n\toffsetCollateral?: BN;\n\tprecision?: number;\n\tisEnteringHighLeverageMode?: boolean;\n\tcapLiqPrice?: boolean;\n\tmarginType?: 'Cross' | 'Isolated';\n}) => {\n\tconst ALLOWED_ORDER_TYPES: UIOrderType[] = [\n\t\t'limit',\n\t\t'market',\n\t\t'oracle',\n\t\t'stopMarket',\n\t\t'stopLimit',\n\t\t'oracleLimit',\n\t];\n\n\tif (!ALLOWED_ORDER_TYPES.includes(orderType)) {\n\t\tconsole.error(\n\t\t\t'Invalid order type for perp trade liquidation price calculation',\n\t\t\torderType\n\t\t);\n\t\treturn 0;\n\t}\n\n\tif (orderType === 'limit' && !limitPrice) {\n\t\tconsole.error(\n\t\t\t'Limit order must have a limit price for perp trade liquidation price calculation'\n\t\t);\n\t\treturn 0;\n\t}\n\n\tconst signedBaseSize = isLong ? tradeBaseSize : tradeBaseSize.neg();\n\tconst priceToUse = [\n\t\t'limit',\n\t\t'stopMarket',\n\t\t'stopLimit',\n\t\t'oracleLimit',\n\t].includes(orderType)\n\t\t? limitPrice\n\t\t: estEntryPrice;\n\n\tconst liqPriceBn = userClient.liquidationPrice(\n\t\tperpMarketIndex,\n\t\tsignedBaseSize,\n\t\tpriceToUse,\n\t\tundefined,\n\t\tundefined, // we can exclude open orders since open orders will be cancelled first (which results in reducing account leverage) before actual liquidation\n\t\toffsetCollateral,\n\t\tisEnteringHighLeverageMode,\n\t\tmarginType === 'Isolated' ? 'Isolated' : undefined\n\t);\n\n\tif (liqPriceBn.isNeg()) {\n\t\t// means no liquidation price\n\t\treturn 0;\n\t}\n\n\t// Check if user has a spot position using the same oracle as the perp market\n\t// If so, force capLiqPrice to be false to avoid incorrect price capping\n\t// Technically in this case, liq price could be lower for a short or higher for a long\n\tconst perpMarketOracle =\n\t\tuserClient.driftClient.getPerpMarketAccount(perpMarketIndex)?.amm?.oracle;\n\n\tconst spotMarketWithSameOracle = userClient.driftClient\n\t\t.getSpotMarketAccounts()\n\t\t.find((market) => market.oracle.equals(perpMarketOracle));\n\n\tlet hasSpotPositionWithSameOracle = false;\n\tif (spotMarketWithSameOracle) {\n\t\tconst spotPosition = userClient.getSpotPosition(\n\t\t\tspotMarketWithSameOracle.marketIndex\n\t\t);\n\t\thasSpotPositionWithSameOracle = !!spotPosition;\n\t}\n\n\tconst effectiveCapLiqPrice = hasSpotPositionWithSameOracle\n\t\t? false\n\t\t: capLiqPrice;\n\n\tconst cappedLiqPriceBn = effectiveCapLiqPrice\n\t\t? isLong\n\t\t\t? BN.min(liqPriceBn, oraclePrice)\n\t\t\t: BN.max(liqPriceBn, oraclePrice)\n\t\t: liqPriceBn;\n\n\tconst liqPriceBigNum = BigNum.from(cappedLiqPriceBn, PRICE_PRECISION_EXP);\n\n\tconst liqPriceNum =\n\t\tMath.round(liqPriceBigNum.toNum() * 10 ** precision) / 10 ** precision;\n\n\treturn liqPriceNum;\n};\n\nexport { calculateLiquidationPriceAfterPerpTrade };\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BigNum, DriftClient } from '@drift-labs/sdk';
|
|
2
|
+
declare const getLpSharesAmountForQuote: (driftClient: DriftClient, marketIndex: number, quoteAmount: BN) => BigNum;
|
|
3
|
+
declare const getQuoteValueForLpShares: (driftClient: DriftClient, marketIndex: number, sharesAmount: BN) => BigNum;
|
|
4
|
+
export { getLpSharesAmountForQuote, getQuoteValueForLpShares };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getQuoteValueForLpShares = exports.getLpSharesAmountForQuote = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
/* LP Utils */
|
|
6
|
+
const getLpSharesAmountForQuote = (driftClient, marketIndex, quoteAmount) => {
|
|
7
|
+
const tenMillionBigNum = sdk_1.BigNum.fromPrint('10000000', sdk_1.QUOTE_PRECISION_EXP);
|
|
8
|
+
const pricePerLpShare = sdk_1.BigNum.from(driftClient.getQuoteValuePerLpShare(marketIndex), sdk_1.QUOTE_PRECISION_EXP);
|
|
9
|
+
return sdk_1.BigNum.from(quoteAmount, sdk_1.QUOTE_PRECISION_EXP)
|
|
10
|
+
.scale(tenMillionBigNum.toNum(), pricePerLpShare.mul(tenMillionBigNum).toNum())
|
|
11
|
+
.shiftTo(sdk_1.AMM_RESERVE_PRECISION_EXP);
|
|
12
|
+
};
|
|
13
|
+
exports.getLpSharesAmountForQuote = getLpSharesAmountForQuote;
|
|
14
|
+
const getQuoteValueForLpShares = (driftClient, marketIndex, sharesAmount) => {
|
|
15
|
+
const pricePerLpShare = sdk_1.BigNum.from(driftClient.getQuoteValuePerLpShare(marketIndex), sdk_1.QUOTE_PRECISION_EXP).shiftTo(sdk_1.AMM_RESERVE_PRECISION_EXP);
|
|
16
|
+
const lpSharesBigNum = sdk_1.BigNum.from(sharesAmount, sdk_1.AMM_RESERVE_PRECISION_EXP);
|
|
17
|
+
return lpSharesBigNum.mul(pricePerLpShare).shiftTo(sdk_1.QUOTE_PRECISION_EXP);
|
|
18
|
+
};
|
|
19
|
+
exports.getQuoteValueForLpShares = getQuoteValueForLpShares;
|
|
20
|
+
//# sourceMappingURL=lp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lp.js","sourceRoot":"","sources":["../../../src/utils/trading/lp.ts"],"names":[],"mappings":";;;AAAA,yCAMyB;AAEzB,cAAc;AACd,MAAM,yBAAyB,GAAG,CACjC,WAAwB,EACxB,WAAmB,EACnB,WAAe,EACN,EAAE;IACX,MAAM,gBAAgB,GAAG,YAAM,CAAC,SAAS,CAAC,UAAU,EAAE,yBAAmB,CAAC,CAAC;IAE3E,MAAM,eAAe,GAAG,YAAM,CAAC,IAAI,CAClC,WAAW,CAAC,uBAAuB,CAAC,WAAW,CAAC,EAChD,yBAAmB,CACnB,CAAC;IAEF,OAAO,YAAM,CAAC,IAAI,CAAC,WAAW,EAAE,yBAAmB,CAAC;SAClD,KAAK,CACL,gBAAgB,CAAC,KAAK,EAAE,EACxB,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAC7C;SACA,OAAO,CAAC,+BAAyB,CAAC,CAAC;AACtC,CAAC,CAAC;AAeO,8DAAyB;AAblC,MAAM,wBAAwB,GAAG,CAChC,WAAwB,EACxB,WAAmB,EACnB,YAAgB,EACP,EAAE;IACX,MAAM,eAAe,GAAG,YAAM,CAAC,IAAI,CAClC,WAAW,CAAC,uBAAuB,CAAC,WAAW,CAAC,EAChD,yBAAmB,CACnB,CAAC,OAAO,CAAC,+BAAyB,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,YAAM,CAAC,IAAI,CAAC,YAAY,EAAE,+BAAyB,CAAC,CAAC;IAC5E,OAAO,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,yBAAmB,CAAC,CAAC;AACzE,CAAC,CAAC;AAEkC,4DAAwB","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION_EXP,\n\tBN,\n\tBigNum,\n\tDriftClient,\n\tQUOTE_PRECISION_EXP,\n} from '@drift-labs/sdk';\n\n/* LP Utils */\nconst getLpSharesAmountForQuote = (\n\tdriftClient: DriftClient,\n\tmarketIndex: number,\n\tquoteAmount: BN\n): BigNum => {\n\tconst tenMillionBigNum = BigNum.fromPrint('10000000', QUOTE_PRECISION_EXP);\n\n\tconst pricePerLpShare = BigNum.from(\n\t\tdriftClient.getQuoteValuePerLpShare(marketIndex),\n\t\tQUOTE_PRECISION_EXP\n\t);\n\n\treturn BigNum.from(quoteAmount, QUOTE_PRECISION_EXP)\n\t\t.scale(\n\t\t\ttenMillionBigNum.toNum(),\n\t\t\tpricePerLpShare.mul(tenMillionBigNum).toNum()\n\t\t)\n\t\t.shiftTo(AMM_RESERVE_PRECISION_EXP);\n};\n\nconst getQuoteValueForLpShares = (\n\tdriftClient: DriftClient,\n\tmarketIndex: number,\n\tsharesAmount: BN\n): BigNum => {\n\tconst pricePerLpShare = BigNum.from(\n\t\tdriftClient.getQuoteValuePerLpShare(marketIndex),\n\t\tQUOTE_PRECISION_EXP\n\t).shiftTo(AMM_RESERVE_PRECISION_EXP);\n\tconst lpSharesBigNum = BigNum.from(sharesAmount, AMM_RESERVE_PRECISION_EXP);\n\treturn lpSharesBigNum.mul(pricePerLpShare).shiftTo(QUOTE_PRECISION_EXP);\n};\n\nexport { getLpSharesAmountForQuote, getQuoteValueForLpShares };\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BigNum, PositionDirection } from '@drift-labs/sdk';
|
|
2
|
+
import { OpenPosition } from '../../types';
|
|
3
|
+
declare const calculatePnlPctFromPosition: (pnl: BN, position: OpenPosition, marginUsed?: BN) => number;
|
|
4
|
+
export declare const POTENTIAL_PROFIT_DEFAULT_STATE: {
|
|
5
|
+
estimatedProfit: BigNum;
|
|
6
|
+
estimatedProfitBeforeFees: BigNum;
|
|
7
|
+
estimatedTakerFee: BigNum;
|
|
8
|
+
notionalSizeAtEntry: BigNum;
|
|
9
|
+
notionalSizeAtExit: BigNum;
|
|
10
|
+
};
|
|
11
|
+
declare const calculatePotentialProfit: (props: {
|
|
12
|
+
currentPositionSize: BigNum;
|
|
13
|
+
currentPositionDirection: PositionDirection;
|
|
14
|
+
currentPositionEntryPrice: BigNum;
|
|
15
|
+
tradeDirection: PositionDirection;
|
|
16
|
+
/**
|
|
17
|
+
* Amount of position being closed in base asset size
|
|
18
|
+
*/
|
|
19
|
+
exitBaseSize: BigNum;
|
|
20
|
+
/**
|
|
21
|
+
* Either the user's limit price (for limit orders) or the estimated exit price (for market orders)
|
|
22
|
+
*/
|
|
23
|
+
exitPrice: BigNum;
|
|
24
|
+
takerFeeBps: number;
|
|
25
|
+
slippageTolerance?: number;
|
|
26
|
+
isMarketOrder?: boolean;
|
|
27
|
+
}) => {
|
|
28
|
+
estimatedProfit: BigNum;
|
|
29
|
+
estimatedProfitBeforeFees: BigNum;
|
|
30
|
+
estimatedTakerFee: BigNum;
|
|
31
|
+
notionalSizeAtEntry: BigNum;
|
|
32
|
+
notionalSizeAtExit: BigNum;
|
|
33
|
+
};
|
|
34
|
+
export { calculatePnlPctFromPosition, calculatePotentialProfit };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculatePotentialProfit = exports.calculatePnlPctFromPosition = exports.POTENTIAL_PROFIT_DEFAULT_STATE = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const leverage_1 = require("./leverage");
|
|
6
|
+
const calculatePnlPctFromPosition = (pnl, position, marginUsed) => {
|
|
7
|
+
var _a;
|
|
8
|
+
if (!(position === null || position === void 0 ? void 0 : position.quoteEntryAmount) || (position === null || position === void 0 ? void 0 : position.quoteEntryAmount.eq(sdk_1.ZERO)))
|
|
9
|
+
return 0;
|
|
10
|
+
let marginUsedNum;
|
|
11
|
+
if (marginUsed) {
|
|
12
|
+
marginUsedNum = sdk_1.BigNum.from(marginUsed, sdk_1.QUOTE_PRECISION_EXP).toNum();
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
const leverage = (_a = (0, leverage_1.convertMarginRatioToLeverage)(position.maxMarginRatio)) !== null && _a !== void 0 ? _a : 1;
|
|
16
|
+
const quoteEntryAmountNum = sdk_1.BigNum.from(position.quoteEntryAmount.abs(), sdk_1.QUOTE_PRECISION_EXP).toNum();
|
|
17
|
+
if (leverage <= 0 || quoteEntryAmountNum <= 0) {
|
|
18
|
+
marginUsedNum = 0;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
marginUsedNum = quoteEntryAmountNum / leverage;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (marginUsedNum <= 0) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
return (sdk_1.BigNum.from(pnl, sdk_1.QUOTE_PRECISION_EXP)
|
|
28
|
+
.shift(5)
|
|
29
|
+
.div(sdk_1.BigNum.fromPrint(`${marginUsedNum}`, sdk_1.QUOTE_PRECISION_EXP))
|
|
30
|
+
.toNum() * 100);
|
|
31
|
+
};
|
|
32
|
+
exports.calculatePnlPctFromPosition = calculatePnlPctFromPosition;
|
|
33
|
+
exports.POTENTIAL_PROFIT_DEFAULT_STATE = {
|
|
34
|
+
estimatedProfit: sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP),
|
|
35
|
+
estimatedProfitBeforeFees: sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP),
|
|
36
|
+
estimatedTakerFee: sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP),
|
|
37
|
+
notionalSizeAtEntry: sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP),
|
|
38
|
+
notionalSizeAtExit: sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP),
|
|
39
|
+
};
|
|
40
|
+
const calculatePotentialProfit = (props) => {
|
|
41
|
+
let estimatedProfit = sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP);
|
|
42
|
+
let estimatedProfitBeforeFees = sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP);
|
|
43
|
+
let estimatedTakerFee = sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP);
|
|
44
|
+
let notionalSizeAtEntry = sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP);
|
|
45
|
+
let notionalSizeAtExit = sdk_1.BigNum.zero(sdk_1.PRICE_PRECISION_EXP);
|
|
46
|
+
const isClosingLong = (0, sdk_1.isVariant)(props.currentPositionDirection, 'long') &&
|
|
47
|
+
(0, sdk_1.isVariant)(props.tradeDirection, 'short');
|
|
48
|
+
const isClosingShort = (0, sdk_1.isVariant)(props.currentPositionDirection, 'short') &&
|
|
49
|
+
(0, sdk_1.isVariant)(props.tradeDirection, 'long');
|
|
50
|
+
if (!isClosingLong && !isClosingShort)
|
|
51
|
+
return exports.POTENTIAL_PROFIT_DEFAULT_STATE;
|
|
52
|
+
if (!props.exitBaseSize)
|
|
53
|
+
return exports.POTENTIAL_PROFIT_DEFAULT_STATE;
|
|
54
|
+
if (props.exitBaseSize.eqZero() ||
|
|
55
|
+
props.currentPositionSize.lt(props.exitBaseSize)) {
|
|
56
|
+
return exports.POTENTIAL_PROFIT_DEFAULT_STATE;
|
|
57
|
+
}
|
|
58
|
+
const baseSizeBeingClosed = props.exitBaseSize.lte(props.currentPositionSize)
|
|
59
|
+
? props.exitBaseSize
|
|
60
|
+
: props.currentPositionSize;
|
|
61
|
+
// Notional size of amount being closed at entry and exit
|
|
62
|
+
notionalSizeAtEntry = baseSizeBeingClosed.mul(props.currentPositionEntryPrice.shiftTo(baseSizeBeingClosed.precision));
|
|
63
|
+
notionalSizeAtExit = baseSizeBeingClosed.mul(props.exitPrice.shiftTo(baseSizeBeingClosed.precision));
|
|
64
|
+
if (isClosingLong) {
|
|
65
|
+
estimatedProfitBeforeFees = notionalSizeAtExit.sub(notionalSizeAtEntry);
|
|
66
|
+
}
|
|
67
|
+
else if (isClosingShort) {
|
|
68
|
+
estimatedProfitBeforeFees = notionalSizeAtEntry.sub(notionalSizeAtExit);
|
|
69
|
+
}
|
|
70
|
+
// subtract takerFee if applicable
|
|
71
|
+
if (props.takerFeeBps > 0) {
|
|
72
|
+
const takerFeeDenominator = Math.floor(100 / (props.takerFeeBps * 0.01));
|
|
73
|
+
estimatedTakerFee = notionalSizeAtExit.scale(1, takerFeeDenominator);
|
|
74
|
+
estimatedProfit = estimatedProfitBeforeFees.sub(estimatedTakerFee.shiftTo(estimatedProfitBeforeFees.precision));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
estimatedProfit = estimatedProfitBeforeFees;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
estimatedProfit,
|
|
81
|
+
estimatedProfitBeforeFees,
|
|
82
|
+
estimatedTakerFee,
|
|
83
|
+
notionalSizeAtEntry,
|
|
84
|
+
notionalSizeAtExit,
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
exports.calculatePotentialProfit = calculatePotentialProfit;
|
|
88
|
+
//# sourceMappingURL=pnl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pnl.js","sourceRoot":"","sources":["../../../src/utils/trading/pnl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tBN,\n\tBigNum,\n\tPRICE_PRECISION_EXP,\n\tPositionDirection,\n\tQUOTE_PRECISION_EXP,\n\tZERO,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { OpenPosition } from '../../types';\nimport { convertMarginRatioToLeverage } from './leverage';\n\nconst calculatePnlPctFromPosition = (\n\tpnl: BN,\n\tposition: OpenPosition,\n\tmarginUsed?: BN\n): number => {\n\tif (!position?.quoteEntryAmount || position?.quoteEntryAmount.eq(ZERO))\n\t\treturn 0;\n\n\tlet marginUsedNum: number;\n\n\tif (marginUsed) {\n\t\tmarginUsedNum = BigNum.from(marginUsed, QUOTE_PRECISION_EXP).toNum();\n\t} else {\n\t\tconst leverage = convertMarginRatioToLeverage(position.maxMarginRatio) ?? 1;\n\t\tconst quoteEntryAmountNum = BigNum.from(\n\t\t\tposition.quoteEntryAmount.abs(),\n\t\t\tQUOTE_PRECISION_EXP\n\t\t).toNum();\n\n\t\tif (leverage <= 0 || quoteEntryAmountNum <= 0) {\n\t\t\tmarginUsedNum = 0;\n\t\t} else {\n\t\t\tmarginUsedNum = quoteEntryAmountNum / leverage;\n\t\t}\n\t}\n\n\tif (marginUsedNum <= 0) {\n\t\treturn 0;\n\t}\n\n\treturn (\n\t\tBigNum.from(pnl, QUOTE_PRECISION_EXP)\n\t\t\t.shift(5)\n\t\t\t.div(BigNum.fromPrint(`${marginUsedNum}`, QUOTE_PRECISION_EXP))\n\t\t\t.toNum() * 100\n\t);\n};\n\nexport const POTENTIAL_PROFIT_DEFAULT_STATE = {\n\testimatedProfit: BigNum.zero(PRICE_PRECISION_EXP),\n\testimatedProfitBeforeFees: BigNum.zero(PRICE_PRECISION_EXP),\n\testimatedTakerFee: BigNum.zero(PRICE_PRECISION_EXP),\n\tnotionalSizeAtEntry: BigNum.zero(PRICE_PRECISION_EXP),\n\tnotionalSizeAtExit: BigNum.zero(PRICE_PRECISION_EXP),\n};\n\nconst calculatePotentialProfit = (props: {\n\tcurrentPositionSize: BigNum;\n\tcurrentPositionDirection: PositionDirection;\n\tcurrentPositionEntryPrice: BigNum;\n\ttradeDirection: PositionDirection;\n\t/**\n\t * Amount of position being closed in base asset size\n\t */\n\texitBaseSize: BigNum;\n\t/**\n\t * Either the user's limit price (for limit orders) or the estimated exit price (for market orders)\n\t */\n\texitPrice: BigNum;\n\ttakerFeeBps: number;\n\tslippageTolerance?: number;\n\tisMarketOrder?: boolean;\n}): {\n\testimatedProfit: BigNum;\n\testimatedProfitBeforeFees: BigNum;\n\testimatedTakerFee: BigNum;\n\tnotionalSizeAtEntry: BigNum;\n\tnotionalSizeAtExit: BigNum;\n} => {\n\tlet estimatedProfit = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet estimatedProfitBeforeFees = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet estimatedTakerFee = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet notionalSizeAtEntry = BigNum.zero(PRICE_PRECISION_EXP);\n\tlet notionalSizeAtExit = BigNum.zero(PRICE_PRECISION_EXP);\n\n\tconst isClosingLong =\n\t\tisVariant(props.currentPositionDirection, 'long') &&\n\t\tisVariant(props.tradeDirection, 'short');\n\tconst isClosingShort =\n\t\tisVariant(props.currentPositionDirection, 'short') &&\n\t\tisVariant(props.tradeDirection, 'long');\n\n\tif (!isClosingLong && !isClosingShort) return POTENTIAL_PROFIT_DEFAULT_STATE;\n\tif (!props.exitBaseSize) return POTENTIAL_PROFIT_DEFAULT_STATE;\n\n\tif (\n\t\tprops.exitBaseSize.eqZero() ||\n\t\tprops.currentPositionSize.lt(props.exitBaseSize)\n\t) {\n\t\treturn POTENTIAL_PROFIT_DEFAULT_STATE;\n\t}\n\n\tconst baseSizeBeingClosed = props.exitBaseSize.lte(props.currentPositionSize)\n\t\t? props.exitBaseSize\n\t\t: props.currentPositionSize;\n\n\t// Notional size of amount being closed at entry and exit\n\tnotionalSizeAtEntry = baseSizeBeingClosed.mul(\n\t\tprops.currentPositionEntryPrice.shiftTo(baseSizeBeingClosed.precision)\n\t);\n\tnotionalSizeAtExit = baseSizeBeingClosed.mul(\n\t\tprops.exitPrice.shiftTo(baseSizeBeingClosed.precision)\n\t);\n\n\tif (isClosingLong) {\n\t\testimatedProfitBeforeFees = notionalSizeAtExit.sub(notionalSizeAtEntry);\n\t} else if (isClosingShort) {\n\t\testimatedProfitBeforeFees = notionalSizeAtEntry.sub(notionalSizeAtExit);\n\t}\n\n\t// subtract takerFee if applicable\n\tif (props.takerFeeBps > 0) {\n\t\tconst takerFeeDenominator = Math.floor(100 / (props.takerFeeBps * 0.01));\n\t\testimatedTakerFee = notionalSizeAtExit.scale(1, takerFeeDenominator);\n\t\testimatedProfit = estimatedProfitBeforeFees.sub(\n\t\t\testimatedTakerFee.shiftTo(estimatedProfitBeforeFees.precision)\n\t\t);\n\t} else {\n\t\testimatedProfit = estimatedProfitBeforeFees;\n\t}\n\n\treturn {\n\t\testimatedProfit,\n\t\testimatedProfitBeforeFees,\n\t\testimatedTakerFee,\n\t\tnotionalSizeAtEntry,\n\t\tnotionalSizeAtExit,\n\t};\n};\n\nexport { calculatePnlPctFromPosition, calculatePotentialProfit };\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BN, PositionDirection } from '@drift-labs/sdk';
|
|
2
|
+
import { UIOrderType } from '../../types';
|
|
3
|
+
declare const getMarketOrderLimitPrice: ({ direction, baselinePrice, slippageTolerance, }: {
|
|
4
|
+
direction: PositionDirection;
|
|
5
|
+
baselinePrice: BN;
|
|
6
|
+
slippageTolerance: number;
|
|
7
|
+
}) => BN;
|
|
8
|
+
/**
|
|
9
|
+
* Check if the order type is a market order or oracle market order
|
|
10
|
+
*/
|
|
11
|
+
declare const checkIsMarketOrderType: (orderType: UIOrderType) => boolean;
|
|
12
|
+
export { getMarketOrderLimitPrice, checkIsMarketOrderType };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkIsMarketOrderType = exports.getMarketOrderLimitPrice = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const getMarketOrderLimitPrice = ({ direction, baselinePrice, slippageTolerance, }) => {
|
|
6
|
+
let limitPrice;
|
|
7
|
+
if (!baselinePrice)
|
|
8
|
+
return sdk_1.ZERO;
|
|
9
|
+
if (slippageTolerance === 0)
|
|
10
|
+
return baselinePrice;
|
|
11
|
+
// infinite slippage capped at 15% currently
|
|
12
|
+
if (slippageTolerance == undefined)
|
|
13
|
+
slippageTolerance = 15;
|
|
14
|
+
// if manually entered, cap at 99%
|
|
15
|
+
if (slippageTolerance > 99)
|
|
16
|
+
slippageTolerance = 99;
|
|
17
|
+
let limitPricePctDiff;
|
|
18
|
+
if ((0, sdk_1.isVariant)(direction, 'long')) {
|
|
19
|
+
limitPricePctDiff = sdk_1.PRICE_PRECISION.add(new sdk_1.BN(slippageTolerance * sdk_1.PRICE_PRECISION.toNumber()).div(new sdk_1.BN(100)));
|
|
20
|
+
limitPrice = baselinePrice.mul(limitPricePctDiff).div(sdk_1.PRICE_PRECISION);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
limitPricePctDiff = sdk_1.PRICE_PRECISION.sub(new sdk_1.BN(slippageTolerance * sdk_1.PRICE_PRECISION.toNumber()).div(new sdk_1.BN(100)));
|
|
24
|
+
limitPrice = baselinePrice.mul(limitPricePctDiff).div(sdk_1.PRICE_PRECISION);
|
|
25
|
+
}
|
|
26
|
+
return limitPrice;
|
|
27
|
+
};
|
|
28
|
+
exports.getMarketOrderLimitPrice = getMarketOrderLimitPrice;
|
|
29
|
+
/**
|
|
30
|
+
* Check if the order type is a market order or oracle market order
|
|
31
|
+
*/
|
|
32
|
+
const checkIsMarketOrderType = (orderType) => {
|
|
33
|
+
return orderType === 'market' || orderType === 'oracle';
|
|
34
|
+
};
|
|
35
|
+
exports.checkIsMarketOrderType = checkIsMarketOrderType;
|
|
36
|
+
//# sourceMappingURL=price.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price.js","sourceRoot":"","sources":["../../../src/utils/trading/price.ts"],"names":[],"mappings":";;;AAAA,yCAMyB;AAGzB,MAAM,wBAAwB,GAAG,CAAC,EACjC,SAAS,EACT,aAAa,EACb,iBAAiB,GAKjB,EAAM,EAAE;IACR,IAAI,UAAU,CAAC;IAEf,IAAI,CAAC,aAAa;QAAE,OAAO,UAAI,CAAC;IAEhC,IAAI,iBAAiB,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAElD,4CAA4C;IAC5C,IAAI,iBAAiB,IAAI,SAAS;QAAE,iBAAiB,GAAG,EAAE,CAAC;IAE3D,kCAAkC;IAClC,IAAI,iBAAiB,GAAG,EAAE;QAAE,iBAAiB,GAAG,EAAE,CAAC;IAEnD,IAAI,iBAAiB,CAAC;IACtB,IAAI,IAAA,eAAS,EAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;QAClC,iBAAiB,GAAG,qBAAe,CAAC,GAAG,CACtC,IAAI,QAAE,CAAC,iBAAiB,GAAG,qBAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,QAAE,CAAC,GAAG,CAAC,CAAC,CACvE,CAAC;QACF,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,qBAAe,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACP,iBAAiB,GAAG,qBAAe,CAAC,GAAG,CACtC,IAAI,QAAE,CAAC,iBAAiB,GAAG,qBAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,QAAE,CAAC,GAAG,CAAC,CAAC,CACvE,CAAC;QACF,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,qBAAe,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AASO,4DAAwB;AAPjC;;GAEG;AACH,MAAM,sBAAsB,GAAG,CAAC,SAAsB,EAAE,EAAE;IACzD,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,CAAC;AACzD,CAAC,CAAC;AAEiC,wDAAsB","sourcesContent":["import {\n\tBN,\n\tPRICE_PRECISION,\n\tPositionDirection,\n\tZERO,\n\tisVariant,\n} from '@drift-labs/sdk';\nimport { UIOrderType } from '../../types';\n\nconst getMarketOrderLimitPrice = ({\n\tdirection,\n\tbaselinePrice,\n\tslippageTolerance,\n}: {\n\tdirection: PositionDirection;\n\tbaselinePrice: BN;\n\tslippageTolerance: number;\n}): BN => {\n\tlet limitPrice;\n\n\tif (!baselinePrice) return ZERO;\n\n\tif (slippageTolerance === 0) return baselinePrice;\n\n\t// infinite slippage capped at 15% currently\n\tif (slippageTolerance == undefined) slippageTolerance = 15;\n\n\t// if manually entered, cap at 99%\n\tif (slippageTolerance > 99) slippageTolerance = 99;\n\n\tlet limitPricePctDiff;\n\tif (isVariant(direction, 'long')) {\n\t\tlimitPricePctDiff = PRICE_PRECISION.add(\n\t\t\tnew BN(slippageTolerance * PRICE_PRECISION.toNumber()).div(new BN(100))\n\t\t);\n\t\tlimitPrice = baselinePrice.mul(limitPricePctDiff).div(PRICE_PRECISION);\n\t} else {\n\t\tlimitPricePctDiff = PRICE_PRECISION.sub(\n\t\t\tnew BN(slippageTolerance * PRICE_PRECISION.toNumber()).div(new BN(100))\n\t\t);\n\t\tlimitPrice = baselinePrice.mul(limitPricePctDiff).div(PRICE_PRECISION);\n\t}\n\n\treturn limitPrice;\n};\n\n/**\n * Check if the order type is a market order or oracle market order\n */\nconst checkIsMarketOrderType = (orderType: UIOrderType) => {\n\treturn orderType === 'market' || orderType === 'oracle';\n};\n\nexport { getMarketOrderLimitPrice, checkIsMarketOrderType };\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BigNum, DriftClient } from '@drift-labs/sdk';
|
|
2
|
+
import { MarketId } from '../../types';
|
|
3
|
+
declare const getMarketTickSize: (driftClient: DriftClient, marketId: MarketId) => BN;
|
|
4
|
+
declare const getMarketTickSizeDecimals: (driftClient: DriftClient, marketId: MarketId) => number;
|
|
5
|
+
declare const getMarketStepSize: (driftClient: DriftClient, marketId: MarketId) => BN;
|
|
6
|
+
declare const getMarketStepSizeDecimals: (driftClient: DriftClient, marketId: MarketId) => number;
|
|
7
|
+
/**
|
|
8
|
+
* Checks if a given order amount represents an entire position order
|
|
9
|
+
* by comparing it with MAX_LEVERAGE_ORDER_SIZE
|
|
10
|
+
* @param orderAmount - The BigNum order amount to check
|
|
11
|
+
* @returns true if the order is for the entire position, false otherwise
|
|
12
|
+
*/
|
|
13
|
+
export declare const isEntirePositionOrder: (orderAmount: BigNum) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the MAX_LEVERAGE_ORDER_SIZE as a BigNum with the same precision as the given amount
|
|
16
|
+
* @param orderAmount - The BigNum order amount to match precision with
|
|
17
|
+
* @returns BigNum representation of MAX_LEVERAGE_ORDER_SIZE
|
|
18
|
+
*/
|
|
19
|
+
export declare const getMaxLeverageOrderSize: (orderAmount: BigNum) => BigNum;
|
|
20
|
+
/**
|
|
21
|
+
* Formats an order size for display, showing "Entire Position" if it's a max leverage order
|
|
22
|
+
* @param orderAmount - The BigNum order amount to format
|
|
23
|
+
* @param formatFn - Optional custom format function, defaults to prettyPrint()
|
|
24
|
+
* @returns Formatted string showing either "Entire Position" or the formatted amount
|
|
25
|
+
*/
|
|
26
|
+
export declare const formatOrderSize: (orderAmount: BigNum, formatFn?: (amount: BigNum) => string) => string;
|
|
27
|
+
export { getMarketTickSize, getMarketTickSizeDecimals, getMarketStepSize, getMarketStepSizeDecimals, };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMarketStepSizeDecimals = exports.getMarketStepSize = exports.getMarketTickSizeDecimals = exports.getMarketTickSize = exports.formatOrderSize = exports.getMaxLeverageOrderSize = exports.isEntirePositionOrder = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const getMarketTickSize = (driftClient, marketId) => {
|
|
6
|
+
const marketAccount = marketId.isPerp
|
|
7
|
+
? driftClient.getPerpMarketAccount(marketId.marketIndex)
|
|
8
|
+
: driftClient.getSpotMarketAccount(marketId.marketIndex);
|
|
9
|
+
if (!marketAccount)
|
|
10
|
+
return sdk_1.ZERO;
|
|
11
|
+
if (marketId.isPerp) {
|
|
12
|
+
return marketAccount.amm.orderTickSize;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return marketAccount.orderTickSize;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.getMarketTickSize = getMarketTickSize;
|
|
19
|
+
const getMarketTickSizeDecimals = (driftClient, marketId) => {
|
|
20
|
+
const tickSize = getMarketTickSize(driftClient, marketId);
|
|
21
|
+
const decimalPlaces = Math.max(0, Math.floor(Math.log10(sdk_1.PRICE_PRECISION.div(tickSize.eq(sdk_1.ZERO) ? sdk_1.ONE : tickSize).toNumber())));
|
|
22
|
+
return decimalPlaces;
|
|
23
|
+
};
|
|
24
|
+
exports.getMarketTickSizeDecimals = getMarketTickSizeDecimals;
|
|
25
|
+
const getMarketStepSize = (driftClient, marketId) => {
|
|
26
|
+
const marketAccount = marketId.isPerp
|
|
27
|
+
? driftClient.getPerpMarketAccount(marketId.marketIndex)
|
|
28
|
+
: driftClient.getSpotMarketAccount(marketId.marketIndex);
|
|
29
|
+
if (!marketAccount)
|
|
30
|
+
return sdk_1.ZERO;
|
|
31
|
+
if (marketId.isPerp) {
|
|
32
|
+
return marketAccount.amm.orderStepSize;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return marketAccount.orderStepSize;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.getMarketStepSize = getMarketStepSize;
|
|
39
|
+
const getMarketStepSizeDecimals = (driftClient, marketId) => {
|
|
40
|
+
const stepSize = getMarketStepSize(driftClient, marketId);
|
|
41
|
+
const decimalPlaces = Math.max(0, Math.floor(Math.log10(sdk_1.AMM_RESERVE_PRECISION.div(stepSize.eq(sdk_1.ZERO) ? sdk_1.ONE : stepSize).toNumber())));
|
|
42
|
+
return decimalPlaces;
|
|
43
|
+
};
|
|
44
|
+
exports.getMarketStepSizeDecimals = getMarketStepSizeDecimals;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a given order amount represents an entire position order
|
|
47
|
+
* by comparing it with MAX_LEVERAGE_ORDER_SIZE
|
|
48
|
+
* @param orderAmount - The BigNum order amount to check
|
|
49
|
+
* @returns true if the order is for the entire position, false otherwise
|
|
50
|
+
*/
|
|
51
|
+
const isEntirePositionOrder = (orderAmount) => {
|
|
52
|
+
const maxLeverageSize = new sdk_1.BigNum(sdk_1.MAX_LEVERAGE_ORDER_SIZE, orderAmount.precision);
|
|
53
|
+
const isMaxLeverage = Math.abs(maxLeverageSize.sub(orderAmount).toNum()) < 1;
|
|
54
|
+
// Some order paths produce a truncated u64::MAX instead of MAX_LEVERAGE_ORDER_SIZE
|
|
55
|
+
const ALTERNATIVE_MAX_ORDER_SIZE = '18446744072000000000';
|
|
56
|
+
const alternativeMaxSize = new sdk_1.BigNum(ALTERNATIVE_MAX_ORDER_SIZE, orderAmount.precision);
|
|
57
|
+
const isAlternativeMax = Math.abs(alternativeMaxSize.sub(orderAmount).toNum()) < 1;
|
|
58
|
+
return isMaxLeverage || isAlternativeMax;
|
|
59
|
+
};
|
|
60
|
+
exports.isEntirePositionOrder = isEntirePositionOrder;
|
|
61
|
+
/**
|
|
62
|
+
* Gets the MAX_LEVERAGE_ORDER_SIZE as a BigNum with the same precision as the given amount
|
|
63
|
+
* @param orderAmount - The BigNum order amount to match precision with
|
|
64
|
+
* @returns BigNum representation of MAX_LEVERAGE_ORDER_SIZE
|
|
65
|
+
*/
|
|
66
|
+
const getMaxLeverageOrderSize = (orderAmount) => {
|
|
67
|
+
return new sdk_1.BigNum(sdk_1.MAX_LEVERAGE_ORDER_SIZE, orderAmount.precision);
|
|
68
|
+
};
|
|
69
|
+
exports.getMaxLeverageOrderSize = getMaxLeverageOrderSize;
|
|
70
|
+
/**
|
|
71
|
+
* Formats an order size for display, showing "Entire Position" if it's a max leverage order
|
|
72
|
+
* @param orderAmount - The BigNum order amount to format
|
|
73
|
+
* @param formatFn - Optional custom format function, defaults to prettyPrint()
|
|
74
|
+
* @returns Formatted string showing either "Entire Position" or the formatted amount
|
|
75
|
+
*/
|
|
76
|
+
const formatOrderSize = (orderAmount, formatFn) => {
|
|
77
|
+
if ((0, exports.isEntirePositionOrder)(orderAmount)) {
|
|
78
|
+
return 'Entire Position';
|
|
79
|
+
}
|
|
80
|
+
return formatFn ? formatFn(orderAmount) : orderAmount.prettyPrint();
|
|
81
|
+
};
|
|
82
|
+
exports.formatOrderSize = formatOrderSize;
|
|
83
|
+
//# sourceMappingURL=size.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size.js","sourceRoot":"","sources":["../../../src/utils/trading/size.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION,\n\tBN,\n\tBigNum,\n\tDriftClient,\n\tMAX_LEVERAGE_ORDER_SIZE,\n\tONE,\n\tPRICE_PRECISION,\n\tPerpMarketAccount,\n\tSpotMarketAccount,\n\tZERO,\n} from '@drift-labs/sdk';\nimport { MarketId } from '../../types';\n\nconst getMarketTickSize = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n): BN => {\n\tconst marketAccount = marketId.isPerp\n\t\t? driftClient.getPerpMarketAccount(marketId.marketIndex)\n\t\t: driftClient.getSpotMarketAccount(marketId.marketIndex);\n\tif (!marketAccount) return ZERO;\n\n\tif (marketId.isPerp) {\n\t\treturn (marketAccount as PerpMarketAccount).amm.orderTickSize;\n\t} else {\n\t\treturn (marketAccount as SpotMarketAccount).orderTickSize;\n\t}\n};\n\nconst getMarketTickSizeDecimals = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n) => {\n\tconst tickSize = getMarketTickSize(driftClient, marketId);\n\n\tconst decimalPlaces = Math.max(\n\t\t0,\n\t\tMath.floor(\n\t\t\tMath.log10(\n\t\t\t\tPRICE_PRECISION.div(tickSize.eq(ZERO) ? ONE : tickSize).toNumber()\n\t\t\t)\n\t\t)\n\t);\n\n\treturn decimalPlaces;\n};\n\nconst getMarketStepSize = (driftClient: DriftClient, marketId: MarketId) => {\n\tconst marketAccount = marketId.isPerp\n\t\t? driftClient.getPerpMarketAccount(marketId.marketIndex)\n\t\t: driftClient.getSpotMarketAccount(marketId.marketIndex);\n\tif (!marketAccount) return ZERO;\n\n\tif (marketId.isPerp) {\n\t\treturn (marketAccount as PerpMarketAccount).amm.orderStepSize;\n\t} else {\n\t\treturn (marketAccount as SpotMarketAccount).orderStepSize;\n\t}\n};\n\nconst getMarketStepSizeDecimals = (\n\tdriftClient: DriftClient,\n\tmarketId: MarketId\n) => {\n\tconst stepSize = getMarketStepSize(driftClient, marketId);\n\n\tconst decimalPlaces = Math.max(\n\t\t0,\n\t\tMath.floor(\n\t\t\tMath.log10(\n\t\t\t\tAMM_RESERVE_PRECISION.div(stepSize.eq(ZERO) ? ONE : stepSize).toNumber()\n\t\t\t)\n\t\t)\n\t);\n\n\treturn decimalPlaces;\n};\n\n/**\n * Checks if a given order amount represents an entire position order\n * by comparing it with MAX_LEVERAGE_ORDER_SIZE\n * @param orderAmount - The BigNum order amount to check\n * @returns true if the order is for the entire position, false otherwise\n */\nexport const isEntirePositionOrder = (orderAmount: BigNum): boolean => {\n\tconst maxLeverageSize = new BigNum(\n\t\tMAX_LEVERAGE_ORDER_SIZE,\n\t\torderAmount.precision\n\t);\n\n\tconst isMaxLeverage = Math.abs(maxLeverageSize.sub(orderAmount).toNum()) < 1;\n\n\t// Some order paths produce a truncated u64::MAX instead of MAX_LEVERAGE_ORDER_SIZE\n\tconst ALTERNATIVE_MAX_ORDER_SIZE = '18446744072000000000';\n\tconst alternativeMaxSize = new BigNum(\n\t\tALTERNATIVE_MAX_ORDER_SIZE,\n\t\torderAmount.precision\n\t);\n\tconst isAlternativeMax =\n\t\tMath.abs(alternativeMaxSize.sub(orderAmount).toNum()) < 1;\n\n\treturn isMaxLeverage || isAlternativeMax;\n};\n\n/**\n * Gets the MAX_LEVERAGE_ORDER_SIZE as a BigNum with the same precision as the given amount\n * @param orderAmount - The BigNum order amount to match precision with\n * @returns BigNum representation of MAX_LEVERAGE_ORDER_SIZE\n */\nexport const getMaxLeverageOrderSize = (orderAmount: BigNum): BigNum => {\n\treturn new BigNum(MAX_LEVERAGE_ORDER_SIZE, orderAmount.precision);\n};\n\n/**\n * Formats an order size for display, showing \"Entire Position\" if it's a max leverage order\n * @param orderAmount - The BigNum order amount to format\n * @param formatFn - Optional custom format function, defaults to prettyPrint()\n * @returns Formatted string showing either \"Entire Position\" or the formatted amount\n */\nexport const formatOrderSize = (\n\torderAmount: BigNum,\n\tformatFn?: (amount: BigNum) => string\n): string => {\n\tif (isEntirePositionOrder(orderAmount)) {\n\t\treturn 'Entire Position';\n\t}\n\treturn formatFn ? formatFn(orderAmount) : orderAmount.prettyPrint();\n};\n\nexport {\n\tgetMarketTickSize,\n\tgetMarketTickSizeDecimals,\n\tgetMarketStepSize,\n\tgetMarketStepSizeDecimals,\n};\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const isNotionalDust: (val: BigNum) => boolean;
|
|
1
|
+
export { isValidBase58 } from '../strings/parse';
|
|
3
2
|
export declare const isValidPublicKey: (str: string) => boolean;
|
|
4
3
|
export declare const BITCOIN_CHAIN_ID = "8253038";
|
|
5
4
|
export declare const TRON_CHAIN_ID = "728126428";
|