@drift-labs/sdk 2.2.0-beta.0 → 2.2.0-beta.2
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/dlob/DLOB.js +11 -1
- package/lib/idl/drift.json +8 -5
- package/lib/math/amm.js +1 -1
- package/lib/math/auction.d.ts +3 -1
- package/lib/math/auction.js +45 -3
- package/lib/math/orders.d.ts +1 -0
- package/lib/math/orders.js +13 -14
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -0
- package/package.json +1 -1
- package/src/dlob/DLOB.ts +15 -1
- package/src/idl/drift.json +8 -5
- package/src/math/amm.ts +1 -1
- package/src/math/auction.ts +53 -2
- package/src/math/orders.ts +11 -11
- package/src/types.ts +1 -0
package/lib/dlob/DLOB.js
CHANGED
|
@@ -4,6 +4,13 @@ exports.DLOB = void 0;
|
|
|
4
4
|
const NodeList_1 = require("./NodeList");
|
|
5
5
|
const __1 = require("..");
|
|
6
6
|
const exchangeStatus_1 = require("../math/exchangeStatus");
|
|
7
|
+
const SUPPORTED_ORDER_TYPES = [
|
|
8
|
+
'market',
|
|
9
|
+
'limit',
|
|
10
|
+
'triggerMarket',
|
|
11
|
+
'triggerLimit',
|
|
12
|
+
'oracle',
|
|
13
|
+
];
|
|
7
14
|
class DLOB {
|
|
8
15
|
constructor() {
|
|
9
16
|
this.openOrders = new Map();
|
|
@@ -118,6 +125,9 @@ class DLOB {
|
|
|
118
125
|
if ((0, __1.isVariant)(order.status, 'init')) {
|
|
119
126
|
return;
|
|
120
127
|
}
|
|
128
|
+
if (!(0, __1.isOneOfVariant)(order.orderType, SUPPORTED_ORDER_TYPES)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
121
131
|
const marketType = (0, __1.getVariant)(order.marketType);
|
|
122
132
|
if (!this.orderLists.get(marketType).has(order.marketIndex)) {
|
|
123
133
|
this.addOrderList(marketType, order.marketIndex);
|
|
@@ -200,7 +210,7 @@ class DLOB {
|
|
|
200
210
|
if (isInactiveTriggerOrder) {
|
|
201
211
|
type = 'trigger';
|
|
202
212
|
}
|
|
203
|
-
else if ((0, __1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
|
|
213
|
+
else if ((0, __1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket', 'oracle'])) {
|
|
204
214
|
type = 'market';
|
|
205
215
|
}
|
|
206
216
|
else if (order.oraclePriceOffset !== 0) {
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.0.
|
|
2
|
+
"version": "2.2.0-beta.2",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -4672,13 +4672,13 @@
|
|
|
4672
4672
|
{
|
|
4673
4673
|
"name": "auctionStartPrice",
|
|
4674
4674
|
"type": {
|
|
4675
|
-
"option": "
|
|
4675
|
+
"option": "i64"
|
|
4676
4676
|
}
|
|
4677
4677
|
},
|
|
4678
4678
|
{
|
|
4679
4679
|
"name": "auctionEndPrice",
|
|
4680
4680
|
"type": {
|
|
4681
|
-
"option": "
|
|
4681
|
+
"option": "i64"
|
|
4682
4682
|
}
|
|
4683
4683
|
}
|
|
4684
4684
|
]
|
|
@@ -5708,11 +5708,11 @@
|
|
|
5708
5708
|
},
|
|
5709
5709
|
{
|
|
5710
5710
|
"name": "auctionStartPrice",
|
|
5711
|
-
"type": "
|
|
5711
|
+
"type": "i64"
|
|
5712
5712
|
},
|
|
5713
5713
|
{
|
|
5714
5714
|
"name": "auctionEndPrice",
|
|
5715
|
-
"type": "
|
|
5715
|
+
"type": "i64"
|
|
5716
5716
|
},
|
|
5717
5717
|
{
|
|
5718
5718
|
"name": "maxTs",
|
|
@@ -6419,6 +6419,9 @@
|
|
|
6419
6419
|
},
|
|
6420
6420
|
{
|
|
6421
6421
|
"name": "TriggerLimit"
|
|
6422
|
+
},
|
|
6423
|
+
{
|
|
6424
|
+
"name": "Oracle"
|
|
6422
6425
|
}
|
|
6423
6426
|
]
|
|
6424
6427
|
}
|
package/lib/math/amm.js
CHANGED
|
@@ -324,7 +324,7 @@ function calculateSpreadBN(baseSpread, lastOracleReservePriceSpreadPct, lastOrac
|
|
|
324
324
|
spreadTerms.shortSpreadwEL = shortSpread;
|
|
325
325
|
if (netRevenueSinceLastFunding.lt(numericConstants_1.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT)) {
|
|
326
326
|
const revenueRetreatAmount = Math.min(maxTargetSpread / 10, Math.floor((baseSpread * netRevenueSinceLastFunding.abs().toNumber()) /
|
|
327
|
-
numericConstants_1.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT.toNumber()));
|
|
327
|
+
numericConstants_1.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT.abs().toNumber()));
|
|
328
328
|
const halfRevenueRetreatAmount = Math.floor(revenueRetreatAmount / 2);
|
|
329
329
|
spreadTerms.revenueRetreatAmount = revenueRetreatAmount;
|
|
330
330
|
spreadTerms.halfRevenueRetreatAmount = halfRevenueRetreatAmount;
|
package/lib/math/auction.d.ts
CHANGED
|
@@ -2,4 +2,6 @@
|
|
|
2
2
|
import { Order } from '../types';
|
|
3
3
|
import { BN } from '../.';
|
|
4
4
|
export declare function isAuctionComplete(order: Order, slot: number): boolean;
|
|
5
|
-
export declare function getAuctionPrice(order: Order, slot: number): BN;
|
|
5
|
+
export declare function getAuctionPrice(order: Order, slot: number, oraclePrice: BN): BN;
|
|
6
|
+
export declare function getAuctionPriceForFixedAuction(order: Order, slot: number): BN;
|
|
7
|
+
export declare function getAuctionPriceForOracleOffsetAuction(order: Order, slot: number, oraclePrice: BN): BN;
|
package/lib/math/auction.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAuctionPrice = exports.isAuctionComplete = void 0;
|
|
3
|
+
exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isAuctionComplete = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const _1 = require("../.");
|
|
6
6
|
function isAuctionComplete(order, slot) {
|
|
@@ -10,7 +10,19 @@ function isAuctionComplete(order, slot) {
|
|
|
10
10
|
return new _1.BN(slot).sub(order.slot).gt(new _1.BN(order.auctionDuration));
|
|
11
11
|
}
|
|
12
12
|
exports.isAuctionComplete = isAuctionComplete;
|
|
13
|
-
function getAuctionPrice(order, slot) {
|
|
13
|
+
function getAuctionPrice(order, slot, oraclePrice) {
|
|
14
|
+
if ((0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
|
|
15
|
+
return getAuctionPriceForFixedAuction(order, slot);
|
|
16
|
+
}
|
|
17
|
+
else if ((0, types_1.isVariant)(order.orderType, 'oracle')) {
|
|
18
|
+
return getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
throw Error(`Cant get auction price for order type ${order.orderType}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.getAuctionPrice = getAuctionPrice;
|
|
25
|
+
function getAuctionPriceForFixedAuction(order, slot) {
|
|
14
26
|
const slotsElapsed = new _1.BN(slot).sub(order.slot);
|
|
15
27
|
const deltaDenominator = new _1.BN(order.auctionDuration);
|
|
16
28
|
const deltaNumerator = _1.BN.min(slotsElapsed, deltaDenominator);
|
|
@@ -39,4 +51,34 @@ function getAuctionPrice(order, slot) {
|
|
|
39
51
|
}
|
|
40
52
|
return price;
|
|
41
53
|
}
|
|
42
|
-
exports.
|
|
54
|
+
exports.getAuctionPriceForFixedAuction = getAuctionPriceForFixedAuction;
|
|
55
|
+
function getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice) {
|
|
56
|
+
const slotsElapsed = new _1.BN(slot).sub(order.slot);
|
|
57
|
+
const deltaDenominator = new _1.BN(order.auctionDuration);
|
|
58
|
+
const deltaNumerator = _1.BN.min(slotsElapsed, deltaDenominator);
|
|
59
|
+
if (deltaDenominator.eq(_1.ZERO)) {
|
|
60
|
+
return order.auctionEndPrice.add(order.auctionEndPrice);
|
|
61
|
+
}
|
|
62
|
+
let priceOffsetDelta;
|
|
63
|
+
if ((0, types_1.isVariant)(order.direction, 'long')) {
|
|
64
|
+
priceOffsetDelta = order.auctionEndPrice
|
|
65
|
+
.sub(order.auctionStartPrice)
|
|
66
|
+
.mul(deltaNumerator)
|
|
67
|
+
.div(deltaDenominator);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
priceOffsetDelta = order.auctionStartPrice
|
|
71
|
+
.sub(order.auctionEndPrice)
|
|
72
|
+
.mul(deltaNumerator)
|
|
73
|
+
.div(deltaDenominator);
|
|
74
|
+
}
|
|
75
|
+
let priceOffset;
|
|
76
|
+
if ((0, types_1.isVariant)(order.direction, 'long')) {
|
|
77
|
+
priceOffset = order.auctionStartPrice.add(priceOffsetDelta);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
priceOffset = order.auctionStartPrice.sub(priceOffsetDelta);
|
|
81
|
+
}
|
|
82
|
+
return oraclePrice.add(priceOffset);
|
|
83
|
+
}
|
|
84
|
+
exports.getAuctionPriceForOracleOffsetAuction = getAuctionPriceForOracleOffsetAuction;
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare function isOrderReduceOnly(user: User, order: Order): boolean;
|
|
|
9
9
|
export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
|
|
10
10
|
export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number, fallbackPrice?: BN): BN | undefined;
|
|
11
11
|
export declare function hasLimitPrice(order: Order, slot: number): boolean;
|
|
12
|
+
export declare function hasAuctionPrice(order: Order, slot: number): boolean;
|
|
12
13
|
export declare function isFillableByVAMM(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number, ts: number): boolean;
|
|
13
14
|
export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
14
15
|
export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, amm: AMM, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
|
package/lib/math/orders.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@project-serum/anchor");
|
|
@@ -81,19 +81,14 @@ function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
|
|
|
81
81
|
exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
|
|
82
82
|
function getLimitPrice(order, oraclePriceData, slot, fallbackPrice) {
|
|
83
83
|
let limitPrice;
|
|
84
|
-
if (order
|
|
84
|
+
if (hasAuctionPrice(order, slot)) {
|
|
85
|
+
limitPrice = (0, auction_1.getAuctionPrice)(order, slot, oraclePriceData.price);
|
|
86
|
+
}
|
|
87
|
+
else if (order.oraclePriceOffset !== 0) {
|
|
85
88
|
limitPrice = oraclePriceData.price.add(new anchor_1.BN(order.oraclePriceOffset));
|
|
86
89
|
}
|
|
87
|
-
else if (
|
|
88
|
-
|
|
89
|
-
limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
|
|
90
|
-
}
|
|
91
|
-
else if (!order.price.eq(numericConstants_1.ZERO)) {
|
|
92
|
-
limitPrice = order.price;
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
limitPrice = fallbackPrice;
|
|
96
|
-
}
|
|
90
|
+
else if (order.price.eq(numericConstants_1.ZERO)) {
|
|
91
|
+
limitPrice = fallbackPrice;
|
|
97
92
|
}
|
|
98
93
|
else {
|
|
99
94
|
limitPrice = order.price;
|
|
@@ -107,6 +102,10 @@ function hasLimitPrice(order, slot) {
|
|
|
107
102
|
!(0, auction_1.isAuctionComplete)(order, slot));
|
|
108
103
|
}
|
|
109
104
|
exports.hasLimitPrice = hasLimitPrice;
|
|
105
|
+
function hasAuctionPrice(order, slot) {
|
|
106
|
+
return isMarketOrder(order) && !(0, auction_1.isAuctionComplete)(order, slot);
|
|
107
|
+
}
|
|
108
|
+
exports.hasAuctionPrice = hasAuctionPrice;
|
|
110
109
|
function isFillableByVAMM(order, market, oraclePriceData, slot, ts) {
|
|
111
110
|
return (((0, auction_1.isAuctionComplete)(order, slot) &&
|
|
112
111
|
!calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
|
|
@@ -149,7 +148,7 @@ function isSameDirection(firstDirection, secondDirection) {
|
|
|
149
148
|
((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
|
|
150
149
|
}
|
|
151
150
|
function isOrderExpired(order, ts) {
|
|
152
|
-
if ((
|
|
151
|
+
if (mustBeTriggered(order) ||
|
|
153
152
|
!(0, types_1.isVariant)(order.status, 'open') ||
|
|
154
153
|
order.maxTs.eq(numericConstants_1.ZERO)) {
|
|
155
154
|
return false;
|
|
@@ -158,7 +157,7 @@ function isOrderExpired(order, ts) {
|
|
|
158
157
|
}
|
|
159
158
|
exports.isOrderExpired = isOrderExpired;
|
|
160
159
|
function isMarketOrder(order) {
|
|
161
|
-
return (0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket']);
|
|
160
|
+
return (0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket', 'oracle']);
|
|
162
161
|
}
|
|
163
162
|
exports.isMarketOrder = isMarketOrder;
|
|
164
163
|
function isLimitOrder(order) {
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
|
@@ -85,6 +85,7 @@ OrderType.LIMIT = { limit: {} };
|
|
|
85
85
|
OrderType.TRIGGER_MARKET = { triggerMarket: {} };
|
|
86
86
|
OrderType.TRIGGER_LIMIT = { triggerLimit: {} };
|
|
87
87
|
OrderType.MARKET = { market: {} };
|
|
88
|
+
OrderType.ORACLE = { oracle: {} };
|
|
88
89
|
class MarketType {
|
|
89
90
|
}
|
|
90
91
|
exports.MarketType = MarketType;
|
package/package.json
CHANGED
package/src/dlob/DLOB.ts
CHANGED
|
@@ -62,6 +62,14 @@ export type NodeToTrigger = {
|
|
|
62
62
|
node: TriggerOrderNode;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
+
const SUPPORTED_ORDER_TYPES = [
|
|
66
|
+
'market',
|
|
67
|
+
'limit',
|
|
68
|
+
'triggerMarket',
|
|
69
|
+
'triggerLimit',
|
|
70
|
+
'oracle',
|
|
71
|
+
];
|
|
72
|
+
|
|
65
73
|
export class DLOB {
|
|
66
74
|
openOrders = new Map<MarketTypeStr, Set<string>>();
|
|
67
75
|
orderLists = new Map<MarketTypeStr, Map<number, MarketNodeLists>>();
|
|
@@ -204,6 +212,10 @@ export class DLOB {
|
|
|
204
212
|
return;
|
|
205
213
|
}
|
|
206
214
|
|
|
215
|
+
if (!isOneOfVariant(order.orderType, SUPPORTED_ORDER_TYPES)) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
207
219
|
const marketType = getVariant(order.marketType) as MarketTypeStr;
|
|
208
220
|
|
|
209
221
|
if (!this.orderLists.get(marketType).has(order.marketIndex)) {
|
|
@@ -313,7 +325,9 @@ export class DLOB {
|
|
|
313
325
|
let type: DLOBNodeType;
|
|
314
326
|
if (isInactiveTriggerOrder) {
|
|
315
327
|
type = 'trigger';
|
|
316
|
-
} else if (
|
|
328
|
+
} else if (
|
|
329
|
+
isOneOfVariant(order.orderType, ['market', 'triggerMarket', 'oracle'])
|
|
330
|
+
) {
|
|
317
331
|
type = 'market';
|
|
318
332
|
} else if (order.oraclePriceOffset !== 0) {
|
|
319
333
|
type = 'floatingLimit';
|
package/src/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.0.
|
|
2
|
+
"version": "2.2.0-beta.2",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -4672,13 +4672,13 @@
|
|
|
4672
4672
|
{
|
|
4673
4673
|
"name": "auctionStartPrice",
|
|
4674
4674
|
"type": {
|
|
4675
|
-
"option": "
|
|
4675
|
+
"option": "i64"
|
|
4676
4676
|
}
|
|
4677
4677
|
},
|
|
4678
4678
|
{
|
|
4679
4679
|
"name": "auctionEndPrice",
|
|
4680
4680
|
"type": {
|
|
4681
|
-
"option": "
|
|
4681
|
+
"option": "i64"
|
|
4682
4682
|
}
|
|
4683
4683
|
}
|
|
4684
4684
|
]
|
|
@@ -5708,11 +5708,11 @@
|
|
|
5708
5708
|
},
|
|
5709
5709
|
{
|
|
5710
5710
|
"name": "auctionStartPrice",
|
|
5711
|
-
"type": "
|
|
5711
|
+
"type": "i64"
|
|
5712
5712
|
},
|
|
5713
5713
|
{
|
|
5714
5714
|
"name": "auctionEndPrice",
|
|
5715
|
-
"type": "
|
|
5715
|
+
"type": "i64"
|
|
5716
5716
|
},
|
|
5717
5717
|
{
|
|
5718
5718
|
"name": "maxTs",
|
|
@@ -6419,6 +6419,9 @@
|
|
|
6419
6419
|
},
|
|
6420
6420
|
{
|
|
6421
6421
|
"name": "TriggerLimit"
|
|
6422
|
+
},
|
|
6423
|
+
{
|
|
6424
|
+
"name": "Oracle"
|
|
6422
6425
|
}
|
|
6423
6426
|
]
|
|
6424
6427
|
}
|
package/src/math/amm.ts
CHANGED
|
@@ -606,7 +606,7 @@ export function calculateSpreadBN(
|
|
|
606
606
|
maxTargetSpread / 10,
|
|
607
607
|
Math.floor(
|
|
608
608
|
(baseSpread * netRevenueSinceLastFunding.abs().toNumber()) /
|
|
609
|
-
DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT.toNumber()
|
|
609
|
+
DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT.abs().toNumber()
|
|
610
610
|
)
|
|
611
611
|
);
|
|
612
612
|
const halfRevenueRetreatAmount = Math.floor(revenueRetreatAmount / 2);
|
package/src/math/auction.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isVariant, Order } from '../types';
|
|
1
|
+
import { isOneOfVariant, isVariant, Order } from '../types';
|
|
2
2
|
import { BN, ZERO } from '../.';
|
|
3
3
|
|
|
4
4
|
export function isAuctionComplete(order: Order, slot: number): boolean {
|
|
@@ -9,7 +9,21 @@ export function isAuctionComplete(order: Order, slot: number): boolean {
|
|
|
9
9
|
return new BN(slot).sub(order.slot).gt(new BN(order.auctionDuration));
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export function getAuctionPrice(
|
|
12
|
+
export function getAuctionPrice(
|
|
13
|
+
order: Order,
|
|
14
|
+
slot: number,
|
|
15
|
+
oraclePrice: BN
|
|
16
|
+
): BN {
|
|
17
|
+
if (isOneOfVariant(order.orderType, ['market', 'triggerMarket'])) {
|
|
18
|
+
return getAuctionPriceForFixedAuction(order, slot);
|
|
19
|
+
} else if (isVariant(order.orderType, 'oracle')) {
|
|
20
|
+
return getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice);
|
|
21
|
+
} else {
|
|
22
|
+
throw Error(`Cant get auction price for order type ${order.orderType}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getAuctionPriceForFixedAuction(order: Order, slot: number): BN {
|
|
13
27
|
const slotsElapsed = new BN(slot).sub(order.slot);
|
|
14
28
|
|
|
15
29
|
const deltaDenominator = new BN(order.auctionDuration);
|
|
@@ -41,3 +55,40 @@ export function getAuctionPrice(order: Order, slot: number): BN {
|
|
|
41
55
|
|
|
42
56
|
return price;
|
|
43
57
|
}
|
|
58
|
+
|
|
59
|
+
export function getAuctionPriceForOracleOffsetAuction(
|
|
60
|
+
order: Order,
|
|
61
|
+
slot: number,
|
|
62
|
+
oraclePrice: BN
|
|
63
|
+
): BN {
|
|
64
|
+
const slotsElapsed = new BN(slot).sub(order.slot);
|
|
65
|
+
|
|
66
|
+
const deltaDenominator = new BN(order.auctionDuration);
|
|
67
|
+
const deltaNumerator = BN.min(slotsElapsed, deltaDenominator);
|
|
68
|
+
|
|
69
|
+
if (deltaDenominator.eq(ZERO)) {
|
|
70
|
+
return order.auctionEndPrice.add(order.auctionEndPrice);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let priceOffsetDelta;
|
|
74
|
+
if (isVariant(order.direction, 'long')) {
|
|
75
|
+
priceOffsetDelta = order.auctionEndPrice
|
|
76
|
+
.sub(order.auctionStartPrice)
|
|
77
|
+
.mul(deltaNumerator)
|
|
78
|
+
.div(deltaDenominator);
|
|
79
|
+
} else {
|
|
80
|
+
priceOffsetDelta = order.auctionStartPrice
|
|
81
|
+
.sub(order.auctionEndPrice)
|
|
82
|
+
.mul(deltaNumerator)
|
|
83
|
+
.div(deltaDenominator);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let priceOffset;
|
|
87
|
+
if (isVariant(order.direction, 'long')) {
|
|
88
|
+
priceOffset = order.auctionStartPrice.add(priceOffsetDelta);
|
|
89
|
+
} else {
|
|
90
|
+
priceOffset = order.auctionStartPrice.sub(priceOffsetDelta);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return oraclePrice.add(priceOffset);
|
|
94
|
+
}
|
package/src/math/orders.ts
CHANGED
|
@@ -131,16 +131,12 @@ export function getLimitPrice(
|
|
|
131
131
|
fallbackPrice?: BN
|
|
132
132
|
): BN | undefined {
|
|
133
133
|
let limitPrice;
|
|
134
|
-
if (order
|
|
134
|
+
if (hasAuctionPrice(order, slot)) {
|
|
135
|
+
limitPrice = getAuctionPrice(order, slot, oraclePriceData.price);
|
|
136
|
+
} else if (order.oraclePriceOffset !== 0) {
|
|
135
137
|
limitPrice = oraclePriceData.price.add(new BN(order.oraclePriceOffset));
|
|
136
|
-
} else if (
|
|
137
|
-
|
|
138
|
-
limitPrice = getAuctionPrice(order, slot);
|
|
139
|
-
} else if (!order.price.eq(ZERO)) {
|
|
140
|
-
limitPrice = order.price;
|
|
141
|
-
} else {
|
|
142
|
-
limitPrice = fallbackPrice;
|
|
143
|
-
}
|
|
138
|
+
} else if (order.price.eq(ZERO)) {
|
|
139
|
+
limitPrice = fallbackPrice;
|
|
144
140
|
} else {
|
|
145
141
|
limitPrice = order.price;
|
|
146
142
|
}
|
|
@@ -156,6 +152,10 @@ export function hasLimitPrice(order: Order, slot: number): boolean {
|
|
|
156
152
|
);
|
|
157
153
|
}
|
|
158
154
|
|
|
155
|
+
export function hasAuctionPrice(order: Order, slot: number): boolean {
|
|
156
|
+
return isMarketOrder(order) && !isAuctionComplete(order, slot);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
159
|
export function isFillableByVAMM(
|
|
160
160
|
order: Order,
|
|
161
161
|
market: PerpMarketAccount,
|
|
@@ -252,7 +252,7 @@ function isSameDirection(
|
|
|
252
252
|
|
|
253
253
|
export function isOrderExpired(order: Order, ts: number): boolean {
|
|
254
254
|
if (
|
|
255
|
-
|
|
255
|
+
mustBeTriggered(order) ||
|
|
256
256
|
!isVariant(order.status, 'open') ||
|
|
257
257
|
order.maxTs.eq(ZERO)
|
|
258
258
|
) {
|
|
@@ -263,7 +263,7 @@ export function isOrderExpired(order: Order, ts: number): boolean {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
export function isMarketOrder(order: Order): boolean {
|
|
266
|
-
return isOneOfVariant(order.orderType, ['market', 'triggerMarket']);
|
|
266
|
+
return isOneOfVariant(order.orderType, ['market', 'triggerMarket', 'oracle']);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
export function isLimitOrder(order: Order): boolean {
|
package/src/types.ts
CHANGED
|
@@ -83,6 +83,7 @@ export class OrderType {
|
|
|
83
83
|
static readonly TRIGGER_MARKET = { triggerMarket: {} };
|
|
84
84
|
static readonly TRIGGER_LIMIT = { triggerLimit: {} };
|
|
85
85
|
static readonly MARKET = { market: {} };
|
|
86
|
+
static readonly ORACLE = { oracle: {} };
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
export declare type MarketTypeStr = 'perp' | 'spot';
|