@d8x/perpetuals-sdk 0.6.3 → 0.6.5
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/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +5 -4
- package/src/abi/ERC20.json +288 -0
- package/src/abi/IPerpetualManager.json +5888 -0
- package/src/abi/LimitOrderBook.json +1062 -0
- package/src/abi/LimitOrderBookFactory.json +161 -0
- package/src/abi/MockTokenSwap.json +186 -0
- package/src/abi/ShareToken.json +428 -0
- package/src/accountTrade.ts +428 -0
- package/src/brokerTool.ts +555 -0
- package/src/config/defaultConfig.json +62 -0
- package/src/config/mockSwap.json +6 -0
- package/src/config/priceFeedConfig.json +104 -0
- package/src/config/symbolList.json +13 -0
- package/src/contracts/ERC20.ts +444 -0
- package/src/contracts/IPerpetualManager.ts +7227 -0
- package/src/contracts/LimitOrderBook.ts +1251 -0
- package/src/contracts/LimitOrderBookFactory.ts +348 -0
- package/src/contracts/MockTokenSwap.ts +373 -0
- package/src/contracts/ShareToken.ts +695 -0
- package/src/contracts/common.ts +44 -0
- package/src/contracts/factories/ERC20__factory.ts +306 -0
- package/src/contracts/factories/IPerpetualManager__factory.ts +5912 -0
- package/src/contracts/factories/LimitOrderBookFactory__factory.ts +189 -0
- package/src/contracts/factories/LimitOrderBook__factory.ts +1086 -0
- package/src/contracts/factories/MockTokenSwap__factory.ts +207 -0
- package/src/contracts/factories/ShareToken__factory.ts +449 -0
- package/src/contracts/factories/index.ts +9 -0
- package/src/contracts/index.ts +16 -0
- package/src/d8XMath.ts +376 -0
- package/src/index.ts +29 -0
- package/src/liquidatorTool.ts +270 -0
- package/src/liquidityProviderTool.ts +148 -0
- package/src/marketData.ts +1310 -0
- package/src/nodeSDKTypes.ts +332 -0
- package/src/orderReferrerTool.ts +516 -0
- package/src/perpetualDataHandler.ts +1161 -0
- package/src/perpetualEventHandler.ts +455 -0
- package/src/priceFeeds.ts +382 -0
- package/src/traderDigests.ts +86 -0
- package/src/traderInterface.ts +172 -0
- package/src/triangulator.ts +105 -0
- package/src/utils.ts +134 -0
- package/src/version.ts +1 -0
- package/src/writeAccessHandler.ts +139 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { BigNumber } from "@ethersproject/bignumber";
|
|
2
|
+
import { emitWarning } from "process";
|
|
3
|
+
import { ABK64x64ToFloat, mul64x64 } from "./d8XMath";
|
|
4
|
+
import MarketData from "./marketData";
|
|
5
|
+
import {
|
|
6
|
+
ExchangeInfo,
|
|
7
|
+
MarginAccount,
|
|
8
|
+
ONE_64x64,
|
|
9
|
+
Order,
|
|
10
|
+
OrderStruct,
|
|
11
|
+
PerpetualState,
|
|
12
|
+
SmartContractOrder,
|
|
13
|
+
TradeEvent,
|
|
14
|
+
} from "./nodeSDKTypes";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* This class handles events and stores relevant variables
|
|
18
|
+
* as member variables. The events change the state of the member variables:
|
|
19
|
+
* mktData : MarketData relevant market data with current state (e.g. index price)
|
|
20
|
+
* ordersInPerpetual: Map<number, OrderStruct> all open orders for the given trader
|
|
21
|
+
* positionInPerpetual: Map<number, MarginAccount> all open positions for the given trader
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
* Get data:
|
|
25
|
+
* - getPerpetualData(perp id (string) or symbol) : PerpetualState. This is a reference!
|
|
26
|
+
* - getExchangeInfo() : ExchangeInfo. This is a reference!
|
|
27
|
+
* - getCurrentPositionRisk(perp id (string) or symbol) : MarginAccount. This is a reference!
|
|
28
|
+
* - getOrdersInPerpetualMap : Map<number, OrderStruct>. This is a reference!
|
|
29
|
+
* - getpositionInPerpetualMap : Map<number, MarginAccount>. This is a reference!
|
|
30
|
+
*
|
|
31
|
+
* Construct with a trader address and a marketData object
|
|
32
|
+
* Initialize to gather all the relevant data.
|
|
33
|
+
* Send event variables to event handler "on<EventName>" - this updates members
|
|
34
|
+
* - [x] onUpdateMarkPrice : emitted on proxy; updates markprice and index price data
|
|
35
|
+
* - [x] onUpdateUpdateFundingRate : emitted on proxy; sets funding rate
|
|
36
|
+
* - [x] onExecutionFailed : emitted on order book; removes an open order
|
|
37
|
+
* - [x] onPerpetualLimitOrderCancelled : emitted on order book; removes an open order
|
|
38
|
+
* - [x] onPerpetualLimitOrderCreated : emitted on order book; adds an open order to the data
|
|
39
|
+
* - [x] async onUpdateMarginAccount : emitted on proxy; updates position data and open interest
|
|
40
|
+
* - [x] onTrade : emitted on proxy; returns TradeEvent to be displayed
|
|
41
|
+
*/
|
|
42
|
+
export default class PerpetualEventHandler {
|
|
43
|
+
// market data class
|
|
44
|
+
private mktData: MarketData;
|
|
45
|
+
// trader for which the data is tracked
|
|
46
|
+
private traderAddr: string;
|
|
47
|
+
|
|
48
|
+
// perpetual id to trader data
|
|
49
|
+
private ordersInPerpetual: Map<number, OrderStruct>;
|
|
50
|
+
private positionInPerpetual: Map<number, MarginAccount>;
|
|
51
|
+
|
|
52
|
+
// perpetual id to pool index in exchange info
|
|
53
|
+
private poolIndexForPerpetual: Map<number, number>;
|
|
54
|
+
|
|
55
|
+
// keep current state of the system in exchangeInfo
|
|
56
|
+
// data is updated when calling "onEvent"-functions
|
|
57
|
+
private exchangeInfo: ExchangeInfo | undefined;
|
|
58
|
+
|
|
59
|
+
constructor(mktData: MarketData, traderAddr: string) {
|
|
60
|
+
this.mktData = mktData;
|
|
61
|
+
this.traderAddr = traderAddr;
|
|
62
|
+
this.ordersInPerpetual = new Map<number, OrderStruct>();
|
|
63
|
+
this.positionInPerpetual = new Map<number, MarginAccount>();
|
|
64
|
+
this.poolIndexForPerpetual = new Map<number, number>();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Call this async function to initialize the
|
|
69
|
+
* market data
|
|
70
|
+
*/
|
|
71
|
+
public async initialize() {
|
|
72
|
+
this.exchangeInfo = await this.mktData.exchangeInfo();
|
|
73
|
+
// loop through all pools and perpetuals and get
|
|
74
|
+
// open positions and open orders
|
|
75
|
+
for (let k = 0; k < this.exchangeInfo.pools.length; k++) {
|
|
76
|
+
let poolState = this.exchangeInfo.pools[k];
|
|
77
|
+
let poolSymbol = poolState.poolSymbol;
|
|
78
|
+
for (let j = 0; j < poolState.perpetuals.length; j++) {
|
|
79
|
+
let perpState: PerpetualState = poolState.perpetuals[j];
|
|
80
|
+
let perpSymbol = perpState.baseCurrency + "-" + perpState.quoteCurrency + "-" + poolSymbol;
|
|
81
|
+
let orders = await this.mktData.openOrders(this.traderAddr, perpSymbol);
|
|
82
|
+
let perpId = perpState.id;
|
|
83
|
+
this.ordersInPerpetual.set(perpId, orders[0]);
|
|
84
|
+
let position = (await this.mktData.positionRisk(this.traderAddr, perpSymbol))[0];
|
|
85
|
+
this.positionInPerpetual.set(perpId, position);
|
|
86
|
+
this.poolIndexForPerpetual.set(perpId, k);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get the current exchange info
|
|
93
|
+
* @returns exchange info
|
|
94
|
+
*/
|
|
95
|
+
public getExchangeInfo(): ExchangeInfo | undefined {
|
|
96
|
+
return this.exchangeInfo;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* getOrdersInPerpetualMap
|
|
101
|
+
* @returns this.ordersInPerpetual
|
|
102
|
+
*/
|
|
103
|
+
public getOrdersInPerpetualMap(): Map<number, OrderStruct> {
|
|
104
|
+
return this.ordersInPerpetual;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* getpositionInPerpetualMap
|
|
109
|
+
* @returns this.positionInPerpetual
|
|
110
|
+
*/
|
|
111
|
+
public getpositionInPerpetualMap(): Map<number, MarginAccount> {
|
|
112
|
+
return this.positionInPerpetual;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get the data for a perpetual with a given index
|
|
117
|
+
* @param perpetualIdOrSymbol perpetual idx as string or symbol for which we want the data
|
|
118
|
+
* @returns perpetual data for this idx
|
|
119
|
+
*/
|
|
120
|
+
public getPerpetualData(perpetualIdOrSymbol: string): PerpetualState | undefined {
|
|
121
|
+
let perpId = Number(perpetualIdOrSymbol);
|
|
122
|
+
if (isNaN(perpId)) {
|
|
123
|
+
perpId = this.mktData.getPerpIdFromSymbol(perpetualIdOrSymbol);
|
|
124
|
+
}
|
|
125
|
+
//uint24 perpetualId = uint24(_iPoolId) * 100_000 + iPerpetualIndex;
|
|
126
|
+
let poolIdx = this.poolIndexForPerpetual.get(perpId)!; //Math.floor(perpId / 100_000);
|
|
127
|
+
let perpetuals = this.exchangeInfo?.pools[poolIdx].perpetuals;
|
|
128
|
+
if (perpetuals == undefined) {
|
|
129
|
+
emitWarning(`exchangeInfo not found, initialize perpetualEventHandler`);
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
// find perpetual
|
|
133
|
+
let k;
|
|
134
|
+
for (k = 0; k < perpetuals?.length && perpetuals[k].id != perpId; k++);
|
|
135
|
+
if (perpetuals[k].id != perpId) {
|
|
136
|
+
emitWarning(`getPerpetualData: perpetual id ${perpId} not found`);
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
return perpetuals[k];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get the trader's current position risk (margin account data)
|
|
144
|
+
* @param perpetualIdOrSymbol perpetual id as string ('100003') or symbol ('BTC-USD-MATIC')
|
|
145
|
+
* @returns undefined if no position or margin account (='position risk')
|
|
146
|
+
*/
|
|
147
|
+
public getCurrentPositionRisk(perpetualIdOrSymbol: string): MarginAccount | undefined {
|
|
148
|
+
let perpId = Number(perpetualIdOrSymbol);
|
|
149
|
+
if (isNaN(perpId)) {
|
|
150
|
+
perpId = this.mktData.getPerpIdFromSymbol(perpetualIdOrSymbol);
|
|
151
|
+
}
|
|
152
|
+
return this.positionInPerpetual.get(perpId);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Update the following prices:
|
|
157
|
+
* - index price
|
|
158
|
+
* - collateral price
|
|
159
|
+
* - mid-price
|
|
160
|
+
* @param perpetualIdOrSymbol perpetual id as string ('100003') or symbol ('BTC-USD-MATIC')
|
|
161
|
+
*/
|
|
162
|
+
public async updatePrices(perpetualIdOrSymbol: string) {
|
|
163
|
+
let perpId = Number(perpetualIdOrSymbol);
|
|
164
|
+
let symbol = perpetualIdOrSymbol;
|
|
165
|
+
if (!isNaN(perpId)) {
|
|
166
|
+
let sym = this.mktData.getSymbolFromPerpId(perpId);
|
|
167
|
+
if (sym == undefined) {
|
|
168
|
+
throw new Error(`Symbol not found for perpetual ${perpId}`);
|
|
169
|
+
}
|
|
170
|
+
symbol = sym;
|
|
171
|
+
}
|
|
172
|
+
let perpState: PerpetualState = await this.mktData.getPerpetualState(symbol);
|
|
173
|
+
let perp = this.getPerpetualData(symbol);
|
|
174
|
+
if (perp == undefined) {
|
|
175
|
+
throw new Error(`Perpetual not found: ${symbol}`);
|
|
176
|
+
}
|
|
177
|
+
perp.state = perpState.state;
|
|
178
|
+
perp.indexPrice = perpState.indexPrice;
|
|
179
|
+
perp.collToQuoteIndexPrice = perpState.collToQuoteIndexPrice;
|
|
180
|
+
perp.markPrice = perpState.markPrice;
|
|
181
|
+
perp.midPrice = perpState.midPrice;
|
|
182
|
+
perp.currentFundingRateBps = perpState.currentFundingRateBps;
|
|
183
|
+
perp.openInterestBC = perpState.openInterestBC;
|
|
184
|
+
perp.indexPrice = perpState.indexPrice;
|
|
185
|
+
perp.collToQuoteIndexPrice = perpState.collToQuoteIndexPrice;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Handle the event UpdateMarkPrice and update relevant
|
|
190
|
+
* data
|
|
191
|
+
* @param perpetualId perpetual Id
|
|
192
|
+
* @param fMarkPricePremium premium rate in ABDK format
|
|
193
|
+
* @param fSpotIndexPrice spot index price in ABDK format
|
|
194
|
+
* @returns void
|
|
195
|
+
*/
|
|
196
|
+
public onUpdateMarkPrice(
|
|
197
|
+
perpetualId: number,
|
|
198
|
+
fMidPricePremium: BigNumber,
|
|
199
|
+
fMarkPricePremium: BigNumber,
|
|
200
|
+
fSpotIndexPrice: BigNumber
|
|
201
|
+
): void {
|
|
202
|
+
let [newMidPrice, newMarkPrice, newIndexPrice] = PerpetualEventHandler.ConvertUpdateMarkPrice(
|
|
203
|
+
fMidPricePremium,
|
|
204
|
+
fMarkPricePremium,
|
|
205
|
+
fSpotIndexPrice
|
|
206
|
+
);
|
|
207
|
+
let perpetual = this.getPerpetualData(perpetualId.toString());
|
|
208
|
+
if (perpetual == undefined) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
perpetual.midPrice = newMidPrice;
|
|
212
|
+
perpetual.markPrice = newMarkPrice;
|
|
213
|
+
perpetual.indexPrice = newIndexPrice;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Handle the event UpdateFundingRate and update relevant
|
|
218
|
+
* data
|
|
219
|
+
* UpdateFundingRate(uint24 indexed perpetualId, int128 fFundingRate)
|
|
220
|
+
* @param fFundingRate funding rate in ABDK format
|
|
221
|
+
*/
|
|
222
|
+
public onUpdateUpdateFundingRate(perpetualId: number, fFundingRate: BigNumber): void {
|
|
223
|
+
let newRate = ABK64x64ToFloat(fFundingRate);
|
|
224
|
+
let perpetual = this.getPerpetualData(perpetualId.toString());
|
|
225
|
+
if (perpetual == undefined) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
perpetual.currentFundingRateBps = newRate * 1e4;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* event ExecutionFailed(
|
|
233
|
+
uint24 indexed perpetualId,
|
|
234
|
+
address indexed trader,
|
|
235
|
+
bytes32 digest,
|
|
236
|
+
string reason
|
|
237
|
+
);
|
|
238
|
+
* @param perpetualId id of the perpetual
|
|
239
|
+
* @param trader address of the trader
|
|
240
|
+
* @param digest digest of the order/cancel order
|
|
241
|
+
* @param reason reason why the execution failed
|
|
242
|
+
*/
|
|
243
|
+
public onExecutionFailed(perpetualId: number, trader: string, digest: string, reason: string) {
|
|
244
|
+
if (trader != this.traderAddr) {
|
|
245
|
+
emitWarning(`onExecutionFailed: trader ${trader} not relevant`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
// remove order from open orders
|
|
249
|
+
let orderStructs:
|
|
250
|
+
| {
|
|
251
|
+
orders: Order[];
|
|
252
|
+
orderIds: string[];
|
|
253
|
+
}
|
|
254
|
+
| undefined = this.ordersInPerpetual.get(perpetualId);
|
|
255
|
+
if (orderStructs == undefined) {
|
|
256
|
+
emitWarning(`onExecutionFailed: no order found for perpetual ${perpetualId}`);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (reason == "cancel delay required") {
|
|
260
|
+
// canceling failed. We don't remove the order
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
PerpetualEventHandler.deleteOrder(orderStructs, digest);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Event emitted by perpetual proxy
|
|
268
|
+
* event PerpetualLimitOrderCancelled(bytes32 indexed orderHash);
|
|
269
|
+
* @param orderId string order id/digest
|
|
270
|
+
*/
|
|
271
|
+
public onPerpetualLimitOrderCancelled(orderId: string) {
|
|
272
|
+
// remove order from open orders
|
|
273
|
+
let perpId: number | undefined = PerpetualEventHandler.findOrderForId(orderId, this.ordersInPerpetual);
|
|
274
|
+
if (perpId == undefined) {
|
|
275
|
+
emitWarning(`onPerpetualLimitOrderCancelled: no order found with id ${orderId}`);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
let orderStruct: OrderStruct | undefined = this.ordersInPerpetual.get(perpId);
|
|
279
|
+
PerpetualEventHandler.deleteOrder(orderStruct!, orderId);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* event PerpetualLimitOrderCreated(
|
|
284
|
+
* uint24 indexed perpetualId,
|
|
285
|
+
* address indexed trader,
|
|
286
|
+
* address referrerAddr,
|
|
287
|
+
* address brokerAddr,
|
|
288
|
+
* Order order,
|
|
289
|
+
* bytes32 digest
|
|
290
|
+
*)
|
|
291
|
+
* @param perpetualId id of the perpetual
|
|
292
|
+
* @param trader address of the trader
|
|
293
|
+
* @param referrerAddr address of the referrer
|
|
294
|
+
* @param brokerAddr address of the broker
|
|
295
|
+
* @param Order order struct
|
|
296
|
+
* @param digest order id
|
|
297
|
+
*/
|
|
298
|
+
public onPerpetualLimitOrderCreated(
|
|
299
|
+
perpetualId: number,
|
|
300
|
+
trader: string,
|
|
301
|
+
_referrerAddr: string,
|
|
302
|
+
_brokerAddr: string,
|
|
303
|
+
Order: SmartContractOrder,
|
|
304
|
+
digest: string
|
|
305
|
+
): void {
|
|
306
|
+
if (trader != this.traderAddr) {
|
|
307
|
+
emitWarning(`onPerpetualLimitOrderCreated: trader ${trader} not relevant`);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
let order: Order = this.mktData.smartContractOrderToOrder(Order);
|
|
311
|
+
let orderStruct: OrderStruct | undefined = this.ordersInPerpetual.get(perpetualId);
|
|
312
|
+
if (orderStruct == undefined) {
|
|
313
|
+
// no order for this perpetual so far
|
|
314
|
+
this.ordersInPerpetual.set(perpetualId, { orders: [order], orderIds: [digest] });
|
|
315
|
+
} else {
|
|
316
|
+
orderStruct.orderIds.push(digest);
|
|
317
|
+
orderStruct.orders.push(order);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* This function is async -> queries the margin account
|
|
323
|
+
* @param perpetualId id of the perpetual
|
|
324
|
+
* @param trader trader address
|
|
325
|
+
* @param positionId position id
|
|
326
|
+
* @param fPositionBC position size in base currency
|
|
327
|
+
* @param fCashCC margin collateral in margin account
|
|
328
|
+
* @param fLockedInValueQC pos*average opening price
|
|
329
|
+
* @param fFundingPaymentCC funding payment made
|
|
330
|
+
* @param fOpenInterestBC open interest
|
|
331
|
+
*/
|
|
332
|
+
public async onUpdateMarginAccount(
|
|
333
|
+
perpetualId: number,
|
|
334
|
+
trader: string,
|
|
335
|
+
_positionId: string,
|
|
336
|
+
_fPositionBC: BigNumber,
|
|
337
|
+
_fCashCC: BigNumber,
|
|
338
|
+
_fLockedInValueQC: BigNumber,
|
|
339
|
+
_fFundingPaymentCC: BigNumber,
|
|
340
|
+
fOpenInterestBC: BigNumber
|
|
341
|
+
): Promise<void> {
|
|
342
|
+
let perpetual = this.getPerpetualData(perpetualId.toString());
|
|
343
|
+
if (perpetual == undefined) {
|
|
344
|
+
emitWarning(`onUpdateMarginAccount: perpetual ${perpetualId} not found`);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
perpetual.openInterestBC = ABK64x64ToFloat(fOpenInterestBC);
|
|
348
|
+
if (trader != this.traderAddr) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
let perpetualIdStr = perpetualId.toString();
|
|
352
|
+
let margin = (await this.mktData.positionRisk(this.traderAddr, perpetualIdStr))[0];
|
|
353
|
+
this.positionInPerpetual.set(perpetualId, margin);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
*
|
|
358
|
+
* @param perpetualId perpetual id
|
|
359
|
+
* @param trader trader address
|
|
360
|
+
* @param positionId position id
|
|
361
|
+
* @param order order struct
|
|
362
|
+
* @param orderDigest order id
|
|
363
|
+
* @param newPositionSizeBC new pos size in base currency ABDK
|
|
364
|
+
* @param price price in ABDK format
|
|
365
|
+
* @returns trade event data in regular number format
|
|
366
|
+
*/
|
|
367
|
+
public onTrade(
|
|
368
|
+
perpetualId: number,
|
|
369
|
+
_trader: string,
|
|
370
|
+
positionId: string,
|
|
371
|
+
_order: SmartContractOrder,
|
|
372
|
+
orderDigest: string,
|
|
373
|
+
newPositionSizeBC: BigNumber,
|
|
374
|
+
_price: BigNumber
|
|
375
|
+
): TradeEvent {
|
|
376
|
+
// remove order digest from open orders
|
|
377
|
+
let orderStructs = this.ordersInPerpetual.get(perpetualId);
|
|
378
|
+
if (orderStructs == undefined) {
|
|
379
|
+
emitWarning(`onTrade: executed order not found ${orderDigest}`);
|
|
380
|
+
} else {
|
|
381
|
+
PerpetualEventHandler.deleteOrder(orderStructs, orderDigest);
|
|
382
|
+
}
|
|
383
|
+
// return transformed trade info
|
|
384
|
+
return {
|
|
385
|
+
perpetualId: perpetualId,
|
|
386
|
+
positionId: positionId,
|
|
387
|
+
orderId: orderDigest,
|
|
388
|
+
newPositionSizeBC: ABK64x64ToFloat(newPositionSizeBC),
|
|
389
|
+
executionPrice: ABK64x64ToFloat(newPositionSizeBC),
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* static function to find the number of the OrderStruct with given orderId
|
|
395
|
+
* @param orderId id/digest of order
|
|
396
|
+
* @param orderMap mapping for perpetualId->OrderStruct
|
|
397
|
+
* @returns id of perpetual that contains order with id = orderId or undefined
|
|
398
|
+
*/
|
|
399
|
+
private static findOrderForId(orderId: string, orderMap: Map<number, OrderStruct>): number | undefined {
|
|
400
|
+
/*orderMapMap<number, {
|
|
401
|
+
orders: Order[];
|
|
402
|
+
orderIds: string[];*/
|
|
403
|
+
for (const perpId of orderMap.keys()) {
|
|
404
|
+
let orderStructs = orderMap.get(perpId);
|
|
405
|
+
if (orderStructs?.orderIds.includes(orderId)) {
|
|
406
|
+
return perpId;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Delete the order with given id from the class member data
|
|
414
|
+
* @param orderStructs array of order struct as stored for the trader and a given perpetual
|
|
415
|
+
* @param orderId digest/order id
|
|
416
|
+
* @returns void
|
|
417
|
+
*/
|
|
418
|
+
private static deleteOrder(orderStructs: OrderStruct, orderId: string): void {
|
|
419
|
+
// find order
|
|
420
|
+
let k;
|
|
421
|
+
for (k = 0; k < orderStructs.orderIds.length && orderStructs.orderIds[k] != orderId; k++);
|
|
422
|
+
if (orderStructs.orderIds[k] != orderId) {
|
|
423
|
+
emitWarning(`deleteOrder: no order found with digest ${orderId}`);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
// delete element k on reference of orders
|
|
427
|
+
orderStructs.orders[k] = orderStructs.orders[orderStructs.orders.length - 1];
|
|
428
|
+
orderStructs.orders.pop();
|
|
429
|
+
orderStructs.orderIds[k] = orderStructs.orderIds[orderStructs.orderIds.length - 1];
|
|
430
|
+
orderStructs.orderIds.pop();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* UpdateMarkPrice(
|
|
435
|
+
* uint24 indexed perpetualId,
|
|
436
|
+
* int128 fMarkPricePremium,
|
|
437
|
+
* int128 fSpotIndexPrice
|
|
438
|
+
* )
|
|
439
|
+
* @param fMarkPricePremium premium rate in ABDK format
|
|
440
|
+
* @param fSpotIndexPrice spot index price in ABDK format
|
|
441
|
+
* @returns mark price and spot index in float
|
|
442
|
+
*/
|
|
443
|
+
private static ConvertUpdateMarkPrice(
|
|
444
|
+
fMidPricePremium: BigNumber,
|
|
445
|
+
fMarkPricePremium: BigNumber,
|
|
446
|
+
fSpotIndexPrice: BigNumber
|
|
447
|
+
): [number, number, number] {
|
|
448
|
+
let fMarkPrice = mul64x64(fSpotIndexPrice, ONE_64x64.add(fMarkPricePremium));
|
|
449
|
+
let fMidPrice = mul64x64(fSpotIndexPrice, ONE_64x64.add(fMidPricePremium));
|
|
450
|
+
let midPrice = ABK64x64ToFloat(fMidPrice);
|
|
451
|
+
let markPrice = ABK64x64ToFloat(fMarkPrice);
|
|
452
|
+
let indexPrice = ABK64x64ToFloat(fSpotIndexPrice);
|
|
453
|
+
return [midPrice, markPrice, indexPrice];
|
|
454
|
+
}
|
|
455
|
+
}
|