@drift-labs/sdk 0.2.0-master.24 → 0.2.0-master.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +13 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
- package/lib/accounts/types.d.ts +8 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
- package/lib/addresses/pda.d.ts +8 -6
- package/lib/addresses/pda.js +35 -27
- package/lib/admin.d.ts +9 -6
- package/lib/admin.js +90 -54
- package/lib/clearingHouse.d.ts +71 -42
- package/lib/clearingHouse.js +765 -282
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +19 -17
- package/lib/clearingHouseUser.js +145 -123
- package/lib/config.d.ts +7 -7
- package/lib/config.js +21 -21
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/events/eventSubscriber.d.ts +4 -2
- package/lib/events/eventSubscriber.js +16 -9
- package/lib/events/fetchLogs.d.ts +10 -1
- package/lib/events/fetchLogs.js +27 -7
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +6 -2
- package/lib/events/types.d.ts +4 -2
- package/lib/events/types.js +2 -0
- package/lib/examples/makeTradeExample.js +18 -6
- package/lib/idl/clearing_house.json +1128 -347
- package/lib/index.d.ts +6 -3
- package/lib/index.js +6 -3
- package/lib/math/amm.d.ts +5 -3
- package/lib/math/amm.js +42 -4
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +10 -9
- package/lib/math/market.js +29 -6
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +5 -5
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +19 -0
- package/lib/math/spotBalance.js +176 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +2 -0
- package/lib/math/spotPosition.js +8 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +148 -39
- package/lib/types.js +37 -9
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +106 -0
- package/my-script/multiConnections.ts +119 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.js +249 -0
- package/src/accounts/bulkUserStatsSubscription.js +75 -0
- package/src/accounts/bulkUserSubscription.js +75 -0
- package/src/accounts/fetch.js +92 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
- package/src/accounts/pollingOracleSubscriber.js +156 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
- package/src/accounts/pollingUserAccountSubscriber.js +208 -0
- package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
- package/src/accounts/types.js +28 -0
- package/src/accounts/types.ts +11 -9
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +138 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
- package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
- package/src/addresses/pda.js +186 -0
- package/src/addresses/pda.ts +56 -42
- package/src/admin.js +1284 -0
- package/src/admin.ts +149 -75
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.js +3433 -0
- package/src/clearingHouse.ts +1097 -380
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.js +874 -0
- package/src/clearingHouseUser.ts +237 -172
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/clearingHouseUserStats.js +115 -0
- package/src/clearingHouseUserStatsConfig.js +2 -0
- package/src/config.js +80 -0
- package/src/config.ts +30 -30
- package/src/constants/numericConstants.js +18 -11
- package/src/constants/numericConstants.ts +17 -15
- package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/spotMarkets.js +51 -0
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/events/eventList.js +66 -23
- package/src/events/eventSubscriber.js +202 -0
- package/src/events/eventSubscriber.ts +20 -12
- package/src/events/fetchLogs.js +117 -0
- package/src/events/fetchLogs.ts +35 -8
- package/src/events/pollingLogProvider.js +113 -0
- package/src/events/pollingLogProvider.ts +10 -2
- package/src/events/sort.js +41 -0
- package/src/events/txEventCache.js +22 -19
- package/src/events/types.js +25 -0
- package/src/events/types.ts +7 -1
- package/src/events/webSocketLogProvider.js +76 -0
- package/src/examples/makeTradeExample.ts +27 -6
- package/src/factory/bigNum.js +183 -180
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +1128 -347
- package/src/index.js +75 -0
- package/src/index.ts +6 -3
- package/src/math/amm.js +422 -0
- package/src/math/amm.ts +73 -5
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +4 -3
- package/src/math/funding.js +223 -175
- package/src/math/funding.ts +7 -7
- package/src/math/insurance.js +27 -0
- package/src/math/margin.js +77 -0
- package/src/math/margin.ts +34 -23
- package/src/math/market.js +105 -0
- package/src/math/market.ts +71 -19
- package/src/math/oracles.js +40 -10
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.js +153 -0
- package/src/math/orders.ts +5 -5
- package/src/math/position.js +172 -0
- package/src/math/position.ts +31 -31
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.js +176 -0
- package/src/math/spotBalance.ts +290 -0
- package/src/math/spotMarket.js +8 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.js +8 -0
- package/src/math/spotPosition.ts +6 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.js +81 -74
- package/src/math/trade.ts +4 -4
- package/src/math/utils.js +8 -7
- package/src/oracles/oracleClientCache.js +10 -9
- package/src/oracles/pythClient.js +52 -17
- package/src/oracles/quoteAssetOracleClient.js +44 -13
- package/src/oracles/switchboardClient.js +69 -37
- package/src/oracles/types.js +1 -1
- package/src/orderParams.js +14 -6
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.js +102 -0
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.js +2 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.js +67 -20
- package/src/token/index.js +4 -4
- package/src/tokenFaucet.js +288 -154
- package/src/tx/retryTxSender.js +280 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.js +1 -1
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.js +7 -6
- package/src/types.js +216 -0
- package/src/types.ts +131 -39
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +46 -11
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +46 -12
- package/src/wallet.js +55 -18
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/addresses/marketAddresses.js +0 -26
- package/src/constants/banks.js +0 -42
- package/src/examples/makeTradeExample.js +0 -80
- package/src/math/bankBalance.ts +0 -258
- package/src/math/state.js +0 -15
- package/src/math/utils.js.map +0 -1
- package/src/util/getTokenAddress.js +0 -9
package/src/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
exports.__esModule = true;
|
|
13
|
+
exports.pyth = exports.PublicKey = exports.BN = void 0;
|
|
14
|
+
var anchor_1 = require("@project-serum/anchor");
|
|
15
|
+
exports.BN = anchor_1.BN;
|
|
16
|
+
var web3_js_1 = require("@solana/web3.js");
|
|
17
|
+
exports.PublicKey = web3_js_1.PublicKey;
|
|
18
|
+
var client_1 = require("@pythnetwork/client");
|
|
19
|
+
exports.pyth = client_1["default"];
|
|
20
|
+
__exportStar(require("./tokenFaucet"), exports);
|
|
21
|
+
__exportStar(require("./oracles/types"), exports);
|
|
22
|
+
__exportStar(require("./oracles/pythClient"), exports);
|
|
23
|
+
__exportStar(require("./oracles/switchboardClient"), exports);
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
__exportStar(require("./constants/perpMarkets"), exports);
|
|
26
|
+
__exportStar(require("./accounts/fetch"), exports);
|
|
27
|
+
__exportStar(require("./accounts/webSocketClearingHouseAccountSubscriber"), exports);
|
|
28
|
+
__exportStar(require("./accounts/bulkAccountLoader"), exports);
|
|
29
|
+
__exportStar(require("./accounts/bulkUserSubscription"), exports);
|
|
30
|
+
__exportStar(require("./accounts/bulkUserStatsSubscription"), exports);
|
|
31
|
+
__exportStar(require("./accounts/pollingClearingHouseAccountSubscriber"), exports);
|
|
32
|
+
__exportStar(require("./accounts/pollingOracleSubscriber"), exports);
|
|
33
|
+
__exportStar(require("./accounts/pollingTokenAccountSubscriber"), exports);
|
|
34
|
+
__exportStar(require("./accounts/pollingUserAccountSubscriber"), exports);
|
|
35
|
+
__exportStar(require("./accounts/pollingUserStatsAccountSubscriber"), exports);
|
|
36
|
+
__exportStar(require("./accounts/types"), exports);
|
|
37
|
+
__exportStar(require("./addresses/pda"), exports);
|
|
38
|
+
__exportStar(require("./admin"), exports);
|
|
39
|
+
__exportStar(require("./clearingHouseUser"), exports);
|
|
40
|
+
__exportStar(require("./clearingHouseUserConfig"), exports);
|
|
41
|
+
__exportStar(require("./clearingHouseUserStats"), exports);
|
|
42
|
+
__exportStar(require("./clearingHouseUserStatsConfig"), exports);
|
|
43
|
+
__exportStar(require("./clearingHouse"), exports);
|
|
44
|
+
__exportStar(require("./factory/oracleClient"), exports);
|
|
45
|
+
__exportStar(require("./factory/bigNum"), exports);
|
|
46
|
+
__exportStar(require("./events/types"), exports);
|
|
47
|
+
__exportStar(require("./events/eventSubscriber"), exports);
|
|
48
|
+
__exportStar(require("./events/fetchLogs"), exports);
|
|
49
|
+
__exportStar(require("./math/auction"), exports);
|
|
50
|
+
__exportStar(require("./math/spotMarket"), exports);
|
|
51
|
+
__exportStar(require("./math/conversion"), exports);
|
|
52
|
+
__exportStar(require("./math/funding"), exports);
|
|
53
|
+
__exportStar(require("./math/market"), exports);
|
|
54
|
+
__exportStar(require("./math/position"), exports);
|
|
55
|
+
__exportStar(require("./math/oracles"), exports);
|
|
56
|
+
__exportStar(require("./math/amm"), exports);
|
|
57
|
+
__exportStar(require("./math/trade"), exports);
|
|
58
|
+
__exportStar(require("./math/orders"), exports);
|
|
59
|
+
__exportStar(require("./math/repeg"), exports);
|
|
60
|
+
__exportStar(require("./math/margin"), exports);
|
|
61
|
+
__exportStar(require("./math/insurance"), exports);
|
|
62
|
+
__exportStar(require("./orderParams"), exports);
|
|
63
|
+
__exportStar(require("./slot/SlotSubscriber"), exports);
|
|
64
|
+
__exportStar(require("./wallet"), exports);
|
|
65
|
+
__exportStar(require("./types"), exports);
|
|
66
|
+
__exportStar(require("./math/utils"), exports);
|
|
67
|
+
__exportStar(require("./config"), exports);
|
|
68
|
+
__exportStar(require("./constants/numericConstants"), exports);
|
|
69
|
+
__exportStar(require("./serum/serumSubscriber"), exports);
|
|
70
|
+
__exportStar(require("./tx/retryTxSender"), exports);
|
|
71
|
+
__exportStar(require("./util/computeUnits"), exports);
|
|
72
|
+
__exportStar(require("./util/tps"), exports);
|
|
73
|
+
__exportStar(require("./math/spotBalance"), exports);
|
|
74
|
+
__exportStar(require("./constants/spotMarkets"), exports);
|
|
75
|
+
__exportStar(require("./clearingHouseConfig"), exports);
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ export * from './oracles/types';
|
|
|
7
7
|
export * from './oracles/pythClient';
|
|
8
8
|
export * from './oracles/switchboardClient';
|
|
9
9
|
export * from './types';
|
|
10
|
-
export * from './constants/
|
|
10
|
+
export * from './constants/perpMarkets';
|
|
11
11
|
export * from './accounts/fetch';
|
|
12
12
|
export * from './accounts/webSocketClearingHouseAccountSubscriber';
|
|
13
13
|
export * from './accounts/bulkAccountLoader';
|
|
@@ -30,7 +30,9 @@ export * from './factory/oracleClient';
|
|
|
30
30
|
export * from './factory/bigNum';
|
|
31
31
|
export * from './events/types';
|
|
32
32
|
export * from './events/eventSubscriber';
|
|
33
|
+
export * from './events/fetchLogs';
|
|
33
34
|
export * from './math/auction';
|
|
35
|
+
export * from './math/spotMarket';
|
|
34
36
|
export * from './math/conversion';
|
|
35
37
|
export * from './math/funding';
|
|
36
38
|
export * from './math/market';
|
|
@@ -49,11 +51,12 @@ export * from './types';
|
|
|
49
51
|
export * from './math/utils';
|
|
50
52
|
export * from './config';
|
|
51
53
|
export * from './constants/numericConstants';
|
|
54
|
+
export * from './serum/serumSubscriber';
|
|
52
55
|
export * from './tx/retryTxSender';
|
|
53
56
|
export * from './util/computeUnits';
|
|
54
57
|
export * from './util/tps';
|
|
55
|
-
export * from './math/
|
|
56
|
-
export * from './constants/
|
|
58
|
+
export * from './math/spotBalance';
|
|
59
|
+
export * from './constants/spotMarkets';
|
|
57
60
|
export * from './clearingHouseConfig';
|
|
58
61
|
|
|
59
62
|
export { BN, PublicKey, pyth };
|
package/src/math/amm.js
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateInventoryScale = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
4
|
+
var anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
var types_1 = require("../types");
|
|
7
|
+
var assert_1 = require("../assert/assert");
|
|
8
|
+
var __1 = require("..");
|
|
9
|
+
var repeg_1 = require("./repeg");
|
|
10
|
+
function calculatePegFromTargetPrice(targetPrice, baseAssetReserve, quoteAssetReserve) {
|
|
11
|
+
return anchor_1.BN.max(targetPrice
|
|
12
|
+
.mul(baseAssetReserve)
|
|
13
|
+
.div(quoteAssetReserve)
|
|
14
|
+
.add(numericConstants_1.PRICE_DIV_PEG.div(new anchor_1.BN(2)))
|
|
15
|
+
.div(numericConstants_1.PRICE_DIV_PEG), numericConstants_1.ONE);
|
|
16
|
+
}
|
|
17
|
+
exports.calculatePegFromTargetPrice = calculatePegFromTargetPrice;
|
|
18
|
+
function calculateOptimalPegAndBudget(amm, oraclePriceData) {
|
|
19
|
+
var markPriceBefore = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
|
|
20
|
+
var targetPrice = oraclePriceData.price;
|
|
21
|
+
var newPeg = calculatePegFromTargetPrice(targetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
|
|
22
|
+
var prePegCost = (0, repeg_1.calculateRepegCost)(amm, newPeg);
|
|
23
|
+
var totalFeeLB = amm.totalExchangeFee.div(new anchor_1.BN(2));
|
|
24
|
+
var budget = anchor_1.BN.max(numericConstants_1.ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
|
|
25
|
+
if (budget.lt(prePegCost)) {
|
|
26
|
+
var maxPriceSpread = new anchor_1.BN(amm.maxSpread)
|
|
27
|
+
.mul(targetPrice)
|
|
28
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION);
|
|
29
|
+
var newTargetPrice = void 0;
|
|
30
|
+
var newOptimalPeg = void 0;
|
|
31
|
+
var newBudget = void 0;
|
|
32
|
+
var targetPriceGap = markPriceBefore.sub(targetPrice);
|
|
33
|
+
if (targetPriceGap.abs().gt(maxPriceSpread)) {
|
|
34
|
+
var markAdj = targetPriceGap.abs().sub(maxPriceSpread);
|
|
35
|
+
if (targetPriceGap.lt(new anchor_1.BN(0))) {
|
|
36
|
+
newTargetPrice = markPriceBefore.add(markAdj);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
newTargetPrice = markPriceBefore.sub(markAdj);
|
|
40
|
+
}
|
|
41
|
+
newOptimalPeg = calculatePegFromTargetPrice(newTargetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
|
|
42
|
+
newBudget = (0, repeg_1.calculateRepegCost)(amm, newOptimalPeg);
|
|
43
|
+
return [newTargetPrice, newOptimalPeg, newBudget, false];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return [targetPrice, newPeg, budget, true];
|
|
47
|
+
}
|
|
48
|
+
exports.calculateOptimalPegAndBudget = calculateOptimalPegAndBudget;
|
|
49
|
+
function calculateNewAmm(amm, oraclePriceData) {
|
|
50
|
+
var _a;
|
|
51
|
+
var pKNumer = new anchor_1.BN(1);
|
|
52
|
+
var pKDenom = new anchor_1.BN(1);
|
|
53
|
+
var _b = calculateOptimalPegAndBudget(amm, oraclePriceData), targetPrice = _b[0], _newPeg = _b[1], budget = _b[2], checkLowerBound = _b[3];
|
|
54
|
+
var prePegCost = (0, repeg_1.calculateRepegCost)(amm, _newPeg);
|
|
55
|
+
var newPeg = _newPeg;
|
|
56
|
+
if (prePegCost.gt(budget) && checkLowerBound) {
|
|
57
|
+
_a = [new anchor_1.BN(999), new anchor_1.BN(1000)], pKNumer = _a[0], pKDenom = _a[1];
|
|
58
|
+
var deficitMadeup = (0, repeg_1.calculateAdjustKCost)(amm, pKNumer, pKDenom);
|
|
59
|
+
(0, assert_1.assert)(deficitMadeup.lte(new anchor_1.BN(0)));
|
|
60
|
+
prePegCost = budget.add(deficitMadeup.abs());
|
|
61
|
+
var newAmm = Object.assign({}, amm);
|
|
62
|
+
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
63
|
+
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
64
|
+
var invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
65
|
+
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
66
|
+
var directionToClose = amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
|
|
67
|
+
? types_1.PositionDirection.SHORT
|
|
68
|
+
: types_1.PositionDirection.LONG;
|
|
69
|
+
var _c = calculateAmmReservesAfterSwap(newAmm, 'base', amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose)), newQuoteAssetReserve = _c[0], _newBaseAssetReserve = _c[1];
|
|
70
|
+
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
71
|
+
newPeg = (0, repeg_1.calculateBudgetedPeg)(newAmm, prePegCost, targetPrice);
|
|
72
|
+
prePegCost = (0, repeg_1.calculateRepegCost)(newAmm, newPeg);
|
|
73
|
+
}
|
|
74
|
+
return [prePegCost, pKNumer, pKDenom, newPeg];
|
|
75
|
+
}
|
|
76
|
+
exports.calculateNewAmm = calculateNewAmm;
|
|
77
|
+
function calculateUpdatedAMM(amm, oraclePriceData) {
|
|
78
|
+
if (amm.curveUpdateIntensity == 0) {
|
|
79
|
+
return amm;
|
|
80
|
+
}
|
|
81
|
+
var newAmm = Object.assign({}, amm);
|
|
82
|
+
var _a = calculateNewAmm(amm, oraclePriceData), prepegCost = _a[0], pKNumer = _a[1], pKDenom = _a[2], newPeg = _a[3];
|
|
83
|
+
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
84
|
+
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
85
|
+
var invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
86
|
+
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
87
|
+
newAmm.pegMultiplier = newPeg;
|
|
88
|
+
var directionToClose = amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
|
|
89
|
+
? types_1.PositionDirection.SHORT
|
|
90
|
+
: types_1.PositionDirection.LONG;
|
|
91
|
+
var _b = calculateAmmReservesAfterSwap(newAmm, 'base', amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose)), newQuoteAssetReserve = _b[0], _newBaseAssetReserve = _b[1];
|
|
92
|
+
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
93
|
+
newAmm.totalFeeMinusDistributions =
|
|
94
|
+
newAmm.totalFeeMinusDistributions.sub(prepegCost);
|
|
95
|
+
return newAmm;
|
|
96
|
+
}
|
|
97
|
+
exports.calculateUpdatedAMM = calculateUpdatedAMM;
|
|
98
|
+
function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
|
|
99
|
+
var newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
100
|
+
var dirReserves = calculateSpreadReserves(newAmm, direction, oraclePriceData);
|
|
101
|
+
var result = {
|
|
102
|
+
baseAssetReserve: dirReserves.baseAssetReserve,
|
|
103
|
+
quoteAssetReserve: dirReserves.quoteAssetReserve,
|
|
104
|
+
sqrtK: newAmm.sqrtK,
|
|
105
|
+
newPeg: newAmm.pegMultiplier
|
|
106
|
+
};
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
exports.calculateUpdatedAMMSpreadReserves = calculateUpdatedAMMSpreadReserves;
|
|
110
|
+
function calculateBidAskPrice(amm, oraclePriceData, withUpdate) {
|
|
111
|
+
if (withUpdate === void 0) { withUpdate = true; }
|
|
112
|
+
var newAmm;
|
|
113
|
+
if (withUpdate) {
|
|
114
|
+
newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
newAmm = amm;
|
|
118
|
+
}
|
|
119
|
+
var askReserves = calculateSpreadReserves(newAmm, types_1.PositionDirection.LONG, oraclePriceData);
|
|
120
|
+
var bidReserves = calculateSpreadReserves(newAmm, types_1.PositionDirection.SHORT, oraclePriceData);
|
|
121
|
+
var askPrice = calculatePrice(askReserves.baseAssetReserve, askReserves.quoteAssetReserve, newAmm.pegMultiplier);
|
|
122
|
+
var bidPrice = calculatePrice(bidReserves.baseAssetReserve, bidReserves.quoteAssetReserve, newAmm.pegMultiplier);
|
|
123
|
+
return [bidPrice, askPrice];
|
|
124
|
+
}
|
|
125
|
+
exports.calculateBidAskPrice = calculateBidAskPrice;
|
|
126
|
+
/**
|
|
127
|
+
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
128
|
+
*
|
|
129
|
+
* @param baseAssetReserves
|
|
130
|
+
* @param quoteAssetReserves
|
|
131
|
+
* @param pegMultiplier
|
|
132
|
+
* @returns price : Precision MARK_PRICE_PRECISION
|
|
133
|
+
*/
|
|
134
|
+
function calculatePrice(baseAssetReserves, quoteAssetReserves, pegMultiplier) {
|
|
135
|
+
if (baseAssetReserves.abs().lte(numericConstants_1.ZERO)) {
|
|
136
|
+
return new anchor_1.BN(0);
|
|
137
|
+
}
|
|
138
|
+
return quoteAssetReserves
|
|
139
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
140
|
+
.mul(pegMultiplier)
|
|
141
|
+
.div(numericConstants_1.PEG_PRECISION)
|
|
142
|
+
.div(baseAssetReserves);
|
|
143
|
+
}
|
|
144
|
+
exports.calculatePrice = calculatePrice;
|
|
145
|
+
/**
|
|
146
|
+
* Calculates what the amm reserves would be after swapping a quote or base asset amount.
|
|
147
|
+
*
|
|
148
|
+
* @param amm
|
|
149
|
+
* @param inputAssetType
|
|
150
|
+
* @param swapAmount
|
|
151
|
+
* @param swapDirection
|
|
152
|
+
* @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
|
|
153
|
+
*/
|
|
154
|
+
function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDirection) {
|
|
155
|
+
var _a, _b;
|
|
156
|
+
(0, assert_1.assert)(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
|
|
157
|
+
var newQuoteAssetReserve;
|
|
158
|
+
var newBaseAssetReserve;
|
|
159
|
+
if (inputAssetType === 'quote') {
|
|
160
|
+
swapAmount = swapAmount
|
|
161
|
+
.mul(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
162
|
+
.div(amm.pegMultiplier);
|
|
163
|
+
_a = calculateSwapOutput(amm.quoteAssetReserve, swapAmount, swapDirection, amm.sqrtK.mul(amm.sqrtK)), newQuoteAssetReserve = _a[0], newBaseAssetReserve = _a[1];
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
_b = calculateSwapOutput(amm.baseAssetReserve, swapAmount, swapDirection, amm.sqrtK.mul(amm.sqrtK)), newBaseAssetReserve = _b[0], newQuoteAssetReserve = _b[1];
|
|
167
|
+
}
|
|
168
|
+
return [newQuoteAssetReserve, newBaseAssetReserve];
|
|
169
|
+
}
|
|
170
|
+
exports.calculateAmmReservesAfterSwap = calculateAmmReservesAfterSwap;
|
|
171
|
+
function calculateMarketOpenBidAsk(baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
|
|
172
|
+
// open orders
|
|
173
|
+
var openAsks;
|
|
174
|
+
if (maxBaseAssetReserve > baseAssetReserve) {
|
|
175
|
+
openAsks = maxBaseAssetReserve.sub(baseAssetReserve).mul(new anchor_1.BN(-1));
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
openAsks = numericConstants_1.ZERO;
|
|
179
|
+
}
|
|
180
|
+
var openBids;
|
|
181
|
+
if (minBaseAssetReserve < baseAssetReserve) {
|
|
182
|
+
openBids = baseAssetReserve.sub(minBaseAssetReserve);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
openBids = numericConstants_1.ZERO;
|
|
186
|
+
}
|
|
187
|
+
return [openBids, openAsks];
|
|
188
|
+
}
|
|
189
|
+
exports.calculateMarketOpenBidAsk = calculateMarketOpenBidAsk;
|
|
190
|
+
function calculateInventoryScale(netBaseAssetAmount, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
|
|
191
|
+
// inventory skew
|
|
192
|
+
var _a = calculateMarketOpenBidAsk(baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve), openBids = _a[0], openAsks = _a[1];
|
|
193
|
+
var totalLiquidity = anchor_1.BN.max(openBids.abs().add(openAsks.abs()), new anchor_1.BN(1));
|
|
194
|
+
var inventoryScale = anchor_1.BN.min(netBaseAssetAmount.abs(), totalLiquidity)
|
|
195
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(new anchor_1.BN(5)))
|
|
196
|
+
.div(totalLiquidity)
|
|
197
|
+
.toNumber() / numericConstants_1.BID_ASK_SPREAD_PRECISION.toNumber();
|
|
198
|
+
return inventoryScale;
|
|
199
|
+
}
|
|
200
|
+
exports.calculateInventoryScale = calculateInventoryScale;
|
|
201
|
+
function calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions) {
|
|
202
|
+
// inventory skew
|
|
203
|
+
var netBaseAssetValue = quoteAssetReserve
|
|
204
|
+
.sub(terminalQuoteAssetReserve)
|
|
205
|
+
.mul(pegMultiplier)
|
|
206
|
+
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
207
|
+
var localBaseAssetValue = netBaseAssetAmount
|
|
208
|
+
.mul(markPrice)
|
|
209
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
210
|
+
var effectiveLeverage = localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
|
|
211
|
+
(Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
|
|
212
|
+
1 / numericConstants_1.QUOTE_PRECISION.toNumber();
|
|
213
|
+
return effectiveLeverage;
|
|
214
|
+
}
|
|
215
|
+
exports.calculateEffectiveLeverage = calculateEffectiveLeverage;
|
|
216
|
+
function calculateMaxSpread(marginRatioInitial) {
|
|
217
|
+
var maxTargetSpread = new anchor_1.BN(marginRatioInitial)
|
|
218
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(numericConstants_1.MARGIN_PRECISION))
|
|
219
|
+
.toNumber();
|
|
220
|
+
return maxTargetSpread;
|
|
221
|
+
}
|
|
222
|
+
exports.calculateMaxSpread = calculateMaxSpread;
|
|
223
|
+
function calculateSpreadBN(baseSpread, lastOracleMarkSpreadPct, lastOracleConfPct, maxSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
|
|
224
|
+
var longSpread = baseSpread / 2;
|
|
225
|
+
var shortSpread = baseSpread / 2;
|
|
226
|
+
if (lastOracleMarkSpreadPct.gt(numericConstants_1.ZERO)) {
|
|
227
|
+
shortSpread = Math.max(shortSpread, lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber());
|
|
228
|
+
}
|
|
229
|
+
else if (lastOracleMarkSpreadPct.lt(numericConstants_1.ZERO)) {
|
|
230
|
+
longSpread = Math.max(longSpread, lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber());
|
|
231
|
+
}
|
|
232
|
+
var maxTargetSpread = Math.max(maxSpread, lastOracleMarkSpreadPct.abs().toNumber());
|
|
233
|
+
var MAX_INVENTORY_SKEW = 5;
|
|
234
|
+
var inventoryScale = calculateInventoryScale(netBaseAssetAmount, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve);
|
|
235
|
+
var inventorySpreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + inventoryScale);
|
|
236
|
+
if (netBaseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
237
|
+
longSpread *= inventorySpreadScale;
|
|
238
|
+
}
|
|
239
|
+
else if (netBaseAssetAmount.lt(numericConstants_1.ZERO)) {
|
|
240
|
+
shortSpread *= inventorySpreadScale;
|
|
241
|
+
}
|
|
242
|
+
var effectiveLeverage = calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions);
|
|
243
|
+
if (totalFeeMinusDistributions.gt(numericConstants_1.ZERO)) {
|
|
244
|
+
var spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
|
|
245
|
+
if (netBaseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
246
|
+
longSpread *= spreadScale;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
shortSpread *= spreadScale;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
longSpread *= MAX_INVENTORY_SKEW;
|
|
254
|
+
shortSpread *= MAX_INVENTORY_SKEW;
|
|
255
|
+
}
|
|
256
|
+
var totalSpread = longSpread + shortSpread;
|
|
257
|
+
if (totalSpread > maxTargetSpread) {
|
|
258
|
+
if (longSpread > shortSpread) {
|
|
259
|
+
longSpread = Math.min(longSpread, maxTargetSpread);
|
|
260
|
+
shortSpread = maxTargetSpread - longSpread;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
shortSpread = Math.min(shortSpread, maxTargetSpread);
|
|
264
|
+
longSpread = maxTargetSpread - shortSpread;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return [longSpread, shortSpread];
|
|
268
|
+
}
|
|
269
|
+
exports.calculateSpreadBN = calculateSpreadBN;
|
|
270
|
+
function calculateSpread(amm, direction, oraclePriceData) {
|
|
271
|
+
if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
|
|
272
|
+
return amm.baseSpread / 2;
|
|
273
|
+
}
|
|
274
|
+
var markPrice = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
|
|
275
|
+
var targetPrice = (oraclePriceData === null || oraclePriceData === void 0 ? void 0 : oraclePriceData.price) || markPrice;
|
|
276
|
+
var confInterval = oraclePriceData.confidence || numericConstants_1.ZERO;
|
|
277
|
+
var targetMarkSpreadPct = markPrice
|
|
278
|
+
.sub(targetPrice)
|
|
279
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
280
|
+
.div(markPrice);
|
|
281
|
+
var confIntervalPct = confInterval
|
|
282
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
283
|
+
.div(markPrice);
|
|
284
|
+
var _a = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.netBaseAssetAmount, markPrice, amm.totalFeeMinusDistributions, amm.baseAssetReserve, amm.minBaseAssetReserve, amm.maxBaseAssetReserve), longSpread = _a[0], shortSpread = _a[1];
|
|
285
|
+
var spread;
|
|
286
|
+
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
287
|
+
spread = longSpread;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
spread = shortSpread;
|
|
291
|
+
}
|
|
292
|
+
return spread;
|
|
293
|
+
}
|
|
294
|
+
exports.calculateSpread = calculateSpread;
|
|
295
|
+
function calculateSpreadReserves(amm, direction, oraclePriceData) {
|
|
296
|
+
var spread = calculateSpread(amm, direction, oraclePriceData);
|
|
297
|
+
if (spread === 0) {
|
|
298
|
+
return {
|
|
299
|
+
baseAssetReserve: amm.baseAssetReserve,
|
|
300
|
+
quoteAssetReserve: amm.quoteAssetReserve
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
var quoteAsserReserveDelta = amm.quoteAssetReserve.div(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(new anchor_1.BN(spread / 2)));
|
|
304
|
+
var quoteAssetReserve;
|
|
305
|
+
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
306
|
+
quoteAssetReserve = amm.quoteAssetReserve.add(quoteAsserReserveDelta);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
quoteAssetReserve = amm.quoteAssetReserve.sub(quoteAsserReserveDelta);
|
|
310
|
+
}
|
|
311
|
+
var baseAssetReserve = amm.sqrtK.mul(amm.sqrtK).div(quoteAssetReserve);
|
|
312
|
+
return {
|
|
313
|
+
baseAssetReserve: baseAssetReserve,
|
|
314
|
+
quoteAssetReserve: quoteAssetReserve
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
exports.calculateSpreadReserves = calculateSpreadReserves;
|
|
318
|
+
/**
|
|
319
|
+
* Helper function calculating constant product curve output. Agnostic to whether input asset is quote or base
|
|
320
|
+
*
|
|
321
|
+
* @param inputAssetReserve
|
|
322
|
+
* @param swapAmount
|
|
323
|
+
* @param swapDirection
|
|
324
|
+
* @param invariant
|
|
325
|
+
* @returns newInputAssetReserve and newOutputAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
|
|
326
|
+
*/
|
|
327
|
+
function calculateSwapOutput(inputAssetReserve, swapAmount, swapDirection, invariant) {
|
|
328
|
+
var newInputAssetReserve;
|
|
329
|
+
if (swapDirection === types_1.SwapDirection.ADD) {
|
|
330
|
+
newInputAssetReserve = inputAssetReserve.add(swapAmount);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
newInputAssetReserve = inputAssetReserve.sub(swapAmount);
|
|
334
|
+
}
|
|
335
|
+
var newOutputAssetReserve = invariant.div(newInputAssetReserve);
|
|
336
|
+
return [newInputAssetReserve, newOutputAssetReserve];
|
|
337
|
+
}
|
|
338
|
+
exports.calculateSwapOutput = calculateSwapOutput;
|
|
339
|
+
/**
|
|
340
|
+
* Translate long/shorting quote/base asset into amm operation
|
|
341
|
+
*
|
|
342
|
+
* @param inputAssetType
|
|
343
|
+
* @param positionDirection
|
|
344
|
+
*/
|
|
345
|
+
function getSwapDirection(inputAssetType, positionDirection) {
|
|
346
|
+
if ((0, types_1.isVariant)(positionDirection, 'long') && inputAssetType === 'base') {
|
|
347
|
+
return types_1.SwapDirection.REMOVE;
|
|
348
|
+
}
|
|
349
|
+
if ((0, types_1.isVariant)(positionDirection, 'short') && inputAssetType === 'quote') {
|
|
350
|
+
return types_1.SwapDirection.REMOVE;
|
|
351
|
+
}
|
|
352
|
+
return types_1.SwapDirection.ADD;
|
|
353
|
+
}
|
|
354
|
+
exports.getSwapDirection = getSwapDirection;
|
|
355
|
+
/**
|
|
356
|
+
* Helper function calculating terminal price of amm
|
|
357
|
+
*
|
|
358
|
+
* @param market
|
|
359
|
+
* @returns cost : Precision MARK_PRICE_PRECISION
|
|
360
|
+
*/
|
|
361
|
+
function calculateTerminalPrice(market) {
|
|
362
|
+
var directionToClose = market.amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
|
|
363
|
+
? types_1.PositionDirection.SHORT
|
|
364
|
+
: types_1.PositionDirection.LONG;
|
|
365
|
+
var _a = calculateAmmReservesAfterSwap(market.amm, 'base', market.amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose)), newQuoteAssetReserve = _a[0], newBaseAssetReserve = _a[1];
|
|
366
|
+
var terminalPrice = newQuoteAssetReserve
|
|
367
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
368
|
+
.mul(market.amm.pegMultiplier)
|
|
369
|
+
.div(numericConstants_1.PEG_PRECISION)
|
|
370
|
+
.div(newBaseAssetReserve);
|
|
371
|
+
return terminalPrice;
|
|
372
|
+
}
|
|
373
|
+
exports.calculateTerminalPrice = calculateTerminalPrice;
|
|
374
|
+
function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData) {
|
|
375
|
+
var invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
376
|
+
var newBaseAssetReserveSquared = invariant
|
|
377
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
378
|
+
.mul(amm.pegMultiplier)
|
|
379
|
+
.div(limit_price)
|
|
380
|
+
.div(numericConstants_1.PEG_PRECISION);
|
|
381
|
+
var newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
|
|
382
|
+
var baseAssetReserveBefore = calculateSpreadReserves(amm, direction, oraclePriceData).baseAssetReserve;
|
|
383
|
+
if (newBaseAssetReserve.gt(baseAssetReserveBefore)) {
|
|
384
|
+
return [
|
|
385
|
+
newBaseAssetReserve.sub(baseAssetReserveBefore),
|
|
386
|
+
types_1.PositionDirection.SHORT,
|
|
387
|
+
];
|
|
388
|
+
}
|
|
389
|
+
else if (newBaseAssetReserve.lt(baseAssetReserveBefore)) {
|
|
390
|
+
return [
|
|
391
|
+
baseAssetReserveBefore.sub(newBaseAssetReserve),
|
|
392
|
+
types_1.PositionDirection.LONG,
|
|
393
|
+
];
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
console.log('tradeSize Too Small');
|
|
397
|
+
return [new anchor_1.BN(0), types_1.PositionDirection.LONG];
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
|
|
401
|
+
function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swapDirection) {
|
|
402
|
+
var quoteAssetAmount = quoteAssetReserves
|
|
403
|
+
.mul(pegMultiplier)
|
|
404
|
+
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
405
|
+
if ((0, types_1.isVariant)(swapDirection, 'remove')) {
|
|
406
|
+
quoteAssetAmount = quoteAssetAmount.add(numericConstants_1.ONE);
|
|
407
|
+
}
|
|
408
|
+
return quoteAssetAmount;
|
|
409
|
+
}
|
|
410
|
+
exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
|
|
411
|
+
function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
|
|
412
|
+
var maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.maxBaseAssetAmountRatio));
|
|
413
|
+
var maxBaseAssetAmountOnSide;
|
|
414
|
+
if ((0, types_1.isVariant)(orderDirection, 'long')) {
|
|
415
|
+
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.baseAssetReserve.sub(amm.minBaseAssetReserve));
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.maxBaseAssetReserve.sub(amm.baseAssetReserve));
|
|
419
|
+
}
|
|
420
|
+
return (0, __1.standardizeBaseAssetAmount)(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.baseAssetAmountStepSize);
|
|
421
|
+
}
|
|
422
|
+
exports.calculateMaxBaseAssetAmountFillable = calculateMaxBaseAssetAmountFillable;
|
package/src/math/amm.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
AMM,
|
|
16
16
|
PositionDirection,
|
|
17
17
|
SwapDirection,
|
|
18
|
-
|
|
18
|
+
PerpMarketAccount,
|
|
19
19
|
isVariant,
|
|
20
20
|
} from '../types';
|
|
21
21
|
import { assert } from '../assert/assert';
|
|
@@ -308,6 +308,51 @@ export function calculateAmmReservesAfterSwap(
|
|
|
308
308
|
return [newQuoteAssetReserve, newBaseAssetReserve];
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
export function calculateMarketOpenBidAsk(
|
|
312
|
+
baseAssetReserve: BN,
|
|
313
|
+
minBaseAssetReserve: BN,
|
|
314
|
+
maxBaseAssetReserve: BN
|
|
315
|
+
): [BN, BN] {
|
|
316
|
+
// open orders
|
|
317
|
+
let openAsks;
|
|
318
|
+
if (maxBaseAssetReserve > baseAssetReserve) {
|
|
319
|
+
openAsks = maxBaseAssetReserve.sub(baseAssetReserve).mul(new BN(-1));
|
|
320
|
+
} else {
|
|
321
|
+
openAsks = ZERO;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let openBids;
|
|
325
|
+
if (minBaseAssetReserve < baseAssetReserve) {
|
|
326
|
+
openBids = baseAssetReserve.sub(minBaseAssetReserve);
|
|
327
|
+
} else {
|
|
328
|
+
openBids = ZERO;
|
|
329
|
+
}
|
|
330
|
+
return [openBids, openAsks];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export function calculateInventoryScale(
|
|
334
|
+
netBaseAssetAmount: BN,
|
|
335
|
+
baseAssetReserve: BN,
|
|
336
|
+
minBaseAssetReserve: BN,
|
|
337
|
+
maxBaseAssetReserve: BN
|
|
338
|
+
): number {
|
|
339
|
+
// inventory skew
|
|
340
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
341
|
+
baseAssetReserve,
|
|
342
|
+
minBaseAssetReserve,
|
|
343
|
+
maxBaseAssetReserve
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
const totalLiquidity = BN.max(openBids.abs().add(openAsks.abs()), new BN(1));
|
|
347
|
+
const inventoryScale =
|
|
348
|
+
BN.min(netBaseAssetAmount.abs(), totalLiquidity)
|
|
349
|
+
.mul(BID_ASK_SPREAD_PRECISION.mul(new BN(5)))
|
|
350
|
+
.div(totalLiquidity)
|
|
351
|
+
.toNumber() / BID_ASK_SPREAD_PRECISION.toNumber();
|
|
352
|
+
|
|
353
|
+
return inventoryScale;
|
|
354
|
+
}
|
|
355
|
+
|
|
311
356
|
export function calculateEffectiveLeverage(
|
|
312
357
|
baseSpread: number,
|
|
313
358
|
quoteAssetReserve: BN,
|
|
@@ -353,7 +398,10 @@ export function calculateSpreadBN(
|
|
|
353
398
|
pegMultiplier: BN,
|
|
354
399
|
netBaseAssetAmount: BN,
|
|
355
400
|
markPrice: BN,
|
|
356
|
-
totalFeeMinusDistributions: BN
|
|
401
|
+
totalFeeMinusDistributions: BN,
|
|
402
|
+
baseAssetReserve: BN,
|
|
403
|
+
minBaseAssetReserve: BN,
|
|
404
|
+
maxBaseAssetReserve: BN
|
|
357
405
|
): [number, number] {
|
|
358
406
|
let longSpread = baseSpread / 2;
|
|
359
407
|
let shortSpread = baseSpread / 2;
|
|
@@ -370,10 +418,27 @@ export function calculateSpreadBN(
|
|
|
370
418
|
);
|
|
371
419
|
}
|
|
372
420
|
|
|
373
|
-
const maxTargetSpread: number =
|
|
421
|
+
const maxTargetSpread: number = Math.max(
|
|
422
|
+
maxSpread,
|
|
423
|
+
lastOracleMarkSpreadPct.abs().toNumber()
|
|
424
|
+
);
|
|
374
425
|
|
|
375
426
|
const MAX_INVENTORY_SKEW = 5;
|
|
376
427
|
|
|
428
|
+
const inventoryScale = calculateInventoryScale(
|
|
429
|
+
netBaseAssetAmount,
|
|
430
|
+
baseAssetReserve,
|
|
431
|
+
minBaseAssetReserve,
|
|
432
|
+
maxBaseAssetReserve
|
|
433
|
+
);
|
|
434
|
+
const inventorySpreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + inventoryScale);
|
|
435
|
+
|
|
436
|
+
if (netBaseAssetAmount.gt(ZERO)) {
|
|
437
|
+
longSpread *= inventorySpreadScale;
|
|
438
|
+
} else if (netBaseAssetAmount.lt(ZERO)) {
|
|
439
|
+
shortSpread *= inventorySpreadScale;
|
|
440
|
+
}
|
|
441
|
+
|
|
377
442
|
const effectiveLeverage = calculateEffectiveLeverage(
|
|
378
443
|
baseSpread,
|
|
379
444
|
quoteAssetReserve,
|
|
@@ -447,7 +512,10 @@ export function calculateSpread(
|
|
|
447
512
|
amm.pegMultiplier,
|
|
448
513
|
amm.netBaseAssetAmount,
|
|
449
514
|
markPrice,
|
|
450
|
-
amm.totalFeeMinusDistributions
|
|
515
|
+
amm.totalFeeMinusDistributions,
|
|
516
|
+
amm.baseAssetReserve,
|
|
517
|
+
amm.minBaseAssetReserve,
|
|
518
|
+
amm.maxBaseAssetReserve
|
|
451
519
|
);
|
|
452
520
|
|
|
453
521
|
let spread: number;
|
|
@@ -548,7 +616,7 @@ export function getSwapDirection(
|
|
|
548
616
|
* @param market
|
|
549
617
|
* @returns cost : Precision MARK_PRICE_PRECISION
|
|
550
618
|
*/
|
|
551
|
-
export function calculateTerminalPrice(market:
|
|
619
|
+
export function calculateTerminalPrice(market: PerpMarketAccount) {
|
|
552
620
|
const directionToClose = market.amm.netBaseAssetAmount.gt(ZERO)
|
|
553
621
|
? PositionDirection.SHORT
|
|
554
622
|
: PositionDirection.LONG;
|