@drift-labs/sdk-browser 2.123.0-beta.2 → 2.123.0-beta.3
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/dlob/DLOBSubscriber.js +3 -1
- package/lib/browser/dlob/orderBookLevels.d.ts +1 -0
- package/lib/browser/dlob/orderBookLevels.js +69 -114
- package/lib/node/dlob/DLOBSubscriber.d.ts.map +1 -1
- package/lib/node/dlob/DLOBSubscriber.js +3 -1
- package/lib/node/dlob/orderBookLevels.d.ts +1 -0
- package/lib/node/dlob/orderBookLevels.d.ts.map +1 -1
- package/lib/node/dlob/orderBookLevels.js +69 -114
- package/package.json +1 -1
- package/src/dlob/DLOBSubscriber.ts +5 -1
- package/src/dlob/orderBookLevels.ts +96 -179
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.123.0-beta.
|
|
1
|
+
2.123.0-beta.3
|
|
@@ -85,7 +85,9 @@ class DLOBSubscriber {
|
|
|
85
85
|
marketAccount: this.driftClient.getPerpMarketAccount(marketIndex),
|
|
86
86
|
oraclePriceData,
|
|
87
87
|
numOrders: numVammOrders !== null && numVammOrders !== void 0 ? numVammOrders : depth,
|
|
88
|
-
topOfBookQuoteAmounts:
|
|
88
|
+
topOfBookQuoteAmounts: marketIndex < 3
|
|
89
|
+
? orderBookLevels_1.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS
|
|
90
|
+
: orderBookLevels_1.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
|
|
89
91
|
}),
|
|
90
92
|
];
|
|
91
93
|
}
|
|
@@ -30,6 +30,7 @@ export type L3OrderBook = {
|
|
|
30
30
|
slot?: number;
|
|
31
31
|
};
|
|
32
32
|
export declare const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
|
|
33
|
+
export declare const MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
|
|
33
34
|
export declare function getL2GeneratorFromDLOBNodes(dlobNodes: Generator<DLOBNode>, oraclePriceData: OraclePriceData, slot: number): Generator<L2Level>;
|
|
34
35
|
export declare function mergeL2LevelGenerators(l2LevelGenerators: Generator<L2Level>[], compare: (a: L2Level, b: L2Level) => boolean): Generator<L2Level>;
|
|
35
36
|
export declare function createL2Levels(generator: Generator<L2Level>, depth: number): L2Level[];
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uncrossL2 = exports.groupL2 = exports.getVammL2Generator = exports.createL2Levels = exports.mergeL2LevelGenerators = exports.getL2GeneratorFromDLOBNodes = exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = void 0;
|
|
3
|
+
exports.uncrossL2 = exports.groupL2 = exports.getVammL2Generator = exports.createL2Levels = exports.mergeL2LevelGenerators = exports.getL2GeneratorFromDLOBNodes = exports.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = void 0;
|
|
4
4
|
const __1 = require("..");
|
|
5
|
-
const assert_1 = require("../assert/assert");
|
|
6
5
|
exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
7
6
|
new __1.BN(500).mul(__1.QUOTE_PRECISION),
|
|
8
7
|
new __1.BN(1000).mul(__1.QUOTE_PRECISION),
|
|
9
8
|
new __1.BN(2000).mul(__1.QUOTE_PRECISION),
|
|
10
9
|
new __1.BN(5000).mul(__1.QUOTE_PRECISION),
|
|
11
10
|
];
|
|
11
|
+
exports.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
12
|
+
new __1.BN(5000).mul(__1.QUOTE_PRECISION),
|
|
13
|
+
new __1.BN(10000).mul(__1.QUOTE_PRECISION),
|
|
14
|
+
new __1.BN(20000).mul(__1.QUOTE_PRECISION),
|
|
15
|
+
new __1.BN(50000).mul(__1.QUOTE_PRECISION),
|
|
16
|
+
];
|
|
12
17
|
/**
|
|
13
18
|
* Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
|
|
14
19
|
* @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
|
|
@@ -88,132 +93,82 @@ function createL2Levels(generator, depth) {
|
|
|
88
93
|
return levels;
|
|
89
94
|
}
|
|
90
95
|
exports.createL2Levels = createL2Levels;
|
|
91
|
-
function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, topOfBookQuoteAmounts, }) {
|
|
92
|
-
let numBaseOrders = numOrders;
|
|
93
|
-
if (topOfBookQuoteAmounts) {
|
|
94
|
-
numBaseOrders = numOrders - topOfBookQuoteAmounts.length;
|
|
95
|
-
(0, assert_1.assert)(topOfBookQuoteAmounts.length < numOrders);
|
|
96
|
-
}
|
|
96
|
+
function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now = new __1.BN(Math.floor(Date.now() / 1000)), topOfBookQuoteAmounts = [], }) {
|
|
97
97
|
const updatedAmm = (0, __1.calculateUpdatedAMM)(marketAccount.amm, oraclePriceData);
|
|
98
|
-
const
|
|
99
|
-
let [openBids, openAsks] =
|
|
98
|
+
const paused = (0, __1.isOperationPaused)(marketAccount.pausedOperations, __1.PerpOperation.AMM_FILL);
|
|
99
|
+
let [openBids, openAsks] = paused
|
|
100
100
|
? [__1.ZERO, __1.ZERO]
|
|
101
101
|
: (0, __1.calculateMarketOpenBidAsk)(updatedAmm.baseAssetReserve, updatedAmm.minBaseAssetReserve, updatedAmm.maxBaseAssetReserve, updatedAmm.orderStepSize);
|
|
102
|
-
|
|
103
|
-
if (openBids.lt(minOrderSize.muln(2))) {
|
|
102
|
+
if (openBids.lt(marketAccount.amm.minOrderSize.muln(2)))
|
|
104
103
|
openBids = __1.ZERO;
|
|
105
|
-
|
|
106
|
-
if (openAsks.abs().lt(minOrderSize.muln(2))) {
|
|
104
|
+
if (openAsks.abs().lt(marketAccount.amm.minOrderSize.muln(2)))
|
|
107
105
|
openAsks = __1.ZERO;
|
|
108
|
-
}
|
|
109
|
-
now = now !== null && now !== void 0 ? now : new __1.BN(Date.now() / 1000);
|
|
110
106
|
const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now, (0, __1.isVariant)(marketAccount.contractType, 'prediction'));
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
107
|
+
const numBaseOrders = Math.max(1, numOrders - topOfBookQuoteAmounts.length);
|
|
108
|
+
const commonOpts = {
|
|
109
|
+
numOrders,
|
|
110
|
+
numBaseOrders,
|
|
111
|
+
oraclePriceData,
|
|
112
|
+
orderTickSize: marketAccount.amm.orderTickSize,
|
|
113
|
+
orderStepSize: marketAccount.amm.orderStepSize,
|
|
118
114
|
pegMultiplier: updatedAmm.pegMultiplier,
|
|
119
|
-
};
|
|
120
|
-
const getL2Bids = function* () {
|
|
121
|
-
while (numBids < numOrders && bidSize.gt(__1.ZERO)) {
|
|
122
|
-
let quoteSwapped = __1.ZERO;
|
|
123
|
-
let baseSwapped = __1.ZERO;
|
|
124
|
-
let [afterSwapQuoteReserves, afterSwapBaseReserves] = [__1.ZERO, __1.ZERO];
|
|
125
|
-
if (topOfBookQuoteAmounts && numBids < (topOfBookQuoteAmounts === null || topOfBookQuoteAmounts === void 0 ? void 0 : topOfBookQuoteAmounts.length)) {
|
|
126
|
-
const remainingBaseLiquidity = openBids.sub(topOfBookBidSize);
|
|
127
|
-
quoteSwapped = topOfBookQuoteAmounts[numBids];
|
|
128
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
129
|
-
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'quote', quoteSwapped, __1.SwapDirection.REMOVE);
|
|
130
|
-
baseSwapped = bidAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
|
|
131
|
-
if (baseSwapped.eq(__1.ZERO)) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (remainingBaseLiquidity.lt(baseSwapped)) {
|
|
135
|
-
baseSwapped = remainingBaseLiquidity;
|
|
136
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
137
|
-
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.ADD);
|
|
138
|
-
quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
|
|
139
|
-
}
|
|
140
|
-
topOfBookBidSize = topOfBookBidSize.add(baseSwapped);
|
|
141
|
-
bidSize = openBids.sub(topOfBookBidSize).div(new __1.BN(numBaseOrders));
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
baseSwapped = bidSize;
|
|
145
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
146
|
-
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.ADD);
|
|
147
|
-
quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
|
|
148
|
-
}
|
|
149
|
-
const price = quoteSwapped.mul(__1.BASE_PRECISION).div(baseSwapped);
|
|
150
|
-
bidAmm.baseAssetReserve = afterSwapBaseReserves;
|
|
151
|
-
bidAmm.quoteAssetReserve = afterSwapQuoteReserves;
|
|
152
|
-
yield {
|
|
153
|
-
price,
|
|
154
|
-
size: baseSwapped,
|
|
155
|
-
sources: { vamm: baseSwapped },
|
|
156
|
-
};
|
|
157
|
-
numBids++;
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
let numAsks = 0;
|
|
161
|
-
let topOfBookAskSize = __1.ZERO;
|
|
162
|
-
let askSize = openAsks.abs().div(new __1.BN(numBaseOrders));
|
|
163
|
-
const askAmm = {
|
|
164
|
-
baseAssetReserve: askReserves.baseAssetReserve,
|
|
165
|
-
quoteAssetReserve: askReserves.quoteAssetReserve,
|
|
166
115
|
sqrtK: updatedAmm.sqrtK,
|
|
167
|
-
|
|
116
|
+
topOfBookQuoteAmounts,
|
|
168
117
|
};
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
let
|
|
172
|
-
let
|
|
173
|
-
let
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
118
|
+
const makeL2Gen = ({ openLiquidity, startReserves, swapDir, positionDir, }) => {
|
|
119
|
+
return function* () {
|
|
120
|
+
let count = 0;
|
|
121
|
+
let topSize = __1.ZERO;
|
|
122
|
+
let size = openLiquidity.abs().divn(commonOpts.numBaseOrders);
|
|
123
|
+
const amm = {
|
|
124
|
+
...startReserves,
|
|
125
|
+
sqrtK: commonOpts.sqrtK,
|
|
126
|
+
pegMultiplier: commonOpts.pegMultiplier,
|
|
127
|
+
};
|
|
128
|
+
while (count < commonOpts.numOrders && size.gt(__1.ZERO)) {
|
|
129
|
+
let baseSwap = size;
|
|
130
|
+
if (count < commonOpts.topOfBookQuoteAmounts.length) {
|
|
131
|
+
const raw = commonOpts.topOfBookQuoteAmounts[count]
|
|
132
|
+
.mul(__1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
133
|
+
.mul(__1.PRICE_PRECISION)
|
|
134
|
+
.div(commonOpts.oraclePriceData.price);
|
|
135
|
+
baseSwap = (0, __1.standardizeBaseAssetAmount)(raw, commonOpts.orderStepSize);
|
|
136
|
+
const remaining = openLiquidity.abs().sub(topSize);
|
|
137
|
+
if (remaining.lt(baseSwap))
|
|
138
|
+
baseSwap = remaining;
|
|
184
139
|
}
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
140
|
+
if (baseSwap.isZero())
|
|
141
|
+
return;
|
|
142
|
+
const [newQuoteRes, newBaseRes] = (0, __1.calculateAmmReservesAfterSwap)(amm, 'base', baseSwap, swapDir);
|
|
143
|
+
const quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(amm.quoteAssetReserve.sub(newQuoteRes).abs(), amm.pegMultiplier, swapDir);
|
|
144
|
+
const price = (0, __1.standardizePrice)(quoteSwapped.mul(__1.BASE_PRECISION).div(baseSwap), commonOpts.orderTickSize, positionDir);
|
|
145
|
+
amm.baseAssetReserve = newBaseRes;
|
|
146
|
+
amm.quoteAssetReserve = newQuoteRes;
|
|
147
|
+
if (count < commonOpts.topOfBookQuoteAmounts.length) {
|
|
148
|
+
topSize = topSize.add(baseSwap);
|
|
149
|
+
size = openLiquidity
|
|
150
|
+
.abs()
|
|
151
|
+
.sub(topSize)
|
|
152
|
+
.divn(commonOpts.numBaseOrders);
|
|
190
153
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
.abs()
|
|
194
|
-
.sub(topOfBookAskSize)
|
|
195
|
-
.div(new __1.BN(numBaseOrders));
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
baseSwapped = askSize;
|
|
199
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
200
|
-
(0, __1.calculateAmmReservesAfterSwap)(askAmm, 'base', askSize, __1.SwapDirection.REMOVE);
|
|
201
|
-
quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), askAmm.pegMultiplier, __1.SwapDirection.REMOVE);
|
|
154
|
+
yield { price, size: baseSwap, sources: { vamm: baseSwap } };
|
|
155
|
+
count++;
|
|
202
156
|
}
|
|
203
|
-
|
|
204
|
-
askAmm.baseAssetReserve = afterSwapBaseReserves;
|
|
205
|
-
askAmm.quoteAssetReserve = afterSwapQuoteReserves;
|
|
206
|
-
yield {
|
|
207
|
-
price,
|
|
208
|
-
size: baseSwapped,
|
|
209
|
-
sources: { vamm: baseSwapped },
|
|
210
|
-
};
|
|
211
|
-
numAsks++;
|
|
212
|
-
}
|
|
157
|
+
};
|
|
213
158
|
};
|
|
214
159
|
return {
|
|
215
|
-
getL2Bids
|
|
216
|
-
|
|
160
|
+
getL2Bids: makeL2Gen({
|
|
161
|
+
openLiquidity: openBids,
|
|
162
|
+
startReserves: bidReserves,
|
|
163
|
+
swapDir: __1.SwapDirection.ADD,
|
|
164
|
+
positionDir: __1.PositionDirection.LONG,
|
|
165
|
+
}),
|
|
166
|
+
getL2Asks: makeL2Gen({
|
|
167
|
+
openLiquidity: openAsks,
|
|
168
|
+
startReserves: askReserves,
|
|
169
|
+
swapDir: __1.SwapDirection.REMOVE,
|
|
170
|
+
positionDir: __1.PositionDirection.SHORT,
|
|
171
|
+
}),
|
|
217
172
|
};
|
|
218
173
|
}
|
|
219
174
|
exports.getVammL2Generator = getVammL2Generator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DLOBSubscriber.d.ts","sourceRoot":"","sources":["../../../src/dlob/DLOBSubscriber.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACN,UAAU,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,UAAU,EACV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"DLOBSubscriber.d.ts","sourceRoot":"","sources":["../../../src/dlob/DLOBSubscriber.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACN,UAAU,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,UAAU,EACV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAIN,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,MAAM,mBAAmB,CAAC;AAG3B,qBAAa,cAAc;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC3C,IAAI,EAAE,IAAI,CAAC;IACJ,YAAY,EAAE,kBAAkB,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;IAC5E,kBAAkB,EAAE,OAAO,CAAC;gBAChB,MAAM,EAAE,sBAAsB;IAU7B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvC,0BAA0B,IAAI,qBAAqB,GAAG,SAAS;IAMzD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAO1B,OAAO,IAAI,IAAI;IAItB;;;;;;;;;OASG;IACI,KAAK,CAAC,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,KAAU,EACV,WAAmB,EACnB,aAAa,EACb,oBAAyB,GACzB,EAAE;QACF,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,oBAAoB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAC9C,GAAG,WAAW;IA4Df;;;;;;OAMG;IACI,KAAK,CAAC,EACZ,UAAU,EACV,WAAW,EACX,UAAU,GACV,EAAE;QACF,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,UAAU,CAAC;KACxB,GAAG,WAAW;IAmCF,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAMzC"}
|
|
@@ -85,7 +85,9 @@ class DLOBSubscriber {
|
|
|
85
85
|
marketAccount: this.driftClient.getPerpMarketAccount(marketIndex),
|
|
86
86
|
oraclePriceData,
|
|
87
87
|
numOrders: numVammOrders !== null && numVammOrders !== void 0 ? numVammOrders : depth,
|
|
88
|
-
topOfBookQuoteAmounts:
|
|
88
|
+
topOfBookQuoteAmounts: marketIndex < 3
|
|
89
|
+
? orderBookLevels_1.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS
|
|
90
|
+
: orderBookLevels_1.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
|
|
89
91
|
}),
|
|
90
92
|
];
|
|
91
93
|
}
|
|
@@ -30,6 +30,7 @@ export type L3OrderBook = {
|
|
|
30
30
|
slot?: number;
|
|
31
31
|
};
|
|
32
32
|
export declare const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
|
|
33
|
+
export declare const MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
|
|
33
34
|
export declare function getL2GeneratorFromDLOBNodes(dlobNodes: Generator<DLOBNode>, oraclePriceData: OraclePriceData, slot: number): Generator<L2Level>;
|
|
34
35
|
export declare function mergeL2LevelGenerators(l2LevelGenerators: Generator<L2Level>[], compare: (a: L2Level, b: L2Level) => boolean): Generator<L2Level>;
|
|
35
36
|
export declare function createL2Levels(generator: Generator<L2Level>, depth: number): L2Level[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderBookLevels.d.ts","sourceRoot":"","sources":["../../../src/dlob/orderBookLevels.ts"],"names":[],"mappings":";AAAA,OAAO,EAEN,EAAE,EAMF,QAAQ,EAGR,eAAe,EACf,iBAAiB,
|
|
1
|
+
{"version":3,"file":"orderBookLevels.d.ts","sourceRoot":"","sources":["../../../src/dlob/orderBookLevels.ts"],"names":[],"mappings":";AAAA,OAAO,EAEN,EAAE,EAMF,QAAQ,EAGR,eAAe,EACf,iBAAiB,EAUjB,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,KAAK,eAAe,GACjB,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,UAAU,GACV,YAAY,CAAC;AAEhB,MAAM,MAAM,OAAO,GAAG;IACrB,KAAK,EAAE,EAAE,CAAC;IACV,IAAI,EAAE,EAAE,CAAC;IACT,OAAO,EAAE;SAAG,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,EAAE;KAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,SAAS,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,SAAS,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,OAAO,GAAG;IACrB,KAAK,EAAE,EAAE,CAAC;IACV,IAAI,EAAE,EAAE,CAAC;IACT,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,iCAAiC,MAK7C,CAAC;AAEF,eAAO,MAAM,gCAAgC,MAK5C,CAAC;AASF,wBAAiB,2BAA2B,CAC3C,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC9B,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,MAAM,GACV,SAAS,CAAC,OAAO,CAAC,CAgBpB;AAED,wBAAiB,sBAAsB,CACtC,iBAAiB,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,EACvC,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,GAC1C,SAAS,CAAC,OAAO,CAAC,CA+BpB;AAED,wBAAgB,cAAc,CAC7B,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,GACX,OAAO,EAAE,CAsBX;AAED,wBAAgB,kBAAkB,CAAC,EAClC,aAAa,EACb,eAAe,EACf,SAAS,EACT,GAA2C,EAC3C,qBAA0B,GAC1B,EAAE;IACF,aAAa,EAAE,iBAAiB,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,EAAE,CAAC;IACT,qBAAqB,CAAC,EAAE,EAAE,EAAE,CAAC;CAC7B,GAAG,oBAAoB,CAwHvB;AAED,wBAAgB,OAAO,CACtB,EAAE,EAAE,WAAW,EACf,QAAQ,EAAE,EAAE,EACZ,KAAK,EAAE,MAAM,GACX,WAAW,CAMb;AAiFD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CACxB,IAAI,EAAE,OAAO,EAAE,EACf,IAAI,EAAE,OAAO,EAAE,EACf,WAAW,EAAE,EAAE,EACf,cAAc,EAAE,EAAE,EAClB,YAAY,EAAE,EAAE,EAChB,QAAQ,EAAE,EAAE,EACZ,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GACnB;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAAE,CAoJtC"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uncrossL2 = exports.groupL2 = exports.getVammL2Generator = exports.createL2Levels = exports.mergeL2LevelGenerators = exports.getL2GeneratorFromDLOBNodes = exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = void 0;
|
|
3
|
+
exports.uncrossL2 = exports.groupL2 = exports.getVammL2Generator = exports.createL2Levels = exports.mergeL2LevelGenerators = exports.getL2GeneratorFromDLOBNodes = exports.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = void 0;
|
|
4
4
|
const __1 = require("..");
|
|
5
|
-
const assert_1 = require("../assert/assert");
|
|
6
5
|
exports.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
7
6
|
new __1.BN(500).mul(__1.QUOTE_PRECISION),
|
|
8
7
|
new __1.BN(1000).mul(__1.QUOTE_PRECISION),
|
|
9
8
|
new __1.BN(2000).mul(__1.QUOTE_PRECISION),
|
|
10
9
|
new __1.BN(5000).mul(__1.QUOTE_PRECISION),
|
|
11
10
|
];
|
|
11
|
+
exports.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
12
|
+
new __1.BN(5000).mul(__1.QUOTE_PRECISION),
|
|
13
|
+
new __1.BN(10000).mul(__1.QUOTE_PRECISION),
|
|
14
|
+
new __1.BN(20000).mul(__1.QUOTE_PRECISION),
|
|
15
|
+
new __1.BN(50000).mul(__1.QUOTE_PRECISION),
|
|
16
|
+
];
|
|
12
17
|
/**
|
|
13
18
|
* Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
|
|
14
19
|
* @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
|
|
@@ -88,132 +93,82 @@ function createL2Levels(generator, depth) {
|
|
|
88
93
|
return levels;
|
|
89
94
|
}
|
|
90
95
|
exports.createL2Levels = createL2Levels;
|
|
91
|
-
function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, topOfBookQuoteAmounts, }) {
|
|
92
|
-
let numBaseOrders = numOrders;
|
|
93
|
-
if (topOfBookQuoteAmounts) {
|
|
94
|
-
numBaseOrders = numOrders - topOfBookQuoteAmounts.length;
|
|
95
|
-
(0, assert_1.assert)(topOfBookQuoteAmounts.length < numOrders);
|
|
96
|
-
}
|
|
96
|
+
function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now = new __1.BN(Math.floor(Date.now() / 1000)), topOfBookQuoteAmounts = [], }) {
|
|
97
97
|
const updatedAmm = (0, __1.calculateUpdatedAMM)(marketAccount.amm, oraclePriceData);
|
|
98
|
-
const
|
|
99
|
-
let [openBids, openAsks] =
|
|
98
|
+
const paused = (0, __1.isOperationPaused)(marketAccount.pausedOperations, __1.PerpOperation.AMM_FILL);
|
|
99
|
+
let [openBids, openAsks] = paused
|
|
100
100
|
? [__1.ZERO, __1.ZERO]
|
|
101
101
|
: (0, __1.calculateMarketOpenBidAsk)(updatedAmm.baseAssetReserve, updatedAmm.minBaseAssetReserve, updatedAmm.maxBaseAssetReserve, updatedAmm.orderStepSize);
|
|
102
|
-
|
|
103
|
-
if (openBids.lt(minOrderSize.muln(2))) {
|
|
102
|
+
if (openBids.lt(marketAccount.amm.minOrderSize.muln(2)))
|
|
104
103
|
openBids = __1.ZERO;
|
|
105
|
-
|
|
106
|
-
if (openAsks.abs().lt(minOrderSize.muln(2))) {
|
|
104
|
+
if (openAsks.abs().lt(marketAccount.amm.minOrderSize.muln(2)))
|
|
107
105
|
openAsks = __1.ZERO;
|
|
108
|
-
}
|
|
109
|
-
now = now !== null && now !== void 0 ? now : new __1.BN(Date.now() / 1000);
|
|
110
106
|
const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now, (0, __1.isVariant)(marketAccount.contractType, 'prediction'));
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
107
|
+
const numBaseOrders = Math.max(1, numOrders - topOfBookQuoteAmounts.length);
|
|
108
|
+
const commonOpts = {
|
|
109
|
+
numOrders,
|
|
110
|
+
numBaseOrders,
|
|
111
|
+
oraclePriceData,
|
|
112
|
+
orderTickSize: marketAccount.amm.orderTickSize,
|
|
113
|
+
orderStepSize: marketAccount.amm.orderStepSize,
|
|
118
114
|
pegMultiplier: updatedAmm.pegMultiplier,
|
|
119
|
-
};
|
|
120
|
-
const getL2Bids = function* () {
|
|
121
|
-
while (numBids < numOrders && bidSize.gt(__1.ZERO)) {
|
|
122
|
-
let quoteSwapped = __1.ZERO;
|
|
123
|
-
let baseSwapped = __1.ZERO;
|
|
124
|
-
let [afterSwapQuoteReserves, afterSwapBaseReserves] = [__1.ZERO, __1.ZERO];
|
|
125
|
-
if (topOfBookQuoteAmounts && numBids < (topOfBookQuoteAmounts === null || topOfBookQuoteAmounts === void 0 ? void 0 : topOfBookQuoteAmounts.length)) {
|
|
126
|
-
const remainingBaseLiquidity = openBids.sub(topOfBookBidSize);
|
|
127
|
-
quoteSwapped = topOfBookQuoteAmounts[numBids];
|
|
128
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
129
|
-
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'quote', quoteSwapped, __1.SwapDirection.REMOVE);
|
|
130
|
-
baseSwapped = bidAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
|
|
131
|
-
if (baseSwapped.eq(__1.ZERO)) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (remainingBaseLiquidity.lt(baseSwapped)) {
|
|
135
|
-
baseSwapped = remainingBaseLiquidity;
|
|
136
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
137
|
-
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.ADD);
|
|
138
|
-
quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
|
|
139
|
-
}
|
|
140
|
-
topOfBookBidSize = topOfBookBidSize.add(baseSwapped);
|
|
141
|
-
bidSize = openBids.sub(topOfBookBidSize).div(new __1.BN(numBaseOrders));
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
baseSwapped = bidSize;
|
|
145
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
146
|
-
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'base', baseSwapped, __1.SwapDirection.ADD);
|
|
147
|
-
quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), bidAmm.pegMultiplier, __1.SwapDirection.ADD);
|
|
148
|
-
}
|
|
149
|
-
const price = quoteSwapped.mul(__1.BASE_PRECISION).div(baseSwapped);
|
|
150
|
-
bidAmm.baseAssetReserve = afterSwapBaseReserves;
|
|
151
|
-
bidAmm.quoteAssetReserve = afterSwapQuoteReserves;
|
|
152
|
-
yield {
|
|
153
|
-
price,
|
|
154
|
-
size: baseSwapped,
|
|
155
|
-
sources: { vamm: baseSwapped },
|
|
156
|
-
};
|
|
157
|
-
numBids++;
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
let numAsks = 0;
|
|
161
|
-
let topOfBookAskSize = __1.ZERO;
|
|
162
|
-
let askSize = openAsks.abs().div(new __1.BN(numBaseOrders));
|
|
163
|
-
const askAmm = {
|
|
164
|
-
baseAssetReserve: askReserves.baseAssetReserve,
|
|
165
|
-
quoteAssetReserve: askReserves.quoteAssetReserve,
|
|
166
115
|
sqrtK: updatedAmm.sqrtK,
|
|
167
|
-
|
|
116
|
+
topOfBookQuoteAmounts,
|
|
168
117
|
};
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
let
|
|
172
|
-
let
|
|
173
|
-
let
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
118
|
+
const makeL2Gen = ({ openLiquidity, startReserves, swapDir, positionDir, }) => {
|
|
119
|
+
return function* () {
|
|
120
|
+
let count = 0;
|
|
121
|
+
let topSize = __1.ZERO;
|
|
122
|
+
let size = openLiquidity.abs().divn(commonOpts.numBaseOrders);
|
|
123
|
+
const amm = {
|
|
124
|
+
...startReserves,
|
|
125
|
+
sqrtK: commonOpts.sqrtK,
|
|
126
|
+
pegMultiplier: commonOpts.pegMultiplier,
|
|
127
|
+
};
|
|
128
|
+
while (count < commonOpts.numOrders && size.gt(__1.ZERO)) {
|
|
129
|
+
let baseSwap = size;
|
|
130
|
+
if (count < commonOpts.topOfBookQuoteAmounts.length) {
|
|
131
|
+
const raw = commonOpts.topOfBookQuoteAmounts[count]
|
|
132
|
+
.mul(__1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
133
|
+
.mul(__1.PRICE_PRECISION)
|
|
134
|
+
.div(commonOpts.oraclePriceData.price);
|
|
135
|
+
baseSwap = (0, __1.standardizeBaseAssetAmount)(raw, commonOpts.orderStepSize);
|
|
136
|
+
const remaining = openLiquidity.abs().sub(topSize);
|
|
137
|
+
if (remaining.lt(baseSwap))
|
|
138
|
+
baseSwap = remaining;
|
|
184
139
|
}
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
140
|
+
if (baseSwap.isZero())
|
|
141
|
+
return;
|
|
142
|
+
const [newQuoteRes, newBaseRes] = (0, __1.calculateAmmReservesAfterSwap)(amm, 'base', baseSwap, swapDir);
|
|
143
|
+
const quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(amm.quoteAssetReserve.sub(newQuoteRes).abs(), amm.pegMultiplier, swapDir);
|
|
144
|
+
const price = (0, __1.standardizePrice)(quoteSwapped.mul(__1.BASE_PRECISION).div(baseSwap), commonOpts.orderTickSize, positionDir);
|
|
145
|
+
amm.baseAssetReserve = newBaseRes;
|
|
146
|
+
amm.quoteAssetReserve = newQuoteRes;
|
|
147
|
+
if (count < commonOpts.topOfBookQuoteAmounts.length) {
|
|
148
|
+
topSize = topSize.add(baseSwap);
|
|
149
|
+
size = openLiquidity
|
|
150
|
+
.abs()
|
|
151
|
+
.sub(topSize)
|
|
152
|
+
.divn(commonOpts.numBaseOrders);
|
|
190
153
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
.abs()
|
|
194
|
-
.sub(topOfBookAskSize)
|
|
195
|
-
.div(new __1.BN(numBaseOrders));
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
baseSwapped = askSize;
|
|
199
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
200
|
-
(0, __1.calculateAmmReservesAfterSwap)(askAmm, 'base', askSize, __1.SwapDirection.REMOVE);
|
|
201
|
-
quoteSwapped = (0, __1.calculateQuoteAssetAmountSwapped)(askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), askAmm.pegMultiplier, __1.SwapDirection.REMOVE);
|
|
154
|
+
yield { price, size: baseSwap, sources: { vamm: baseSwap } };
|
|
155
|
+
count++;
|
|
202
156
|
}
|
|
203
|
-
|
|
204
|
-
askAmm.baseAssetReserve = afterSwapBaseReserves;
|
|
205
|
-
askAmm.quoteAssetReserve = afterSwapQuoteReserves;
|
|
206
|
-
yield {
|
|
207
|
-
price,
|
|
208
|
-
size: baseSwapped,
|
|
209
|
-
sources: { vamm: baseSwapped },
|
|
210
|
-
};
|
|
211
|
-
numAsks++;
|
|
212
|
-
}
|
|
157
|
+
};
|
|
213
158
|
};
|
|
214
159
|
return {
|
|
215
|
-
getL2Bids
|
|
216
|
-
|
|
160
|
+
getL2Bids: makeL2Gen({
|
|
161
|
+
openLiquidity: openBids,
|
|
162
|
+
startReserves: bidReserves,
|
|
163
|
+
swapDir: __1.SwapDirection.ADD,
|
|
164
|
+
positionDir: __1.PositionDirection.LONG,
|
|
165
|
+
}),
|
|
166
|
+
getL2Asks: makeL2Gen({
|
|
167
|
+
openLiquidity: openAsks,
|
|
168
|
+
startReserves: askReserves,
|
|
169
|
+
swapDir: __1.SwapDirection.REMOVE,
|
|
170
|
+
positionDir: __1.PositionDirection.SHORT,
|
|
171
|
+
}),
|
|
217
172
|
};
|
|
218
173
|
}
|
|
219
174
|
exports.getVammL2Generator = getVammL2Generator;
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import { DriftClient } from '../driftClient';
|
|
|
12
12
|
import { isVariant, MarketType } from '../types';
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
|
|
15
|
+
MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS,
|
|
15
16
|
getVammL2Generator,
|
|
16
17
|
L2OrderBook,
|
|
17
18
|
L2OrderBookGenerator,
|
|
@@ -140,7 +141,10 @@ export class DLOBSubscriber {
|
|
|
140
141
|
marketAccount: this.driftClient.getPerpMarketAccount(marketIndex),
|
|
141
142
|
oraclePriceData,
|
|
142
143
|
numOrders: numVammOrders ?? depth,
|
|
143
|
-
topOfBookQuoteAmounts:
|
|
144
|
+
topOfBookQuoteAmounts:
|
|
145
|
+
marketIndex < 3
|
|
146
|
+
? MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS
|
|
147
|
+
: DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
|
|
144
148
|
}),
|
|
145
149
|
];
|
|
146
150
|
}
|
|
@@ -17,9 +17,11 @@ import {
|
|
|
17
17
|
standardizePrice,
|
|
18
18
|
SwapDirection,
|
|
19
19
|
ZERO,
|
|
20
|
+
PRICE_PRECISION,
|
|
21
|
+
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
22
|
+
standardizeBaseAssetAmount,
|
|
20
23
|
} from '..';
|
|
21
24
|
import { PublicKey } from '@solana/web3.js';
|
|
22
|
-
import { assert } from '../assert/assert';
|
|
23
25
|
|
|
24
26
|
type liquiditySource =
|
|
25
27
|
| 'serum'
|
|
@@ -66,6 +68,13 @@ export const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
|
66
68
|
new BN(5000).mul(QUOTE_PRECISION),
|
|
67
69
|
];
|
|
68
70
|
|
|
71
|
+
export const MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
72
|
+
new BN(5000).mul(QUOTE_PRECISION),
|
|
73
|
+
new BN(10000).mul(QUOTE_PRECISION),
|
|
74
|
+
new BN(20000).mul(QUOTE_PRECISION),
|
|
75
|
+
new BN(50000).mul(QUOTE_PRECISION),
|
|
76
|
+
];
|
|
77
|
+
|
|
69
78
|
/**
|
|
70
79
|
* Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
|
|
71
80
|
* @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
|
|
@@ -162,8 +171,8 @@ export function getVammL2Generator({
|
|
|
162
171
|
marketAccount,
|
|
163
172
|
oraclePriceData,
|
|
164
173
|
numOrders,
|
|
165
|
-
now,
|
|
166
|
-
topOfBookQuoteAmounts,
|
|
174
|
+
now = new BN(Math.floor(Date.now() / 1000)),
|
|
175
|
+
topOfBookQuoteAmounts = [],
|
|
167
176
|
}: {
|
|
168
177
|
marketAccount: PerpMarketAccount;
|
|
169
178
|
oraclePriceData: OraclePriceData;
|
|
@@ -171,20 +180,12 @@ export function getVammL2Generator({
|
|
|
171
180
|
now?: BN;
|
|
172
181
|
topOfBookQuoteAmounts?: BN[];
|
|
173
182
|
}): L2OrderBookGenerator {
|
|
174
|
-
let numBaseOrders = numOrders;
|
|
175
|
-
if (topOfBookQuoteAmounts) {
|
|
176
|
-
numBaseOrders = numOrders - topOfBookQuoteAmounts.length;
|
|
177
|
-
assert(topOfBookQuoteAmounts.length < numOrders);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
183
|
const updatedAmm = calculateUpdatedAMM(marketAccount.amm, oraclePriceData);
|
|
181
|
-
|
|
182
|
-
const vammFillsDisabled = isOperationPaused(
|
|
184
|
+
const paused = isOperationPaused(
|
|
183
185
|
marketAccount.pausedOperations,
|
|
184
186
|
PerpOperation.AMM_FILL
|
|
185
187
|
);
|
|
186
|
-
|
|
187
|
-
let [openBids, openAsks] = vammFillsDisabled
|
|
188
|
+
let [openBids, openAsks] = paused
|
|
188
189
|
? [ZERO, ZERO]
|
|
189
190
|
: calculateMarketOpenBidAsk(
|
|
190
191
|
updatedAmm.baseAssetReserve,
|
|
@@ -193,16 +194,10 @@ export function getVammL2Generator({
|
|
|
193
194
|
updatedAmm.orderStepSize
|
|
194
195
|
);
|
|
195
196
|
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
openBids = ZERO;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (openAsks.abs().lt(minOrderSize.muln(2))) {
|
|
197
|
+
if (openBids.lt(marketAccount.amm.minOrderSize.muln(2))) openBids = ZERO;
|
|
198
|
+
if (openAsks.abs().lt(marketAccount.amm.minOrderSize.muln(2)))
|
|
202
199
|
openAsks = ZERO;
|
|
203
|
-
}
|
|
204
200
|
|
|
205
|
-
now = now ?? new BN(Date.now() / 1000);
|
|
206
201
|
const [bidReserves, askReserves] = calculateSpreadReserves(
|
|
207
202
|
updatedAmm,
|
|
208
203
|
oraclePriceData,
|
|
@@ -210,177 +205,99 @@ export function getVammL2Generator({
|
|
|
210
205
|
isVariant(marketAccount.contractType, 'prediction')
|
|
211
206
|
);
|
|
212
207
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
sqrtK: updatedAmm.sqrtK,
|
|
208
|
+
const numBaseOrders = Math.max(1, numOrders - topOfBookQuoteAmounts.length);
|
|
209
|
+
const commonOpts = {
|
|
210
|
+
numOrders,
|
|
211
|
+
numBaseOrders,
|
|
212
|
+
oraclePriceData,
|
|
213
|
+
orderTickSize: marketAccount.amm.orderTickSize,
|
|
214
|
+
orderStepSize: marketAccount.amm.orderStepSize,
|
|
221
215
|
pegMultiplier: updatedAmm.pegMultiplier,
|
|
216
|
+
sqrtK: updatedAmm.sqrtK,
|
|
217
|
+
topOfBookQuoteAmounts,
|
|
222
218
|
};
|
|
223
219
|
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
if (remainingBaseLiquidity.lt(baseSwapped)) {
|
|
246
|
-
baseSwapped = remainingBaseLiquidity;
|
|
247
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
248
|
-
calculateAmmReservesAfterSwap(
|
|
249
|
-
bidAmm,
|
|
250
|
-
'base',
|
|
251
|
-
baseSwapped,
|
|
252
|
-
SwapDirection.ADD
|
|
253
|
-
);
|
|
254
|
-
|
|
255
|
-
quoteSwapped = calculateQuoteAssetAmountSwapped(
|
|
256
|
-
bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
|
|
257
|
-
bidAmm.pegMultiplier,
|
|
258
|
-
SwapDirection.ADD
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
topOfBookBidSize = topOfBookBidSize.add(baseSwapped);
|
|
262
|
-
bidSize = openBids.sub(topOfBookBidSize).div(new BN(numBaseOrders));
|
|
263
|
-
} else {
|
|
264
|
-
baseSwapped = bidSize;
|
|
265
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
266
|
-
calculateAmmReservesAfterSwap(
|
|
267
|
-
bidAmm,
|
|
268
|
-
'base',
|
|
269
|
-
baseSwapped,
|
|
270
|
-
SwapDirection.ADD
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
quoteSwapped = calculateQuoteAssetAmountSwapped(
|
|
274
|
-
bidAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
|
|
275
|
-
bidAmm.pegMultiplier,
|
|
276
|
-
SwapDirection.ADD
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const price = quoteSwapped.mul(BASE_PRECISION).div(baseSwapped);
|
|
281
|
-
|
|
282
|
-
bidAmm.baseAssetReserve = afterSwapBaseReserves;
|
|
283
|
-
bidAmm.quoteAssetReserve = afterSwapQuoteReserves;
|
|
284
|
-
|
|
285
|
-
yield {
|
|
286
|
-
price,
|
|
287
|
-
size: baseSwapped,
|
|
288
|
-
sources: { vamm: baseSwapped },
|
|
220
|
+
const makeL2Gen = ({
|
|
221
|
+
openLiquidity,
|
|
222
|
+
startReserves,
|
|
223
|
+
swapDir,
|
|
224
|
+
positionDir,
|
|
225
|
+
}: {
|
|
226
|
+
openLiquidity: BN;
|
|
227
|
+
startReserves: { baseAssetReserve: BN; quoteAssetReserve: BN };
|
|
228
|
+
swapDir: SwapDirection;
|
|
229
|
+
positionDir: PositionDirection;
|
|
230
|
+
}) => {
|
|
231
|
+
return function* () {
|
|
232
|
+
let count = 0;
|
|
233
|
+
let topSize = ZERO;
|
|
234
|
+
let size = openLiquidity.abs().divn(commonOpts.numBaseOrders);
|
|
235
|
+
const amm = {
|
|
236
|
+
...startReserves,
|
|
237
|
+
sqrtK: commonOpts.sqrtK,
|
|
238
|
+
pegMultiplier: commonOpts.pegMultiplier,
|
|
289
239
|
};
|
|
290
240
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
sqrtK: updatedAmm.sqrtK,
|
|
302
|
-
pegMultiplier: updatedAmm.pegMultiplier,
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
const getL2Asks = function* () {
|
|
306
|
-
while (numAsks < numOrders && askSize.gt(ZERO)) {
|
|
307
|
-
let quoteSwapped: BN = ZERO;
|
|
308
|
-
let baseSwapped: BN = ZERO;
|
|
309
|
-
let [afterSwapQuoteReserves, afterSwapBaseReserves] = [ZERO, ZERO];
|
|
310
|
-
|
|
311
|
-
if (topOfBookQuoteAmounts && numAsks < topOfBookQuoteAmounts?.length) {
|
|
312
|
-
const remainingBaseLiquidity = openAsks
|
|
313
|
-
.mul(new BN(-1))
|
|
314
|
-
.sub(topOfBookAskSize);
|
|
315
|
-
quoteSwapped = topOfBookQuoteAmounts[numAsks];
|
|
316
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
317
|
-
calculateAmmReservesAfterSwap(
|
|
318
|
-
askAmm,
|
|
319
|
-
'quote',
|
|
320
|
-
quoteSwapped,
|
|
321
|
-
SwapDirection.ADD
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
baseSwapped = askAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
|
|
325
|
-
if (baseSwapped.eq(ZERO)) {
|
|
326
|
-
return;
|
|
241
|
+
while (count < commonOpts.numOrders && size.gt(ZERO)) {
|
|
242
|
+
let baseSwap = size;
|
|
243
|
+
if (count < commonOpts.topOfBookQuoteAmounts.length) {
|
|
244
|
+
const raw = commonOpts.topOfBookQuoteAmounts[count]
|
|
245
|
+
.mul(AMM_TO_QUOTE_PRECISION_RATIO)
|
|
246
|
+
.mul(PRICE_PRECISION)
|
|
247
|
+
.div(commonOpts.oraclePriceData.price);
|
|
248
|
+
baseSwap = standardizeBaseAssetAmount(raw, commonOpts.orderStepSize);
|
|
249
|
+
const remaining = openLiquidity.abs().sub(topSize);
|
|
250
|
+
if (remaining.lt(baseSwap)) baseSwap = remaining;
|
|
327
251
|
}
|
|
328
|
-
if (
|
|
329
|
-
baseSwapped = remainingBaseLiquidity;
|
|
330
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
331
|
-
calculateAmmReservesAfterSwap(
|
|
332
|
-
askAmm,
|
|
333
|
-
'base',
|
|
334
|
-
baseSwapped,
|
|
335
|
-
SwapDirection.REMOVE
|
|
336
|
-
);
|
|
337
|
-
|
|
338
|
-
quoteSwapped = calculateQuoteAssetAmountSwapped(
|
|
339
|
-
askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
|
|
340
|
-
askAmm.pegMultiplier,
|
|
341
|
-
SwapDirection.REMOVE
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
topOfBookAskSize = topOfBookAskSize.add(baseSwapped);
|
|
345
|
-
askSize = openAsks
|
|
346
|
-
.abs()
|
|
347
|
-
.sub(topOfBookAskSize)
|
|
348
|
-
.div(new BN(numBaseOrders));
|
|
349
|
-
} else {
|
|
350
|
-
baseSwapped = askSize;
|
|
351
|
-
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
352
|
-
calculateAmmReservesAfterSwap(
|
|
353
|
-
askAmm,
|
|
354
|
-
'base',
|
|
355
|
-
askSize,
|
|
356
|
-
SwapDirection.REMOVE
|
|
357
|
-
);
|
|
358
|
-
|
|
359
|
-
quoteSwapped = calculateQuoteAssetAmountSwapped(
|
|
360
|
-
askAmm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
|
|
361
|
-
askAmm.pegMultiplier,
|
|
362
|
-
SwapDirection.REMOVE
|
|
363
|
-
);
|
|
364
|
-
}
|
|
252
|
+
if (baseSwap.isZero()) return;
|
|
365
253
|
|
|
366
|
-
|
|
254
|
+
const [newQuoteRes, newBaseRes] = calculateAmmReservesAfterSwap(
|
|
255
|
+
amm,
|
|
256
|
+
'base',
|
|
257
|
+
baseSwap,
|
|
258
|
+
swapDir
|
|
259
|
+
);
|
|
260
|
+
const quoteSwapped = calculateQuoteAssetAmountSwapped(
|
|
261
|
+
amm.quoteAssetReserve.sub(newQuoteRes).abs(),
|
|
262
|
+
amm.pegMultiplier,
|
|
263
|
+
swapDir
|
|
264
|
+
);
|
|
265
|
+
const price = standardizePrice(
|
|
266
|
+
quoteSwapped.mul(BASE_PRECISION).div(baseSwap),
|
|
267
|
+
commonOpts.orderTickSize,
|
|
268
|
+
positionDir
|
|
269
|
+
);
|
|
367
270
|
|
|
368
|
-
|
|
369
|
-
|
|
271
|
+
amm.baseAssetReserve = newBaseRes;
|
|
272
|
+
amm.quoteAssetReserve = newQuoteRes;
|
|
370
273
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
274
|
+
if (count < commonOpts.topOfBookQuoteAmounts.length) {
|
|
275
|
+
topSize = topSize.add(baseSwap);
|
|
276
|
+
size = openLiquidity
|
|
277
|
+
.abs()
|
|
278
|
+
.sub(topSize)
|
|
279
|
+
.divn(commonOpts.numBaseOrders);
|
|
280
|
+
}
|
|
376
281
|
|
|
377
|
-
|
|
378
|
-
|
|
282
|
+
yield { price, size: baseSwap, sources: { vamm: baseSwap } };
|
|
283
|
+
count++;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
379
286
|
};
|
|
380
287
|
|
|
381
288
|
return {
|
|
382
|
-
getL2Bids
|
|
383
|
-
|
|
289
|
+
getL2Bids: makeL2Gen({
|
|
290
|
+
openLiquidity: openBids,
|
|
291
|
+
startReserves: bidReserves,
|
|
292
|
+
swapDir: SwapDirection.ADD,
|
|
293
|
+
positionDir: PositionDirection.LONG,
|
|
294
|
+
}),
|
|
295
|
+
getL2Asks: makeL2Gen({
|
|
296
|
+
openLiquidity: openAsks,
|
|
297
|
+
startReserves: askReserves,
|
|
298
|
+
swapDir: SwapDirection.REMOVE,
|
|
299
|
+
positionDir: PositionDirection.SHORT,
|
|
300
|
+
}),
|
|
384
301
|
};
|
|
385
302
|
}
|
|
386
303
|
|