@drift-labs/sdk 2.124.0-beta.2 → 2.124.0-beta.4
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/VERSION +1 -1
- package/lib/browser/math/amm.js +3 -3
- package/lib/browser/math/auction.d.ts +7 -1
- package/lib/browser/math/auction.js +58 -1
- package/lib/node/math/amm.js +3 -3
- package/lib/node/math/auction.d.ts +7 -1
- package/lib/node/math/auction.d.ts.map +1 -1
- package/lib/node/math/auction.js +58 -1
- package/package.json +1 -1
- package/src/math/amm.ts +3 -3
- package/src/math/auction.ts +96 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.124.0-beta.
|
|
1
|
+
2.124.0-beta.4
|
package/lib/browser/math/amm.js
CHANGED
|
@@ -282,16 +282,16 @@ function calculateVolSpreadBN(lastOracleConfPct, reservePrice, markStd, oracleSt
|
|
|
282
282
|
.add(oracleStd)
|
|
283
283
|
.mul(numericConstants_1.PERCENTAGE_PRECISION)
|
|
284
284
|
.div(reservePrice)
|
|
285
|
-
.div(new anchor_1.BN(
|
|
285
|
+
.div(new anchor_1.BN(4));
|
|
286
286
|
const volSpread = anchor_1.BN.max(lastOracleConfPct, marketAvgStdPct.div(new anchor_1.BN(2)));
|
|
287
287
|
const clampMin = numericConstants_1.PERCENTAGE_PRECISION.div(new anchor_1.BN(100));
|
|
288
|
-
const clampMax = numericConstants_1.PERCENTAGE_PRECISION
|
|
288
|
+
const clampMax = numericConstants_1.PERCENTAGE_PRECISION;
|
|
289
289
|
const longVolSpreadFactor = (0, __1.clampBN)(longIntensity.mul(numericConstants_1.PERCENTAGE_PRECISION).div(anchor_1.BN.max(numericConstants_1.ONE, volume24H)), clampMin, clampMax);
|
|
290
290
|
const shortVolSpreadFactor = (0, __1.clampBN)(shortIntensity.mul(numericConstants_1.PERCENTAGE_PRECISION).div(anchor_1.BN.max(numericConstants_1.ONE, volume24H)), clampMin, clampMax);
|
|
291
291
|
// only consider confidence interval at full value when above 25 bps
|
|
292
292
|
let confComponent = lastOracleConfPct;
|
|
293
293
|
if (lastOracleConfPct.lte(numericConstants_1.PRICE_PRECISION.div(new anchor_1.BN(400)))) {
|
|
294
|
-
confComponent = lastOracleConfPct.div(new anchor_1.BN(
|
|
294
|
+
confComponent = lastOracleConfPct.div(new anchor_1.BN(20));
|
|
295
295
|
}
|
|
296
296
|
const longVolSpread = anchor_1.BN.max(confComponent, volSpread.mul(longVolSpreadFactor).div(numericConstants_1.PERCENTAGE_PRECISION));
|
|
297
297
|
const shortVolSpread = anchor_1.BN.max(confComponent, volSpread.mul(shortVolSpreadFactor).div(numericConstants_1.PERCENTAGE_PRECISION));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { Order, PositionDirection } from '../types';
|
|
3
|
-
import { BN } from '../.';
|
|
3
|
+
import { BN, PerpMarketAccount } from '../.';
|
|
4
4
|
export declare function isAuctionComplete(order: Order, slot: number): boolean;
|
|
5
5
|
export declare function isFallbackAvailableLiquiditySource(order: Order, minAuctionDuration: number, slot: number): boolean;
|
|
6
6
|
export declare function getAuctionPrice(order: Order, slot: number, oraclePrice: BN): BN;
|
|
@@ -21,3 +21,9 @@ export declare function deriveOracleAuctionParams({ direction, oraclePrice, auct
|
|
|
21
21
|
auctionEndPrice: BN;
|
|
22
22
|
oraclePriceOffset: number;
|
|
23
23
|
};
|
|
24
|
+
export declare function getTriggerAuctionStartPrice(params: {
|
|
25
|
+
perpMarket: PerpMarketAccount;
|
|
26
|
+
direction: PositionDirection;
|
|
27
|
+
oraclePrice: BN;
|
|
28
|
+
limitPrice?: BN;
|
|
29
|
+
}): BN;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deriveOracleAuctionParams = exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isFallbackAvailableLiquiditySource = exports.isAuctionComplete = void 0;
|
|
3
|
+
exports.getTriggerAuctionStartPrice = exports.deriveOracleAuctionParams = exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isFallbackAvailableLiquiditySource = exports.isAuctionComplete = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const _1 = require("../.");
|
|
6
6
|
function isAuctionComplete(order, slot) {
|
|
@@ -132,3 +132,60 @@ function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice,
|
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
exports.deriveOracleAuctionParams = deriveOracleAuctionParams;
|
|
135
|
+
function getTriggerAuctionStartPrice(params) {
|
|
136
|
+
const { perpMarket, direction, oraclePrice, limitPrice } = params;
|
|
137
|
+
const twapMismatch = perpMarket.amm.historicalOracleData.lastOraclePriceTwapTs
|
|
138
|
+
.sub(perpMarket.amm.lastMarkPriceTwapTs)
|
|
139
|
+
.abs()
|
|
140
|
+
.gte(new _1.BN(60)) ||
|
|
141
|
+
perpMarket.amm.volume24H.lte(new _1.BN(100000).mul(_1.QUOTE_PRECISION));
|
|
142
|
+
let baselineStartOffset;
|
|
143
|
+
if (twapMismatch) {
|
|
144
|
+
const contractTierNumber = (0, _1.getPerpMarketTierNumber)(perpMarket);
|
|
145
|
+
const priceDivisor = contractTierNumber <= 1 ? 500 : 100;
|
|
146
|
+
baselineStartOffset = (0, types_1.isVariant)(direction, 'long')
|
|
147
|
+
? perpMarket.amm.lastBidPriceTwap.divn(priceDivisor)
|
|
148
|
+
: perpMarket.amm.lastAskPriceTwap.divn(priceDivisor).neg();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const markTwapSlow = (0, types_1.isVariant)(direction, 'long')
|
|
152
|
+
? perpMarket.amm.lastBidPriceTwap
|
|
153
|
+
: perpMarket.amm.lastAskPriceTwap;
|
|
154
|
+
const markTwapFast = perpMarket.amm.lastMarkPriceTwap5Min;
|
|
155
|
+
const oracleTwapSlow = perpMarket.amm.historicalOracleData.lastOraclePriceTwap;
|
|
156
|
+
const oracleTwapFast = perpMarket.amm.historicalOracleData.lastOraclePriceTwap5Min;
|
|
157
|
+
const offsetSlow = markTwapSlow.sub(oracleTwapSlow);
|
|
158
|
+
const offsetFast = markTwapFast.sub(oracleTwapFast);
|
|
159
|
+
const fracOfLongSpreadInPrice = new _1.BN(perpMarket.amm.longSpread)
|
|
160
|
+
.mul(markTwapSlow)
|
|
161
|
+
.div(_1.PRICE_PRECISION.muln(10)); // divide by 10x for safety
|
|
162
|
+
const fracOfShortSpreadInPrice = new _1.BN(perpMarket.amm.shortSpread)
|
|
163
|
+
.mul(markTwapSlow)
|
|
164
|
+
.div(_1.PRICE_PRECISION.muln(10)); // divide by 10x for safety
|
|
165
|
+
baselineStartOffset = (0, types_1.isVariant)(direction, 'long')
|
|
166
|
+
? _1.BN.min(offsetSlow.add(fracOfLongSpreadInPrice), offsetFast.sub(fracOfShortSpreadInPrice))
|
|
167
|
+
: _1.BN.max(offsetSlow.sub(fracOfShortSpreadInPrice), offsetFast.add(fracOfLongSpreadInPrice));
|
|
168
|
+
}
|
|
169
|
+
let startBuffer = -3500;
|
|
170
|
+
if ((0, types_1.isVariant)(perpMarket.contractTier, 'a') ||
|
|
171
|
+
(0, types_1.isVariant)(perpMarket.contractTier, 'b')) {
|
|
172
|
+
startBuffer = -500;
|
|
173
|
+
}
|
|
174
|
+
// Apply start buffer (in BPS)
|
|
175
|
+
const startBufferPrice = oraclePrice
|
|
176
|
+
.mul(new _1.BN(startBuffer))
|
|
177
|
+
.div(new _1.BN(_1.PRICE_PRECISION));
|
|
178
|
+
let auctionStartPrice = (0, types_1.isVariant)(direction, 'long')
|
|
179
|
+
? oraclePrice.add(baselineStartOffset).sub(startBufferPrice)
|
|
180
|
+
: oraclePrice.add(baselineStartOffset).add(startBufferPrice);
|
|
181
|
+
if (limitPrice) {
|
|
182
|
+
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
183
|
+
auctionStartPrice = _1.BN.min(auctionStartPrice, limitPrice);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
auctionStartPrice = _1.BN.max(auctionStartPrice, limitPrice);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return auctionStartPrice;
|
|
190
|
+
}
|
|
191
|
+
exports.getTriggerAuctionStartPrice = getTriggerAuctionStartPrice;
|
package/lib/node/math/amm.js
CHANGED
|
@@ -282,16 +282,16 @@ function calculateVolSpreadBN(lastOracleConfPct, reservePrice, markStd, oracleSt
|
|
|
282
282
|
.add(oracleStd)
|
|
283
283
|
.mul(numericConstants_1.PERCENTAGE_PRECISION)
|
|
284
284
|
.div(reservePrice)
|
|
285
|
-
.div(new anchor_1.BN(
|
|
285
|
+
.div(new anchor_1.BN(4));
|
|
286
286
|
const volSpread = anchor_1.BN.max(lastOracleConfPct, marketAvgStdPct.div(new anchor_1.BN(2)));
|
|
287
287
|
const clampMin = numericConstants_1.PERCENTAGE_PRECISION.div(new anchor_1.BN(100));
|
|
288
|
-
const clampMax = numericConstants_1.PERCENTAGE_PRECISION
|
|
288
|
+
const clampMax = numericConstants_1.PERCENTAGE_PRECISION;
|
|
289
289
|
const longVolSpreadFactor = (0, __1.clampBN)(longIntensity.mul(numericConstants_1.PERCENTAGE_PRECISION).div(anchor_1.BN.max(numericConstants_1.ONE, volume24H)), clampMin, clampMax);
|
|
290
290
|
const shortVolSpreadFactor = (0, __1.clampBN)(shortIntensity.mul(numericConstants_1.PERCENTAGE_PRECISION).div(anchor_1.BN.max(numericConstants_1.ONE, volume24H)), clampMin, clampMax);
|
|
291
291
|
// only consider confidence interval at full value when above 25 bps
|
|
292
292
|
let confComponent = lastOracleConfPct;
|
|
293
293
|
if (lastOracleConfPct.lte(numericConstants_1.PRICE_PRECISION.div(new anchor_1.BN(400)))) {
|
|
294
|
-
confComponent = lastOracleConfPct.div(new anchor_1.BN(
|
|
294
|
+
confComponent = lastOracleConfPct.div(new anchor_1.BN(20));
|
|
295
295
|
}
|
|
296
296
|
const longVolSpread = anchor_1.BN.max(confComponent, volSpread.mul(longVolSpreadFactor).div(numericConstants_1.PERCENTAGE_PRECISION));
|
|
297
297
|
const shortVolSpread = anchor_1.BN.max(confComponent, volSpread.mul(shortVolSpreadFactor).div(numericConstants_1.PERCENTAGE_PRECISION));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { Order, PositionDirection } from '../types';
|
|
3
|
-
import { BN } from '../.';
|
|
3
|
+
import { BN, PerpMarketAccount } from '../.';
|
|
4
4
|
export declare function isAuctionComplete(order: Order, slot: number): boolean;
|
|
5
5
|
export declare function isFallbackAvailableLiquiditySource(order: Order, minAuctionDuration: number, slot: number): boolean;
|
|
6
6
|
export declare function getAuctionPrice(order: Order, slot: number, oraclePrice: BN): BN;
|
|
@@ -21,4 +21,10 @@ export declare function deriveOracleAuctionParams({ direction, oraclePrice, auct
|
|
|
21
21
|
auctionEndPrice: BN;
|
|
22
22
|
oraclePriceOffset: number;
|
|
23
23
|
};
|
|
24
|
+
export declare function getTriggerAuctionStartPrice(params: {
|
|
25
|
+
perpMarket: PerpMarketAccount;
|
|
26
|
+
direction: PositionDirection;
|
|
27
|
+
oraclePrice: BN;
|
|
28
|
+
limitPrice?: BN;
|
|
29
|
+
}): BN;
|
|
24
30
|
//# sourceMappingURL=auction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auction.d.ts","sourceRoot":"","sources":["../../../src/math/auction.ts"],"names":[],"mappings":";AAAA,OAAO,EAA6B,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,
|
|
1
|
+
{"version":3,"file":"auction.d.ts","sourceRoot":"","sources":["../../../src/math/auction.ts"],"names":[],"mappings":";AAAA,OAAO,EAA6B,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EACN,EAAE,EAKF,iBAAiB,EAIjB,MAAM,MAAM,CAAC;AAEd,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMrE;AAED,wBAAgB,kCAAkC,CACjD,KAAK,EAAE,KAAK,EACZ,kBAAkB,EAAE,MAAM,EAC1B,IAAI,EAAE,MAAM,GACV,OAAO,CAMT;AAED,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,EAAE,GACb,EAAE,CAwBJ;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,CA+B7E;AAED,wBAAgB,qCAAqC,CACpD,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,EAAE,GACb,EAAE,CA+BJ;AAED,wBAAgB,yBAAyB,CAAC,EACzC,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,gBAAgB,GAChB,EAAE;IACF,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,EAAE,CAAC;IAChB,iBAAiB,EAAE,EAAE,CAAC;IACtB,eAAe,EAAE,EAAE,CAAC;IACpB,UAAU,EAAE,EAAE,CAAC;IACf,gBAAgB,CAAC,EAAE;QAClB,GAAG,EAAE,EAAE,CAAC;QACR,GAAG,EAAE,EAAE,CAAC;KACR,CAAC;CACF,GAAG;IAAE,iBAAiB,EAAE,EAAE,CAAC;IAAC,eAAe,EAAE,EAAE,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAsC5E;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IACnD,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,EAAE,CAAC;CAChB,GAAG,EAAE,CA8EL"}
|
package/lib/node/math/auction.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deriveOracleAuctionParams = exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isFallbackAvailableLiquiditySource = exports.isAuctionComplete = void 0;
|
|
3
|
+
exports.getTriggerAuctionStartPrice = exports.deriveOracleAuctionParams = exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isFallbackAvailableLiquiditySource = exports.isAuctionComplete = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const _1 = require("../.");
|
|
6
6
|
function isAuctionComplete(order, slot) {
|
|
@@ -132,3 +132,60 @@ function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice,
|
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
exports.deriveOracleAuctionParams = deriveOracleAuctionParams;
|
|
135
|
+
function getTriggerAuctionStartPrice(params) {
|
|
136
|
+
const { perpMarket, direction, oraclePrice, limitPrice } = params;
|
|
137
|
+
const twapMismatch = perpMarket.amm.historicalOracleData.lastOraclePriceTwapTs
|
|
138
|
+
.sub(perpMarket.amm.lastMarkPriceTwapTs)
|
|
139
|
+
.abs()
|
|
140
|
+
.gte(new _1.BN(60)) ||
|
|
141
|
+
perpMarket.amm.volume24H.lte(new _1.BN(100000).mul(_1.QUOTE_PRECISION));
|
|
142
|
+
let baselineStartOffset;
|
|
143
|
+
if (twapMismatch) {
|
|
144
|
+
const contractTierNumber = (0, _1.getPerpMarketTierNumber)(perpMarket);
|
|
145
|
+
const priceDivisor = contractTierNumber <= 1 ? 500 : 100;
|
|
146
|
+
baselineStartOffset = (0, types_1.isVariant)(direction, 'long')
|
|
147
|
+
? perpMarket.amm.lastBidPriceTwap.divn(priceDivisor)
|
|
148
|
+
: perpMarket.amm.lastAskPriceTwap.divn(priceDivisor).neg();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const markTwapSlow = (0, types_1.isVariant)(direction, 'long')
|
|
152
|
+
? perpMarket.amm.lastBidPriceTwap
|
|
153
|
+
: perpMarket.amm.lastAskPriceTwap;
|
|
154
|
+
const markTwapFast = perpMarket.amm.lastMarkPriceTwap5Min;
|
|
155
|
+
const oracleTwapSlow = perpMarket.amm.historicalOracleData.lastOraclePriceTwap;
|
|
156
|
+
const oracleTwapFast = perpMarket.amm.historicalOracleData.lastOraclePriceTwap5Min;
|
|
157
|
+
const offsetSlow = markTwapSlow.sub(oracleTwapSlow);
|
|
158
|
+
const offsetFast = markTwapFast.sub(oracleTwapFast);
|
|
159
|
+
const fracOfLongSpreadInPrice = new _1.BN(perpMarket.amm.longSpread)
|
|
160
|
+
.mul(markTwapSlow)
|
|
161
|
+
.div(_1.PRICE_PRECISION.muln(10)); // divide by 10x for safety
|
|
162
|
+
const fracOfShortSpreadInPrice = new _1.BN(perpMarket.amm.shortSpread)
|
|
163
|
+
.mul(markTwapSlow)
|
|
164
|
+
.div(_1.PRICE_PRECISION.muln(10)); // divide by 10x for safety
|
|
165
|
+
baselineStartOffset = (0, types_1.isVariant)(direction, 'long')
|
|
166
|
+
? _1.BN.min(offsetSlow.add(fracOfLongSpreadInPrice), offsetFast.sub(fracOfShortSpreadInPrice))
|
|
167
|
+
: _1.BN.max(offsetSlow.sub(fracOfShortSpreadInPrice), offsetFast.add(fracOfLongSpreadInPrice));
|
|
168
|
+
}
|
|
169
|
+
let startBuffer = -3500;
|
|
170
|
+
if ((0, types_1.isVariant)(perpMarket.contractTier, 'a') ||
|
|
171
|
+
(0, types_1.isVariant)(perpMarket.contractTier, 'b')) {
|
|
172
|
+
startBuffer = -500;
|
|
173
|
+
}
|
|
174
|
+
// Apply start buffer (in BPS)
|
|
175
|
+
const startBufferPrice = oraclePrice
|
|
176
|
+
.mul(new _1.BN(startBuffer))
|
|
177
|
+
.div(new _1.BN(_1.PRICE_PRECISION));
|
|
178
|
+
let auctionStartPrice = (0, types_1.isVariant)(direction, 'long')
|
|
179
|
+
? oraclePrice.add(baselineStartOffset).sub(startBufferPrice)
|
|
180
|
+
: oraclePrice.add(baselineStartOffset).add(startBufferPrice);
|
|
181
|
+
if (limitPrice) {
|
|
182
|
+
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
183
|
+
auctionStartPrice = _1.BN.min(auctionStartPrice, limitPrice);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
auctionStartPrice = _1.BN.max(auctionStartPrice, limitPrice);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return auctionStartPrice;
|
|
190
|
+
}
|
|
191
|
+
exports.getTriggerAuctionStartPrice = getTriggerAuctionStartPrice;
|
package/package.json
CHANGED
package/src/math/amm.ts
CHANGED
|
@@ -547,11 +547,11 @@ export function calculateVolSpreadBN(
|
|
|
547
547
|
.add(oracleStd)
|
|
548
548
|
.mul(PERCENTAGE_PRECISION)
|
|
549
549
|
.div(reservePrice)
|
|
550
|
-
.div(new BN(
|
|
550
|
+
.div(new BN(4));
|
|
551
551
|
const volSpread = BN.max(lastOracleConfPct, marketAvgStdPct.div(new BN(2)));
|
|
552
552
|
|
|
553
553
|
const clampMin = PERCENTAGE_PRECISION.div(new BN(100));
|
|
554
|
-
const clampMax = PERCENTAGE_PRECISION
|
|
554
|
+
const clampMax = PERCENTAGE_PRECISION;
|
|
555
555
|
|
|
556
556
|
const longVolSpreadFactor = clampBN(
|
|
557
557
|
longIntensity.mul(PERCENTAGE_PRECISION).div(BN.max(ONE, volume24H)),
|
|
@@ -568,7 +568,7 @@ export function calculateVolSpreadBN(
|
|
|
568
568
|
let confComponent = lastOracleConfPct;
|
|
569
569
|
|
|
570
570
|
if (lastOracleConfPct.lte(PRICE_PRECISION.div(new BN(400)))) {
|
|
571
|
-
confComponent = lastOracleConfPct.div(new BN(
|
|
571
|
+
confComponent = lastOracleConfPct.div(new BN(20));
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
const longVolSpread = BN.max(
|
package/src/math/auction.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { isOneOfVariant, isVariant, Order, PositionDirection } from '../types';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BN,
|
|
4
|
+
getVariant,
|
|
5
|
+
ONE,
|
|
6
|
+
OrderBitFlag,
|
|
7
|
+
ZERO,
|
|
8
|
+
PerpMarketAccount,
|
|
9
|
+
getPerpMarketTierNumber,
|
|
10
|
+
QUOTE_PRECISION,
|
|
11
|
+
PRICE_PRECISION,
|
|
12
|
+
} from '../.';
|
|
3
13
|
|
|
4
14
|
export function isAuctionComplete(order: Order, slot: number): boolean {
|
|
5
15
|
if (order.auctionDuration === 0) {
|
|
@@ -177,3 +187,88 @@ export function deriveOracleAuctionParams({
|
|
|
177
187
|
oraclePriceOffset: oraclePriceOffsetNum,
|
|
178
188
|
};
|
|
179
189
|
}
|
|
190
|
+
|
|
191
|
+
export function getTriggerAuctionStartPrice(params: {
|
|
192
|
+
perpMarket: PerpMarketAccount;
|
|
193
|
+
direction: PositionDirection;
|
|
194
|
+
oraclePrice: BN;
|
|
195
|
+
limitPrice?: BN;
|
|
196
|
+
}): BN {
|
|
197
|
+
const { perpMarket, direction, oraclePrice, limitPrice } = params;
|
|
198
|
+
|
|
199
|
+
const twapMismatch =
|
|
200
|
+
perpMarket.amm.historicalOracleData.lastOraclePriceTwapTs
|
|
201
|
+
.sub(perpMarket.amm.lastMarkPriceTwapTs)
|
|
202
|
+
.abs()
|
|
203
|
+
.gte(new BN(60)) ||
|
|
204
|
+
perpMarket.amm.volume24H.lte(new BN(100_000).mul(QUOTE_PRECISION));
|
|
205
|
+
|
|
206
|
+
let baselineStartOffset: BN;
|
|
207
|
+
|
|
208
|
+
if (twapMismatch) {
|
|
209
|
+
const contractTierNumber = getPerpMarketTierNumber(perpMarket);
|
|
210
|
+
const priceDivisor = contractTierNumber <= 1 ? 500 : 100;
|
|
211
|
+
baselineStartOffset = isVariant(direction, 'long')
|
|
212
|
+
? perpMarket.amm.lastBidPriceTwap.divn(priceDivisor)
|
|
213
|
+
: perpMarket.amm.lastAskPriceTwap.divn(priceDivisor).neg();
|
|
214
|
+
} else {
|
|
215
|
+
const markTwapSlow = isVariant(direction, 'long')
|
|
216
|
+
? perpMarket.amm.lastBidPriceTwap
|
|
217
|
+
: perpMarket.amm.lastAskPriceTwap;
|
|
218
|
+
|
|
219
|
+
const markTwapFast = perpMarket.amm.lastMarkPriceTwap5Min;
|
|
220
|
+
const oracleTwapSlow =
|
|
221
|
+
perpMarket.amm.historicalOracleData.lastOraclePriceTwap;
|
|
222
|
+
const oracleTwapFast =
|
|
223
|
+
perpMarket.amm.historicalOracleData.lastOraclePriceTwap5Min;
|
|
224
|
+
|
|
225
|
+
const offsetSlow = markTwapSlow.sub(oracleTwapSlow);
|
|
226
|
+
const offsetFast = markTwapFast.sub(oracleTwapFast);
|
|
227
|
+
|
|
228
|
+
const fracOfLongSpreadInPrice = new BN(perpMarket.amm.longSpread)
|
|
229
|
+
.mul(markTwapSlow)
|
|
230
|
+
.div(PRICE_PRECISION.muln(10)); // divide by 10x for safety
|
|
231
|
+
|
|
232
|
+
const fracOfShortSpreadInPrice = new BN(perpMarket.amm.shortSpread)
|
|
233
|
+
.mul(markTwapSlow)
|
|
234
|
+
.div(PRICE_PRECISION.muln(10)); // divide by 10x for safety
|
|
235
|
+
|
|
236
|
+
baselineStartOffset = isVariant(direction, 'long')
|
|
237
|
+
? BN.min(
|
|
238
|
+
offsetSlow.add(fracOfLongSpreadInPrice),
|
|
239
|
+
offsetFast.sub(fracOfShortSpreadInPrice)
|
|
240
|
+
)
|
|
241
|
+
: BN.max(
|
|
242
|
+
offsetSlow.sub(fracOfShortSpreadInPrice),
|
|
243
|
+
offsetFast.add(fracOfLongSpreadInPrice)
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let startBuffer = -3500;
|
|
248
|
+
|
|
249
|
+
if (
|
|
250
|
+
isVariant(perpMarket.contractTier, 'a') ||
|
|
251
|
+
isVariant(perpMarket.contractTier, 'b')
|
|
252
|
+
) {
|
|
253
|
+
startBuffer = -500;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Apply start buffer (in BPS)
|
|
257
|
+
const startBufferPrice = oraclePrice
|
|
258
|
+
.mul(new BN(startBuffer))
|
|
259
|
+
.div(new BN(PRICE_PRECISION));
|
|
260
|
+
|
|
261
|
+
let auctionStartPrice = isVariant(direction, 'long')
|
|
262
|
+
? oraclePrice.add(baselineStartOffset).sub(startBufferPrice)
|
|
263
|
+
: oraclePrice.add(baselineStartOffset).add(startBufferPrice);
|
|
264
|
+
|
|
265
|
+
if (limitPrice) {
|
|
266
|
+
if (isVariant(direction, 'long')) {
|
|
267
|
+
auctionStartPrice = BN.min(auctionStartPrice, limitPrice);
|
|
268
|
+
} else {
|
|
269
|
+
auctionStartPrice = BN.max(auctionStartPrice, limitPrice);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return auctionStartPrice;
|
|
274
|
+
}
|