@drift-labs/sdk 0.2.0-master.26 → 0.2.0-master.27
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 +1 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +3 -0
- package/lib/accounts/types.d.ts +1 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +1 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +3 -0
- package/lib/admin.d.ts +5 -2
- package/lib/admin.js +30 -4
- package/lib/clearingHouse.d.ts +2 -0
- package/lib/clearingHouse.js +14 -1
- package/lib/clearingHouseUser.d.ts +11 -9
- package/lib/clearingHouseUser.js +182 -106
- package/lib/config.js +1 -1
- package/lib/dlob/DLOB.d.ts +73 -0
- package/lib/dlob/DLOB.js +557 -0
- package/lib/dlob/DLOBNode.d.ts +52 -0
- package/lib/dlob/DLOBNode.js +82 -0
- package/lib/dlob/NodeList.d.ts +26 -0
- package/lib/dlob/NodeList.js +138 -0
- package/lib/idl/clearing_house.json +122 -202
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -0
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +1 -1
- package/lib/math/orders.d.ts +3 -3
- package/lib/math/orders.js +31 -16
- package/lib/math/spotBalance.d.ts +3 -0
- package/lib/math/spotBalance.js +18 -1
- package/lib/math/spotPosition.d.ts +5 -1
- package/lib/math/spotPosition.js +16 -1
- package/lib/types.d.ts +24 -23
- package/lib/types.js +9 -3
- package/lib/userMap/userMap.d.ts +25 -0
- package/lib/userMap/userMap.js +73 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/package.json +6 -3
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +4 -0
- package/src/accounts/types.ts +1 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +6 -0
- package/src/addresses/marketAddresses.js +26 -0
- package/src/admin.ts +50 -8
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.ts +23 -1
- package/src/clearingHouseUser.ts +364 -165
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/{perpMarkets.js → markets.js} +11 -11
- package/src/dlob/DLOB.ts +884 -0
- package/src/dlob/DLOBNode.ts +163 -0
- package/src/dlob/NodeList.ts +185 -0
- package/src/events/eventList.js +23 -66
- package/src/events/txEventCache.js +19 -22
- package/src/examples/makeTradeExample.js +157 -0
- package/src/factory/bigNum.js +180 -183
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +122 -202
- package/src/index.ts +5 -0
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +3 -4
- package/src/math/funding.js +175 -223
- package/src/math/market.ts +1 -1
- package/src/math/orders.ts +29 -21
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.ts +26 -0
- package/src/math/spotPosition.ts +42 -1
- package/src/math/trade.js +74 -81
- package/src/math/utils.js +7 -8
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.js +9 -10
- package/src/oracles/pythClient.js +17 -52
- package/src/oracles/quoteAssetOracleClient.js +13 -44
- package/src/oracles/switchboardClient.js +37 -69
- package/src/oracles/types.js +1 -1
- package/src/token/index.js +4 -4
- package/src/tx/types.js +1 -1
- package/src/tx/utils.js +6 -7
- package/src/types.ts +25 -23
- package/src/userMap/userMap.ts +100 -0
- package/src/userMap/userStatsMap.ts +110 -0
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +11 -46
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +12 -46
- package/src/wallet.js +18 -55
- package/tests/bn/test.ts +2 -3
- package/tests/dlob/helpers.ts +322 -0
- package/tests/dlob/test.ts +2865 -0
- package/my-script/.env +0 -7
- package/my-script/getUserStats.ts +0 -106
- package/my-script/multiConnections.ts +0 -119
- package/my-script/test-regex.ts +0 -11
- package/my-script/utils.ts +0 -52
- package/src/accounts/bulkAccountLoader.js +0 -249
- package/src/accounts/bulkUserStatsSubscription.js +0 -75
- package/src/accounts/bulkUserSubscription.js +0 -75
- package/src/accounts/fetch.js +0 -92
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -465
- package/src/accounts/pollingOracleSubscriber.js +0 -156
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -141
- package/src/accounts/pollingUserAccountSubscriber.js +0 -208
- package/src/accounts/pollingUserStatsAccountSubscriber.js +0 -208
- package/src/accounts/types.js +0 -28
- package/src/accounts/utils.js +0 -7
- package/src/accounts/webSocketAccountSubscriber.js +0 -138
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -433
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -113
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +0 -113
- package/src/addresses/pda.js +0 -186
- package/src/admin.js +0 -1284
- package/src/clearingHouse.js +0 -3433
- package/src/clearingHouseConfig.js +0 -2
- package/src/clearingHouseUser.js +0 -874
- package/src/clearingHouseUserConfig.js +0 -2
- package/src/clearingHouseUserStats.js +0 -115
- package/src/clearingHouseUserStatsConfig.js +0 -2
- package/src/config.js +0 -80
- package/src/constants/numericConstants.js +0 -48
- package/src/constants/spotMarkets.js +0 -51
- package/src/events/eventSubscriber.js +0 -202
- package/src/events/fetchLogs.js +0 -117
- package/src/events/pollingLogProvider.js +0 -113
- package/src/events/sort.js +0 -41
- package/src/events/types.js +0 -25
- package/src/events/webSocketLogProvider.js +0 -76
- package/src/index.js +0 -75
- package/src/math/amm.js +0 -422
- package/src/math/insurance.js +0 -27
- package/src/math/margin.js +0 -77
- package/src/math/market.js +0 -105
- package/src/math/oracles.js +0 -56
- package/src/math/orders.js +0 -153
- package/src/math/position.js +0 -172
- package/src/math/spotBalance.js +0 -176
- package/src/math/spotMarket.js +0 -8
- package/src/math/spotPosition.js +0 -8
- package/src/orderParams.js +0 -28
- package/src/serum/serumSubscriber.js +0 -102
- package/src/serum/types.js +0 -2
- package/src/slot/SlotSubscriber.js +0 -86
- package/src/tokenFaucet.js +0 -323
- package/src/tx/retryTxSender.js +0 -280
- package/src/types.js +0 -216
package/src/math/funding.js
CHANGED
|
@@ -8,39 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
exports.__esModule = true;
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
12
|
exports.calculateFundingPool = exports.calculateLongShortFundingRateAndLiveTwaps = exports.calculateLongShortFundingRate = exports.calculateEstimatedFundingRate = exports.calculateAllEstimatedFundingRate = void 0;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
var market_1 = require("./market");
|
|
13
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
14
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
15
|
+
const market_1 = require("./market");
|
|
44
16
|
/**
|
|
45
17
|
*
|
|
46
18
|
* @param market
|
|
@@ -48,139 +20,146 @@ var market_1 = require("./market");
|
|
|
48
20
|
* @param periodAdjustment
|
|
49
21
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
50
22
|
*/
|
|
51
|
-
function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
|
|
92
|
-
.mul(lastOracleTwapWithMantissa)
|
|
93
|
-
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
94
|
-
.div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
|
|
98
|
-
.mul(lastOracleTwapWithMantissa)
|
|
99
|
-
.add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
|
|
100
|
-
.div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
|
|
101
|
-
twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
|
|
102
|
-
twapSpreadPct = twapSpread
|
|
23
|
+
function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
// periodAdjustment
|
|
26
|
+
// 1: hourly
|
|
27
|
+
// 24: daily
|
|
28
|
+
// 24 * 365.25: annualized
|
|
29
|
+
const secondsInHour = new anchor_1.BN(3600);
|
|
30
|
+
const hoursInDay = new anchor_1.BN(24);
|
|
31
|
+
const ONE = new anchor_1.BN(1);
|
|
32
|
+
if (!market.initialized) {
|
|
33
|
+
return [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
34
|
+
}
|
|
35
|
+
const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
|
|
36
|
+
// todo: sufficiently differs from blockchain timestamp?
|
|
37
|
+
const now = new anchor_1.BN((Date.now() / 1000).toFixed(0));
|
|
38
|
+
const timeSinceLastUpdate = now.sub(market.amm.lastFundingRateTs);
|
|
39
|
+
// calculate real-time mark twap
|
|
40
|
+
const lastMarkTwapWithMantissa = market.amm.lastMarkPriceTwap;
|
|
41
|
+
const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
|
|
42
|
+
const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
|
|
43
|
+
const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
|
|
44
|
+
const baseAssetPriceWithMantissa = market_1.calculateMarkPrice(market, oraclePriceData);
|
|
45
|
+
const markTwapWithMantissa = markTwapTimeSinceLastUpdate
|
|
46
|
+
.mul(lastMarkTwapWithMantissa)
|
|
47
|
+
.add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
|
|
48
|
+
.div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
|
|
49
|
+
// calculate real-time (predicted) oracle twap
|
|
50
|
+
// note: oracle twap depends on `when the chord is struck` (market is trade)
|
|
51
|
+
const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
|
|
52
|
+
const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
|
|
53
|
+
const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
|
|
54
|
+
const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
|
|
55
|
+
const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
|
|
56
|
+
let oracleTwapWithMantissa = lastOracleTwapWithMantissa;
|
|
57
|
+
// if passing live oracle data, improve predicted calc estimate
|
|
58
|
+
if (oraclePriceData) {
|
|
59
|
+
const oraclePrice = oraclePriceData.price;
|
|
60
|
+
const oracleLiveVsTwap = oraclePrice
|
|
61
|
+
.sub(lastOracleTwapWithMantissa)
|
|
62
|
+
.abs()
|
|
103
63
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
104
64
|
.mul(new anchor_1.BN(100))
|
|
105
|
-
.div(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
.div(hoursInDay);
|
|
113
|
-
interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
|
|
114
|
-
interpRateQuote = twapSpreadPct
|
|
115
|
-
.mul(periodAdjustment)
|
|
116
|
-
.div(hoursInDay)
|
|
117
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
|
|
118
|
-
feePoolSize = calculateFundingPool(market);
|
|
119
|
-
if (interpRateQuote.lt(new anchor_1.BN(0))) {
|
|
120
|
-
feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
|
|
121
|
-
}
|
|
122
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
123
|
-
largerSide = market.baseAssetAmountLong.abs();
|
|
124
|
-
smallerSide = market.baseAssetAmountShort.abs();
|
|
125
|
-
if (twapSpread.gt(new anchor_1.BN(0))) {
|
|
126
|
-
return [2 /*return*/, [
|
|
127
|
-
markTwapWithMantissa,
|
|
128
|
-
oracleTwapWithMantissa,
|
|
129
|
-
lowerboundEst,
|
|
130
|
-
interpEst,
|
|
131
|
-
interpEst,
|
|
132
|
-
]];
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
136
|
-
largerSide = market.baseAssetAmountShort.abs();
|
|
137
|
-
smallerSide = market.baseAssetAmountLong.abs();
|
|
138
|
-
if (twapSpread.lt(new anchor_1.BN(0))) {
|
|
139
|
-
return [2 /*return*/, [
|
|
140
|
-
markTwapWithMantissa,
|
|
141
|
-
oracleTwapWithMantissa,
|
|
142
|
-
lowerboundEst,
|
|
143
|
-
interpEst,
|
|
144
|
-
interpEst,
|
|
145
|
-
]];
|
|
146
|
-
}
|
|
65
|
+
.div(lastOracleTwapWithMantissa);
|
|
66
|
+
// verify pyth live input is within 10% of last twap for live update
|
|
67
|
+
if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
|
|
68
|
+
oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
|
|
69
|
+
.mul(lastOracleTwapWithMantissa)
|
|
70
|
+
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
71
|
+
.div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
|
|
147
72
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
73
|
+
}
|
|
74
|
+
const shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
|
|
75
|
+
.mul(lastOracleTwapWithMantissa)
|
|
76
|
+
.add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
|
|
77
|
+
.div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
|
|
78
|
+
const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
|
|
79
|
+
const twapSpreadPct = twapSpread
|
|
80
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
81
|
+
.mul(new anchor_1.BN(100))
|
|
82
|
+
.div(shrunkLastOracleTwapwithMantissa);
|
|
83
|
+
const lowerboundEst = twapSpreadPct
|
|
84
|
+
.mul(payFreq)
|
|
85
|
+
.mul(anchor_1.BN.min(secondsInHour, timeSinceLastUpdate))
|
|
86
|
+
.mul(periodAdjustment)
|
|
87
|
+
.div(secondsInHour)
|
|
88
|
+
.div(secondsInHour)
|
|
89
|
+
.div(hoursInDay);
|
|
90
|
+
const interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
|
|
91
|
+
const interpRateQuote = twapSpreadPct
|
|
92
|
+
.mul(periodAdjustment)
|
|
93
|
+
.div(hoursInDay)
|
|
94
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
|
|
95
|
+
let feePoolSize = calculateFundingPool(market);
|
|
96
|
+
if (interpRateQuote.lt(new anchor_1.BN(0))) {
|
|
97
|
+
feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
|
|
98
|
+
}
|
|
99
|
+
let cappedAltEst;
|
|
100
|
+
let largerSide;
|
|
101
|
+
let smallerSide;
|
|
102
|
+
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
103
|
+
largerSide = market.baseAssetAmountLong.abs();
|
|
104
|
+
smallerSide = market.baseAssetAmountShort.abs();
|
|
105
|
+
if (twapSpread.gt(new anchor_1.BN(0))) {
|
|
106
|
+
return [
|
|
107
|
+
markTwapWithMantissa,
|
|
108
|
+
oracleTwapWithMantissa,
|
|
109
|
+
lowerboundEst,
|
|
110
|
+
interpEst,
|
|
111
|
+
interpEst,
|
|
112
|
+
];
|
|
175
113
|
}
|
|
176
|
-
|
|
114
|
+
}
|
|
115
|
+
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
116
|
+
largerSide = market.baseAssetAmountShort.abs();
|
|
117
|
+
smallerSide = market.baseAssetAmountLong.abs();
|
|
118
|
+
if (twapSpread.lt(new anchor_1.BN(0))) {
|
|
119
|
+
return [
|
|
177
120
|
markTwapWithMantissa,
|
|
178
121
|
oracleTwapWithMantissa,
|
|
179
122
|
lowerboundEst,
|
|
180
|
-
cappedAltEst,
|
|
181
123
|
interpEst,
|
|
182
|
-
|
|
183
|
-
|
|
124
|
+
interpEst,
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
return [
|
|
130
|
+
markTwapWithMantissa,
|
|
131
|
+
oracleTwapWithMantissa,
|
|
132
|
+
lowerboundEst,
|
|
133
|
+
interpEst,
|
|
134
|
+
interpEst,
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
if (largerSide.gt(numericConstants_1.ZERO)) {
|
|
138
|
+
// funding smaller flow
|
|
139
|
+
cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
|
|
140
|
+
const feePoolTopOff = feePoolSize
|
|
141
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
|
|
142
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
143
|
+
cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
|
|
144
|
+
cappedAltEst = cappedAltEst
|
|
145
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
146
|
+
.mul(new anchor_1.BN(100))
|
|
147
|
+
.div(oracleTwapWithMantissa)
|
|
148
|
+
.mul(periodAdjustment);
|
|
149
|
+
if (cappedAltEst.abs().gte(interpEst.abs())) {
|
|
150
|
+
cappedAltEst = interpEst;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
cappedAltEst = interpEst;
|
|
155
|
+
}
|
|
156
|
+
return [
|
|
157
|
+
markTwapWithMantissa,
|
|
158
|
+
oracleTwapWithMantissa,
|
|
159
|
+
lowerboundEst,
|
|
160
|
+
cappedAltEst,
|
|
161
|
+
interpEst,
|
|
162
|
+
];
|
|
184
163
|
});
|
|
185
164
|
}
|
|
186
165
|
exports.calculateAllEstimatedFundingRate = calculateAllEstimatedFundingRate;
|
|
@@ -192,28 +171,19 @@ exports.calculateAllEstimatedFundingRate = calculateAllEstimatedFundingRate;
|
|
|
192
171
|
* @param estimationMethod
|
|
193
172
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
194
173
|
*/
|
|
195
|
-
function calculateEstimatedFundingRate(market, oraclePriceData, periodAdjustment, estimationMethod) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
else if (estimationMethod == 'capped') {
|
|
209
|
-
return [2 /*return*/, cappedAltEst];
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
return [2 /*return*/, interpEst];
|
|
213
|
-
}
|
|
214
|
-
return [2 /*return*/];
|
|
215
|
-
}
|
|
216
|
-
});
|
|
174
|
+
function calculateEstimatedFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1), estimationMethod) {
|
|
175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
const [_1, _2, lowerboundEst, cappedAltEst, interpEst] = yield calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
177
|
+
if (estimationMethod == 'lowerbound') {
|
|
178
|
+
//assuming remaining funding period has no gap
|
|
179
|
+
return lowerboundEst;
|
|
180
|
+
}
|
|
181
|
+
else if (estimationMethod == 'capped') {
|
|
182
|
+
return cappedAltEst;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
return interpEst;
|
|
186
|
+
}
|
|
217
187
|
});
|
|
218
188
|
}
|
|
219
189
|
exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
|
|
@@ -224,27 +194,18 @@ exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
|
|
|
224
194
|
* @param periodAdjustment
|
|
225
195
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
226
196
|
*/
|
|
227
|
-
function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
|
|
240
|
-
return [2 /*return*/, [interpEst, cappedAltEst]];
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
return [2 /*return*/, [interpEst, interpEst]];
|
|
244
|
-
}
|
|
245
|
-
return [2 /*return*/];
|
|
246
|
-
}
|
|
247
|
-
});
|
|
197
|
+
function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
const [_1, _2, _, cappedAltEst, interpEst] = yield calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
200
|
+
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
|
|
201
|
+
return [cappedAltEst, interpEst];
|
|
202
|
+
}
|
|
203
|
+
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
|
|
204
|
+
return [interpEst, cappedAltEst];
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
return [interpEst, interpEst];
|
|
208
|
+
}
|
|
248
209
|
});
|
|
249
210
|
}
|
|
250
211
|
exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
|
|
@@ -255,27 +216,18 @@ exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
|
|
|
255
216
|
* @param periodAdjustment
|
|
256
217
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
257
218
|
*/
|
|
258
|
-
function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
271
|
-
return [2 /*return*/, [markTwapLive, oracleTwapLive, interpEst, cappedAltEst]];
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
return [2 /*return*/, [markTwapLive, oracleTwapLive, interpEst, interpEst]];
|
|
275
|
-
}
|
|
276
|
-
return [2 /*return*/];
|
|
277
|
-
}
|
|
278
|
-
});
|
|
219
|
+
function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
220
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
+
const [markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst] = yield calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
222
|
+
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
223
|
+
return [markTwapLive, oracleTwapLive, cappedAltEst, interpEst];
|
|
224
|
+
}
|
|
225
|
+
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
226
|
+
return [markTwapLive, oracleTwapLive, interpEst, cappedAltEst];
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
return [markTwapLive, oracleTwapLive, interpEst, interpEst];
|
|
230
|
+
}
|
|
279
231
|
});
|
|
280
232
|
}
|
|
281
233
|
exports.calculateLongShortFundingRateAndLiveTwaps = calculateLongShortFundingRateAndLiveTwaps;
|
|
@@ -286,8 +238,8 @@ exports.calculateLongShortFundingRateAndLiveTwaps = calculateLongShortFundingRat
|
|
|
286
238
|
*/
|
|
287
239
|
function calculateFundingPool(market) {
|
|
288
240
|
// todo
|
|
289
|
-
|
|
290
|
-
|
|
241
|
+
const totalFeeLB = market.amm.totalExchangeFee.div(new anchor_1.BN(2));
|
|
242
|
+
const feePool = anchor_1.BN.max(numericConstants_1.ZERO, market.amm.totalFeeMinusDistributions
|
|
291
243
|
.sub(totalFeeLB)
|
|
292
244
|
.mul(new anchor_1.BN(1))
|
|
293
245
|
.div(new anchor_1.BN(3)));
|
package/src/math/market.ts
CHANGED
|
@@ -68,7 +68,7 @@ export function calculateBidPrice(
|
|
|
68
68
|
* Calculates market ask price
|
|
69
69
|
*
|
|
70
70
|
* @param market
|
|
71
|
-
* @return
|
|
71
|
+
* @return askPrice : Precision MARK_PRICE_PRECISION
|
|
72
72
|
*/
|
|
73
73
|
export function calculateAskPrice(
|
|
74
74
|
market: PerpMarketAccount,
|
package/src/math/orders.ts
CHANGED
|
@@ -131,9 +131,9 @@ export function standardizeBaseAssetAmount(
|
|
|
131
131
|
|
|
132
132
|
export function getLimitPrice(
|
|
133
133
|
order: Order,
|
|
134
|
-
market: PerpMarketAccount,
|
|
135
134
|
oraclePriceData: OraclePriceData,
|
|
136
|
-
slot: number
|
|
135
|
+
slot: number,
|
|
136
|
+
perpMarket?: PerpMarketAccount
|
|
137
137
|
): BN {
|
|
138
138
|
let limitPrice;
|
|
139
139
|
if (!order.oraclePriceOffset.eq(ZERO)) {
|
|
@@ -143,14 +143,26 @@ export function getLimitPrice(
|
|
|
143
143
|
limitPrice = getAuctionPrice(order, slot);
|
|
144
144
|
} else if (!order.price.eq(ZERO)) {
|
|
145
145
|
limitPrice = order.price;
|
|
146
|
-
} else if (isVariant(order.direction, 'long')) {
|
|
147
|
-
const askPrice = calculateAskPrice(market, oraclePriceData);
|
|
148
|
-
const delta = askPrice.div(new BN(market.amm.maxSlippageRatio));
|
|
149
|
-
limitPrice = askPrice.add(delta);
|
|
150
146
|
} else {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
147
|
+
if (perpMarket) {
|
|
148
|
+
if (isVariant(order.direction, 'long')) {
|
|
149
|
+
const askPrice = calculateAskPrice(perpMarket, oraclePriceData);
|
|
150
|
+
const delta = askPrice.div(new BN(perpMarket.amm.maxSlippageRatio));
|
|
151
|
+
limitPrice = askPrice.add(delta);
|
|
152
|
+
} else {
|
|
153
|
+
const bidPrice = calculateBidPrice(perpMarket, oraclePriceData);
|
|
154
|
+
const delta = bidPrice.div(new BN(perpMarket.amm.maxSlippageRatio));
|
|
155
|
+
limitPrice = bidPrice.sub(delta);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
// check oracle validity?
|
|
159
|
+
const oraclePrice1Pct = oraclePriceData.price.div(new BN(100));
|
|
160
|
+
if (isVariant(order.direction, 'long')) {
|
|
161
|
+
limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
|
|
162
|
+
} else {
|
|
163
|
+
limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
154
166
|
}
|
|
155
167
|
} else {
|
|
156
168
|
limitPrice = order.price;
|
|
@@ -163,8 +175,7 @@ export function isFillableByVAMM(
|
|
|
163
175
|
order: Order,
|
|
164
176
|
market: PerpMarketAccount,
|
|
165
177
|
oraclePriceData: OraclePriceData,
|
|
166
|
-
slot: number
|
|
167
|
-
maxAuctionDuration: number
|
|
178
|
+
slot: number
|
|
168
179
|
): boolean {
|
|
169
180
|
return (
|
|
170
181
|
(isAuctionComplete(order, slot) &&
|
|
@@ -174,7 +185,7 @@ export function isFillableByVAMM(
|
|
|
174
185
|
oraclePriceData,
|
|
175
186
|
slot
|
|
176
187
|
).eq(ZERO)) ||
|
|
177
|
-
isOrderExpired(order, slot
|
|
188
|
+
isOrderExpired(order, slot)
|
|
178
189
|
);
|
|
179
190
|
}
|
|
180
191
|
|
|
@@ -191,7 +202,7 @@ export function calculateBaseAssetAmountForAmmToFulfill(
|
|
|
191
202
|
return ZERO;
|
|
192
203
|
}
|
|
193
204
|
|
|
194
|
-
const limitPrice = getLimitPrice(order,
|
|
205
|
+
const limitPrice = getLimitPrice(order, oraclePriceData, slot, market);
|
|
195
206
|
const baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(
|
|
196
207
|
order,
|
|
197
208
|
market,
|
|
@@ -246,17 +257,14 @@ function isSameDirection(
|
|
|
246
257
|
);
|
|
247
258
|
}
|
|
248
259
|
|
|
249
|
-
export function isOrderExpired(
|
|
250
|
-
order: Order,
|
|
251
|
-
slot: number,
|
|
252
|
-
maxAuctionDuration: number
|
|
253
|
-
): boolean {
|
|
260
|
+
export function isOrderExpired(order: Order, slot: number): boolean {
|
|
254
261
|
if (
|
|
255
|
-
|
|
256
|
-
!isVariant(order.status, 'open')
|
|
262
|
+
isOneOfVariant(order.orderType, ['triggerMarket', 'triggerLimit']) ||
|
|
263
|
+
!isVariant(order.status, 'open') ||
|
|
264
|
+
order.timeInForce === 0
|
|
257
265
|
) {
|
|
258
266
|
return false;
|
|
259
267
|
}
|
|
260
268
|
|
|
261
|
-
return new BN(slot).sub(order.slot).gt(new BN(
|
|
269
|
+
return new BN(slot).sub(order.slot).gt(new BN(order.timeInForce));
|
|
262
270
|
}
|