@drift-labs/sdk 2.13.0-beta.0 → 2.13.0-beta.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/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/driftClient.d.ts +9 -0
- package/lib/driftClient.js +49 -0
- package/lib/idl/drift.json +1 -1
- package/lib/math/market.d.ts +5 -0
- package/lib/math/market.js +18 -1
- package/lib/math/oracles.d.ts +2 -2
- package/lib/math/oracles.js +20 -8
- package/lib/math/orders.js +1 -1
- package/lib/math/spotBalance.d.ts +5 -0
- package/lib/math/spotBalance.js +30 -3
- package/lib/math/trade.js +8 -2
- package/lib/user.d.ts +12 -6
- package/lib/user.js +124 -72
- package/package.json +1 -1
- package/src/constants/numericConstants.ts +2 -0
- package/src/driftClient.ts +64 -0
- package/src/idl/drift.json +1 -1
- package/src/math/market.ts +51 -0
- package/src/math/oracles.ts +30 -16
- package/src/math/orders.ts +2 -2
- package/src/math/spotBalance.ts +51 -3
- package/src/math/trade.ts +10 -2
- package/src/user.ts +267 -138
- package/tests/amm/test.ts +3 -2
|
@@ -51,6 +51,8 @@ export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
|
|
|
51
51
|
export declare const MARGIN_PRECISION: BN;
|
|
52
52
|
export declare const BID_ASK_SPREAD_PRECISION: BN;
|
|
53
53
|
export declare const LIQUIDATION_PCT_PRECISION: BN;
|
|
54
|
+
export declare const FIVE_MINUTE: BN;
|
|
55
|
+
export declare const ONE_HOUR: BN;
|
|
54
56
|
export declare const ONE_YEAR: BN;
|
|
55
57
|
export declare const QUOTE_SPOT_MARKET_INDEX = 0;
|
|
56
58
|
export declare const LAMPORTS_PRECISION: BN;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
4
|
-
exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.LIQUIDATION_PCT_PRECISION = void 0;
|
|
4
|
+
exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.LIQUIDATION_PCT_PRECISION = void 0;
|
|
5
5
|
const web3_js_1 = require("@solana/web3.js");
|
|
6
6
|
const __1 = require("../");
|
|
7
7
|
exports.ZERO = new __1.BN(0);
|
|
@@ -55,6 +55,8 @@ exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.m
|
|
|
55
55
|
exports.MARGIN_PRECISION = exports.TEN_THOUSAND;
|
|
56
56
|
exports.BID_ASK_SPREAD_PRECISION = new __1.BN(1000000); // 10^6
|
|
57
57
|
exports.LIQUIDATION_PCT_PRECISION = exports.TEN_THOUSAND;
|
|
58
|
+
exports.FIVE_MINUTE = new __1.BN(60 * 5);
|
|
59
|
+
exports.ONE_HOUR = new __1.BN(60 * 60);
|
|
58
60
|
exports.ONE_YEAR = new __1.BN(31536000);
|
|
59
61
|
exports.QUOTE_SPOT_MARKET_INDEX = 0;
|
|
60
62
|
exports.LAMPORTS_PRECISION = new __1.BN(web3_js_1.LAMPORTS_PER_SOL);
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -219,6 +219,15 @@ export declare class DriftClient {
|
|
|
219
219
|
* @returns
|
|
220
220
|
*/
|
|
221
221
|
modifyPerpOrder(orderId: number, newBaseAmount?: BN, newLimitPrice?: BN, newOraclePriceOffset?: number): Promise<TransactionSignature>;
|
|
222
|
+
/**
|
|
223
|
+
* Modifies an open order by closing it and replacing it with a new order.
|
|
224
|
+
* @param userOrderId: The open order to modify
|
|
225
|
+
* @param newBaseAmount: The new base amount for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
|
|
226
|
+
* @param newLimitPice: The new limit price for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
|
|
227
|
+
* @param newOraclePriceOffset: The new oracle price offset for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
|
|
228
|
+
* @returns
|
|
229
|
+
*/
|
|
230
|
+
modifyPerpOrderByUserOrderId(userOrderId: number, newBaseAmount?: BN, newLimitPrice?: BN, newOraclePriceOffset?: number): Promise<TransactionSignature>;
|
|
222
231
|
settlePNLs(users: {
|
|
223
232
|
settleeUserAccountPublicKey: PublicKey;
|
|
224
233
|
settleeUserAccount: UserAccount;
|
package/lib/driftClient.js
CHANGED
|
@@ -1777,6 +1777,55 @@ class DriftClient {
|
|
|
1777
1777
|
maxTs: openOrder.maxTs,
|
|
1778
1778
|
auctionStartPrice: openOrder.auctionStartPrice,
|
|
1779
1779
|
auctionEndPrice: openOrder.auctionEndPrice,
|
|
1780
|
+
userOrderId: openOrder.userOrderId,
|
|
1781
|
+
};
|
|
1782
|
+
const placeOrderIx = await this.getPlacePerpOrderIx(newOrderParams);
|
|
1783
|
+
const tx = new web3_js_1.Transaction();
|
|
1784
|
+
tx.add(web3_js_1.ComputeBudgetProgram.requestUnits({
|
|
1785
|
+
units: 1000000,
|
|
1786
|
+
additionalFee: 0,
|
|
1787
|
+
}));
|
|
1788
|
+
tx.add(cancelOrderIx);
|
|
1789
|
+
tx.add(placeOrderIx);
|
|
1790
|
+
const { txSig, slot } = await this.sendTransaction(tx, [], this.opts);
|
|
1791
|
+
this.perpMarketLastSlotCache.set(newOrderParams.marketIndex, slot);
|
|
1792
|
+
return txSig;
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Modifies an open order by closing it and replacing it with a new order.
|
|
1796
|
+
* @param userOrderId: The open order to modify
|
|
1797
|
+
* @param newBaseAmount: The new base amount for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
|
|
1798
|
+
* @param newLimitPice: The new limit price for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
|
|
1799
|
+
* @param newOraclePriceOffset: The new oracle price offset for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
|
|
1800
|
+
* @returns
|
|
1801
|
+
*/
|
|
1802
|
+
async modifyPerpOrderByUserOrderId(userOrderId, newBaseAmount, newLimitPrice, newOraclePriceOffset) {
|
|
1803
|
+
if (!newBaseAmount && !newLimitPrice && !newOraclePriceOffset) {
|
|
1804
|
+
throw new Error(`Must provide newBaseAmount or newLimitPrice or newOraclePriceOffset to modify order`);
|
|
1805
|
+
}
|
|
1806
|
+
const openOrder = this.getUser().getOrderByUserOrderId(userOrderId);
|
|
1807
|
+
if (!openOrder) {
|
|
1808
|
+
throw new Error(`No open order with user order id ${userOrderId.toString()}`);
|
|
1809
|
+
}
|
|
1810
|
+
const cancelOrderIx = await this.getCancelOrderIx(openOrder.orderId);
|
|
1811
|
+
const newOrderParams = {
|
|
1812
|
+
orderType: openOrder.orderType,
|
|
1813
|
+
marketType: openOrder.marketType,
|
|
1814
|
+
direction: openOrder.direction,
|
|
1815
|
+
baseAssetAmount: newBaseAmount || openOrder.baseAssetAmount,
|
|
1816
|
+
price: newLimitPrice || openOrder.price,
|
|
1817
|
+
marketIndex: openOrder.marketIndex,
|
|
1818
|
+
reduceOnly: openOrder.reduceOnly,
|
|
1819
|
+
postOnly: openOrder.postOnly,
|
|
1820
|
+
immediateOrCancel: openOrder.immediateOrCancel,
|
|
1821
|
+
triggerPrice: openOrder.triggerPrice,
|
|
1822
|
+
triggerCondition: openOrder.triggerCondition,
|
|
1823
|
+
oraclePriceOffset: newOraclePriceOffset || openOrder.oraclePriceOffset,
|
|
1824
|
+
auctionDuration: openOrder.auctionDuration,
|
|
1825
|
+
maxTs: openOrder.maxTs,
|
|
1826
|
+
auctionStartPrice: openOrder.auctionStartPrice,
|
|
1827
|
+
auctionEndPrice: openOrder.auctionEndPrice,
|
|
1828
|
+
userOrderId: openOrder.userOrderId,
|
|
1780
1829
|
};
|
|
1781
1830
|
const placeOrderIx = await this.getPlacePerpOrderIx(newOrderParams);
|
|
1782
1831
|
const tx = new web3_js_1.Transaction();
|
package/lib/idl/drift.json
CHANGED
package/lib/math/market.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { BN } from '@project-serum/anchor';
|
|
3
3
|
import { PerpMarketAccount, PositionDirection, MarginCategory, SpotMarketAccount } from '../types';
|
|
4
4
|
import { OraclePriceData } from '../oracles/types';
|
|
5
|
+
import { DLOB } from '../dlob/DLOB';
|
|
5
6
|
/**
|
|
6
7
|
* Calculates market mark price
|
|
7
8
|
*
|
|
@@ -31,3 +32,7 @@ export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount
|
|
|
31
32
|
export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
|
|
32
33
|
export declare function calculateNetUserPnl(perpMarket: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
33
34
|
export declare function calculateNetUserPnlImbalance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
35
|
+
export declare function calculateAvailablePerpLiquidity(market: PerpMarketAccount, oraclePriceData: OraclePriceData, dlob: DLOB, slot: number): {
|
|
36
|
+
bids: BN;
|
|
37
|
+
asks: BN;
|
|
38
|
+
};
|
package/lib/math/market.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateOracleReserveSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
|
|
3
|
+
exports.calculateAvailablePerpLiquidity = exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateOracleReserveSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const amm_1 = require("./amm");
|
|
@@ -115,3 +115,20 @@ function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
|
|
|
115
115
|
return imbalance;
|
|
116
116
|
}
|
|
117
117
|
exports.calculateNetUserPnlImbalance = calculateNetUserPnlImbalance;
|
|
118
|
+
function calculateAvailablePerpLiquidity(market, oraclePriceData, dlob, slot) {
|
|
119
|
+
let [bids, asks] = amm_1.calculateMarketOpenBidAsk(market.amm.baseAssetReserve, market.amm.minBaseAssetReserve, market.amm.maxBaseAssetReserve, market.amm.orderStepSize);
|
|
120
|
+
asks = asks.abs();
|
|
121
|
+
const bidPrice = calculateBidPrice(market, oraclePriceData);
|
|
122
|
+
const askPrice = calculateAskPrice(market, oraclePriceData);
|
|
123
|
+
for (const bid of dlob.getMakerLimitBids(market.marketIndex, slot, types_1.MarketType.PERP, oraclePriceData, askPrice)) {
|
|
124
|
+
bids = bids.add(bid.order.baseAssetAmount.sub(bid.order.baseAssetAmountFilled));
|
|
125
|
+
}
|
|
126
|
+
for (const ask of dlob.getMakerLimitAsks(market.marketIndex, slot, types_1.MarketType.PERP, oraclePriceData, bidPrice)) {
|
|
127
|
+
asks = asks.add(ask.order.baseAssetAmount.sub(ask.order.baseAssetAmountFilled));
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
bids: bids,
|
|
131
|
+
asks: asks,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
exports.calculateAvailablePerpLiquidity = calculateAvailablePerpLiquidity;
|
package/lib/math/oracles.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { AMM, OracleGuardRails } from '../types';
|
|
3
3
|
import { OraclePriceData } from '../oracles/types';
|
|
4
|
-
import { BN, PerpMarketAccount } from '../index';
|
|
4
|
+
import { BN, HistoricalOracleData, PerpMarketAccount } from '../index';
|
|
5
5
|
export declare function oraclePriceBands(market: PerpMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
|
|
6
6
|
export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
|
|
7
7
|
export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;
|
|
8
|
-
export declare function calculateLiveOracleTwap(
|
|
8
|
+
export declare function calculateLiveOracleTwap(histOracleData: HistoricalOracleData, oraclePriceData: OraclePriceData, now: BN, period: BN): BN;
|
|
9
9
|
export declare function calculateLiveOracleStd(amm: AMM, oraclePriceData: OraclePriceData, now: BN): BN;
|
package/lib/math/oracles.js
CHANGED
|
@@ -38,7 +38,7 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
|
38
38
|
exports.isOracleValid = isOracleValid;
|
|
39
39
|
function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
40
40
|
const sinceLastUpdate = now.sub(amm.historicalOracleData.lastOraclePriceTwapTs);
|
|
41
|
-
const sinceStart = index_1.BN.max(numericConstants_1.ZERO,
|
|
41
|
+
const sinceStart = index_1.BN.max(numericConstants_1.ZERO, numericConstants_1.FIVE_MINUTE.sub(sinceLastUpdate));
|
|
42
42
|
const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5Min
|
|
43
43
|
.mul(sinceStart)
|
|
44
44
|
.add(oraclePriceData.price)
|
|
@@ -52,12 +52,24 @@ function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
|
52
52
|
return tooDivergent;
|
|
53
53
|
}
|
|
54
54
|
exports.isOracleTooDivergent = isOracleTooDivergent;
|
|
55
|
-
function calculateLiveOracleTwap(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
function calculateLiveOracleTwap(histOracleData, oraclePriceData, now, period) {
|
|
56
|
+
let oracleTwap = undefined;
|
|
57
|
+
if (period.eq(numericConstants_1.ONE_HOUR)) {
|
|
58
|
+
//todo: assumes its 1hr
|
|
59
|
+
// period = amm.fundingPeriod;
|
|
60
|
+
oracleTwap = histOracleData.lastOraclePriceTwap;
|
|
61
|
+
}
|
|
62
|
+
else if (period.eq(numericConstants_1.FIVE_MINUTE)) {
|
|
63
|
+
histOracleData.lastOraclePriceTwap5Min;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
throw Error('unsupported twap period passed');
|
|
67
|
+
}
|
|
68
|
+
const sinceLastUpdate = index_1.BN.max(numericConstants_1.ONE, now.sub(histOracleData.lastOraclePriceTwapTs));
|
|
69
|
+
const sinceStart = index_1.BN.max(numericConstants_1.ZERO, period.sub(sinceLastUpdate));
|
|
70
|
+
const clampRange = oracleTwap.div(new index_1.BN(3));
|
|
71
|
+
const clampedOraclePrice = index_1.BN.min(oracleTwap.add(clampRange), index_1.BN.max(oraclePriceData.price, oracleTwap.sub(clampRange)));
|
|
72
|
+
const newOracleTwap = oracleTwap
|
|
61
73
|
.mul(sinceStart)
|
|
62
74
|
.add(clampedOraclePrice.mul(sinceLastUpdate))
|
|
63
75
|
.div(sinceStart.add(sinceLastUpdate));
|
|
@@ -67,7 +79,7 @@ exports.calculateLiveOracleTwap = calculateLiveOracleTwap;
|
|
|
67
79
|
function calculateLiveOracleStd(amm, oraclePriceData, now) {
|
|
68
80
|
const sinceLastUpdate = index_1.BN.max(numericConstants_1.ONE, now.sub(amm.historicalOracleData.lastOraclePriceTwapTs));
|
|
69
81
|
const sinceStart = index_1.BN.max(numericConstants_1.ZERO, amm.fundingPeriod.sub(sinceLastUpdate));
|
|
70
|
-
const liveOracleTwap = calculateLiveOracleTwap(amm, oraclePriceData, now);
|
|
82
|
+
const liveOracleTwap = calculateLiveOracleTwap(amm.historicalOracleData, oraclePriceData, now, amm.fundingPeriod);
|
|
71
83
|
const priceDeltaVsTwap = oraclePriceData.price.sub(liveOracleTwap).abs();
|
|
72
84
|
const oracleStd = priceDeltaVsTwap.add(amm.oracleStd.mul(sinceStart).div(sinceStart.add(sinceLastUpdate)));
|
|
73
85
|
return oracleStd;
|
package/lib/math/orders.js
CHANGED
|
@@ -108,7 +108,7 @@ function hasAuctionPrice(order, slot) {
|
|
|
108
108
|
exports.hasAuctionPrice = hasAuctionPrice;
|
|
109
109
|
function isFillableByVAMM(order, market, oraclePriceData, slot, ts) {
|
|
110
110
|
return ((auction_1.isAuctionComplete(order, slot) &&
|
|
111
|
-
|
|
111
|
+
calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).gte(market.amm.minOrderSize)) ||
|
|
112
112
|
isOrderExpired(order, ts));
|
|
113
113
|
}
|
|
114
114
|
exports.isFillableByVAMM = isFillableByVAMM;
|
|
@@ -5,6 +5,7 @@ import { OraclePriceData } from '../oracles/types';
|
|
|
5
5
|
export declare function getBalance(tokenAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
|
|
6
6
|
export declare function getTokenAmount(balanceAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
|
|
7
7
|
export declare function getSignedTokenAmount(tokenAmount: BN, balanceType: SpotBalanceType): BN;
|
|
8
|
+
export declare function getStrictTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData, oraclePriceTwap: BN): BN;
|
|
8
9
|
export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData): BN;
|
|
9
10
|
export declare function calculateAssetWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
|
|
10
11
|
export declare function calculateLiabilityWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
|
|
@@ -19,4 +20,8 @@ export declare function calculateInterestAccumulated(bank: SpotMarketAccount, no
|
|
|
19
20
|
export declare function calculateWithdrawLimit(spotMarket: SpotMarketAccount, now: BN): {
|
|
20
21
|
borrowLimit: BN;
|
|
21
22
|
withdrawLimit: BN;
|
|
23
|
+
minDepositAmount: BN;
|
|
24
|
+
maxBorrowAmount: BN;
|
|
25
|
+
currentDepositAmount: any;
|
|
26
|
+
currentBorrowAmount: any;
|
|
22
27
|
};
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
|
|
3
|
+
exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getStrictTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const anchor_1 = require("@project-serum/anchor");
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
@@ -35,6 +35,21 @@ function getSignedTokenAmount(tokenAmount, balanceType) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
exports.getSignedTokenAmount = getSignedTokenAmount;
|
|
38
|
+
function getStrictTokenValue(tokenAmount, spotDecimals, oraclePriceData, oraclePriceTwap) {
|
|
39
|
+
if (tokenAmount.eq(numericConstants_1.ZERO)) {
|
|
40
|
+
return numericConstants_1.ZERO;
|
|
41
|
+
}
|
|
42
|
+
let price = oraclePriceData.price;
|
|
43
|
+
if (tokenAmount.gt(numericConstants_1.ZERO)) {
|
|
44
|
+
price = anchor_1.BN.min(oraclePriceData.price, oraclePriceTwap);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
price = anchor_1.BN.max(oraclePriceData.price, oraclePriceTwap);
|
|
48
|
+
}
|
|
49
|
+
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(spotDecimals));
|
|
50
|
+
return tokenAmount.mul(price).div(precisionDecrease);
|
|
51
|
+
}
|
|
52
|
+
exports.getStrictTokenValue = getStrictTokenValue;
|
|
38
53
|
function getTokenValue(tokenAmount, spotDecimals, oraclePriceData) {
|
|
39
54
|
if (tokenAmount.eq(numericConstants_1.ZERO)) {
|
|
40
55
|
return numericConstants_1.ZERO;
|
|
@@ -187,9 +202,21 @@ function calculateWithdrawLimit(spotMarket, now) {
|
|
|
187
202
|
.div(sinceLast.add(sinceStart));
|
|
188
203
|
const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(5)))); // between ~15-80% utilization with friction on twap
|
|
189
204
|
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
|
|
205
|
+
let withdrawLimit = anchor_1.BN.max(marketDepositTokenAmount.sub(minDepositTokens), numericConstants_1.ZERO);
|
|
206
|
+
let borrowLimit = anchor_1.BN.max(maxBorrowTokens.sub(marketBorrowTokenAmount), numericConstants_1.ZERO);
|
|
207
|
+
if (borrowLimit.eq(numericConstants_1.ZERO)) {
|
|
208
|
+
withdrawLimit = numericConstants_1.ZERO;
|
|
209
|
+
}
|
|
210
|
+
if (withdrawLimit.eq(numericConstants_1.ZERO)) {
|
|
211
|
+
borrowLimit = numericConstants_1.ZERO;
|
|
212
|
+
}
|
|
190
213
|
return {
|
|
191
|
-
borrowLimit
|
|
192
|
-
withdrawLimit
|
|
214
|
+
borrowLimit,
|
|
215
|
+
withdrawLimit,
|
|
216
|
+
maxBorrowAmount: maxBorrowTokens,
|
|
217
|
+
minDepositAmount: minDepositTokens,
|
|
218
|
+
currentDepositAmount: marketDepositTokenAmount,
|
|
219
|
+
currentBorrowAmount: marketBorrowTokenAmount,
|
|
193
220
|
};
|
|
194
221
|
}
|
|
195
222
|
exports.calculateWithdrawLimit = calculateWithdrawLimit;
|
package/lib/math/trade.js
CHANGED
|
@@ -338,7 +338,10 @@ function calculateEstimatedPerpEntryPrice(assetType, amount, direction, market,
|
|
|
338
338
|
break;
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
|
-
if (limitOrder
|
|
341
|
+
if (!limitOrder) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (usersToSkip.has(limitOrder.userAccount)) {
|
|
342
345
|
continue;
|
|
343
346
|
}
|
|
344
347
|
const baseFilled = anchor_1.BN.min(limitOrder.order.baseAssetAmount.sub(limitOrder.order.baseAssetAmountFilled), amount.sub(cumulativeBaseFilled));
|
|
@@ -388,7 +391,10 @@ function calculateEstimatedPerpEntryPrice(assetType, amount, direction, market,
|
|
|
388
391
|
break;
|
|
389
392
|
}
|
|
390
393
|
}
|
|
391
|
-
if (limitOrder
|
|
394
|
+
if (!limitOrder) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (usersToSkip.has(limitOrder.userAccount)) {
|
|
392
398
|
continue;
|
|
393
399
|
}
|
|
394
400
|
const quoteFilled = anchor_1.BN.min(limitOrder.order.baseAssetAmount
|
package/lib/user.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export declare class User {
|
|
|
89
89
|
/**
|
|
90
90
|
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
91
91
|
*/
|
|
92
|
-
getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN): BN;
|
|
92
|
+
getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean): BN;
|
|
93
93
|
/**
|
|
94
94
|
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
95
95
|
*/
|
|
@@ -109,10 +109,10 @@ export declare class User {
|
|
|
109
109
|
* @returns : Precision QUOTE_PRECISION
|
|
110
110
|
*/
|
|
111
111
|
getUnrealizedFundingPNL(marketIndex?: number): BN;
|
|
112
|
-
getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean): BN;
|
|
113
|
-
getSpotLiabilityValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN): BN;
|
|
114
|
-
getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN;
|
|
115
|
-
getSpotAssetValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory): BN;
|
|
112
|
+
getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
|
|
113
|
+
getSpotLiabilityValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN, strict?: boolean, now?: BN): BN;
|
|
114
|
+
getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
|
|
115
|
+
getSpotAssetValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, strict?: boolean, now?: BN): BN;
|
|
116
116
|
getNetSpotMarketValue(withWeightMarginCategory?: MarginCategory): BN;
|
|
117
117
|
/**
|
|
118
118
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
@@ -141,7 +141,7 @@ export declare class User {
|
|
|
141
141
|
*/
|
|
142
142
|
getPositionEstimatedExitPriceAndPnl(position: PerpPosition, amountToClose?: BN, useAMMClose?: boolean): [BN, BN];
|
|
143
143
|
/**
|
|
144
|
-
* calculates current user leverage
|
|
144
|
+
* calculates current user leverage which is (total liability size) / (net asset value)
|
|
145
145
|
* @returns : Precision TEN_THOUSAND
|
|
146
146
|
*/
|
|
147
147
|
getLeverage(): BN;
|
|
@@ -232,6 +232,12 @@ export declare class User {
|
|
|
232
232
|
* @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
|
|
233
233
|
*/
|
|
234
234
|
getWithdrawalLimit(marketIndex: number, reduceOnly?: boolean): BN;
|
|
235
|
+
canBypassWithdrawLimits(marketIndex: number): {
|
|
236
|
+
canBypass: boolean;
|
|
237
|
+
netDeposits: BN;
|
|
238
|
+
depositAmount: BN;
|
|
239
|
+
maxDepositAmount: BN;
|
|
240
|
+
};
|
|
235
241
|
/**
|
|
236
242
|
* Get the total position value, excluding any position coming from the given target market
|
|
237
243
|
* @param marketToIgnore
|