|
1 | 1 | import { isOneOfVariant, isVariant, Order, PositionDirection } from '../types';
|
2 |
| -import { BN, getVariant, ONE, OrderBitFlag, ZERO } from '../.'; |
| 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 | +} |
0 commit comments