@reyaxyz/api-sdk 0.26.0 → 0.28.0

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.
Files changed (95) hide show
  1. package/dist/clients/api-client.js +19 -0
  2. package/dist/clients/api-client.js.map +1 -1
  3. package/dist/clients/modules/{account.js → account/index.js} +2 -2
  4. package/dist/clients/modules/account/index.js.map +1 -0
  5. package/dist/clients/{helpers/trade.simulation.types.js → modules/account/types.js} +1 -1
  6. package/dist/clients/modules/account/types.js.map +1 -0
  7. package/dist/clients/modules/{lp.js → lp/index.js} +2 -2
  8. package/dist/clients/modules/lp/index.js.map +1 -0
  9. package/dist/clients/modules/lp/types.js +13 -0
  10. package/dist/clients/modules/lp/types.js.map +1 -0
  11. package/dist/clients/modules/{markets.js → markets/index.js} +2 -2
  12. package/dist/clients/modules/markets/index.js.map +1 -0
  13. package/dist/clients/modules/markets/types.js +3 -0
  14. package/dist/clients/modules/markets/types.js.map +1 -0
  15. package/dist/clients/modules/{rest.js → rest/index.js} +4 -4
  16. package/dist/clients/modules/rest/index.js.map +1 -0
  17. package/dist/clients/modules/tokens/index.js +75 -0
  18. package/dist/clients/modules/tokens/index.js.map +1 -0
  19. package/dist/clients/modules/tokens/types.js +3 -0
  20. package/dist/clients/modules/tokens/types.js.map +1 -0
  21. package/dist/clients/modules/{trade.simulation.js → trade.simulation/index.js} +10 -10
  22. package/dist/clients/modules/trade.simulation/index.js.map +1 -0
  23. package/dist/clients/modules/trade.simulation/types.js +3 -0
  24. package/dist/clients/modules/trade.simulation/types.js.map +1 -0
  25. package/dist/clients/types.js +4 -36
  26. package/dist/clients/types.js.map +1 -1
  27. package/dist/index.js +0 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/types/clients/api-client.d.ts +13 -0
  30. package/dist/types/clients/api-client.d.ts.map +1 -1
  31. package/dist/types/clients/modules/{account.d.ts → account/index.d.ts} +4 -4
  32. package/dist/types/clients/modules/account/index.d.ts.map +1 -0
  33. package/dist/types/clients/modules/account/types.d.ts +47 -0
  34. package/dist/types/clients/modules/account/types.d.ts.map +1 -0
  35. package/dist/types/clients/modules/{lp.d.ts → lp/index.d.ts} +4 -3
  36. package/dist/types/clients/modules/lp/index.d.ts.map +1 -0
  37. package/dist/types/clients/modules/lp/types.d.ts +46 -0
  38. package/dist/types/clients/modules/lp/types.d.ts.map +1 -0
  39. package/dist/types/clients/modules/{markets.d.ts → markets/index.d.ts} +3 -3
  40. package/dist/types/clients/modules/markets/index.d.ts.map +1 -0
  41. package/dist/types/clients/modules/markets/types.d.ts +23 -0
  42. package/dist/types/clients/modules/markets/types.d.ts.map +1 -0
  43. package/dist/types/clients/modules/{rest.d.ts → rest/index.d.ts} +2 -2
  44. package/dist/types/clients/modules/rest/index.d.ts.map +1 -0
  45. package/dist/types/clients/modules/tokens/index.d.ts +6 -0
  46. package/dist/types/clients/modules/tokens/index.d.ts.map +1 -0
  47. package/dist/types/clients/modules/tokens/types.d.ts +8 -0
  48. package/dist/types/clients/modules/tokens/types.d.ts.map +1 -0
  49. package/dist/types/clients/modules/{trade.simulation.d.ts → trade.simulation/index.d.ts} +3 -3
  50. package/dist/types/clients/modules/trade.simulation/index.d.ts.map +1 -0
  51. package/dist/types/clients/modules/trade.simulation/types.d.ts +19 -0
  52. package/dist/types/clients/modules/trade.simulation/types.d.ts.map +1 -0
  53. package/dist/types/clients/types.d.ts +1 -300
  54. package/dist/types/clients/types.d.ts.map +1 -1
  55. package/dist/types/index.d.ts +0 -2
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/package.json +6 -7
  58. package/src/clients/api-client.ts +17 -0
  59. package/src/clients/modules/{account.ts → account/index.ts} +3 -3
  60. package/src/clients/modules/account/types.ts +74 -0
  61. package/src/clients/modules/{lp.ts → lp/index.ts} +5 -3
  62. package/src/clients/modules/lp/types.ts +62 -0
  63. package/src/clients/modules/{markets.ts → markets/index.ts} +2 -2
  64. package/src/clients/modules/markets/types.ts +33 -0
  65. package/src/clients/modules/{rest.ts → rest/index.ts} +8 -3
  66. package/src/clients/modules/tokens/index.ts +11 -0
  67. package/src/clients/modules/tokens/types.ts +9 -0
  68. package/src/clients/modules/{trade.simulation.ts → trade.simulation/index.ts} +3 -4
  69. package/src/clients/modules/trade.simulation/types.ts +21 -0
  70. package/src/clients/types.ts +16 -388
  71. package/src/index.ts +0 -2
  72. package/dist/clients/helpers/exposure.calculator.js +0 -448
  73. package/dist/clients/helpers/exposure.calculator.js.map +0 -1
  74. package/dist/clients/helpers/number.js +0 -13
  75. package/dist/clients/helpers/number.js.map +0 -1
  76. package/dist/clients/helpers/trade.simulation.types.js.map +0 -1
  77. package/dist/clients/modules/account.js.map +0 -1
  78. package/dist/clients/modules/lp.js.map +0 -1
  79. package/dist/clients/modules/markets.js.map +0 -1
  80. package/dist/clients/modules/rest.js.map +0 -1
  81. package/dist/clients/modules/trade.simulation.js.map +0 -1
  82. package/dist/types/clients/helpers/exposure.calculator.d.ts +0 -58
  83. package/dist/types/clients/helpers/exposure.calculator.d.ts.map +0 -1
  84. package/dist/types/clients/helpers/number.d.ts +0 -3
  85. package/dist/types/clients/helpers/number.d.ts.map +0 -1
  86. package/dist/types/clients/helpers/trade.simulation.types.d.ts +0 -113
  87. package/dist/types/clients/helpers/trade.simulation.types.d.ts.map +0 -1
  88. package/dist/types/clients/modules/account.d.ts.map +0 -1
  89. package/dist/types/clients/modules/lp.d.ts.map +0 -1
  90. package/dist/types/clients/modules/markets.d.ts.map +0 -1
  91. package/dist/types/clients/modules/rest.d.ts.map +0 -1
  92. package/dist/types/clients/modules/trade.simulation.d.ts.map +0 -1
  93. package/src/clients/helpers/exposure.calculator.ts +0 -799
  94. package/src/clients/helpers/number.ts +0 -8
  95. package/src/clients/helpers/trade.simulation.types.ts +0 -125
@@ -1,799 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import _ from 'lodash';
3
- import {
4
- AccountAssetBalance,
5
- CollateralInfo,
6
- ExchangeInfo,
7
- ExposureCommandState,
8
- MarginInfo,
9
- MarketConfiguration,
10
- MarketIdToOraclePriceMap,
11
- MarketStorage,
12
- PositionInfo,
13
- PositionInfoMarketConfiguration,
14
- RiskMatrix,
15
- RiskMultipliersConfiguration,
16
- } from './trade.simulation.types';
17
- import { amountNormalizer } from './number';
18
-
19
- export class ExposureCommand {
20
- rootCollateralPoolId: number;
21
- oraclePricePerMarket: MarketIdToOraclePriceMap;
22
- accountBalancePerAsset: AccountAssetBalance[];
23
- groupedByCollateral: Record<string, AccountAssetBalance>;
24
- riskMultipliers: RiskMultipliersConfiguration;
25
- riskMatrices: RiskMatrix[];
26
- exchangeInfoPerAsset: ExchangeInfo[];
27
- positionInfoMarketConfiguration: PositionInfoMarketConfiguration[];
28
- uniqueTokenAddresses: string[];
29
- uniqueQuoteCollaterals: string[];
30
- tokenMarginInfoPerAsset: MarginInfo[];
31
- realizedPnLSum: BigNumber;
32
- unrealizedPnLSum: BigNumber;
33
- constructor(
34
- rootCollateralPoolId: number,
35
- oraclePricePerMarket: MarketIdToOraclePriceMap,
36
- accountBalancePerAsset: AccountAssetBalance[],
37
- groupedByCollateral: Record<string, AccountAssetBalance>,
38
- riskMultipliers: RiskMultipliersConfiguration,
39
- riskMatrices: RiskMatrix[],
40
- exchangeInfoPerAsset: ExchangeInfo[],
41
- positionInfoMarketConfiguration: PositionInfoMarketConfiguration[],
42
- uniqueTokenAddresses: string[],
43
- uniqueQuoteCollaterals: string[],
44
- tokenMarginInfoPerAsset: MarginInfo[],
45
- realizedPnLSum: BigNumber,
46
- unrealizedPnLSum: BigNumber,
47
- ) {
48
- this.rootCollateralPoolId = rootCollateralPoolId;
49
- this.oraclePricePerMarket = oraclePricePerMarket;
50
- this.accountBalancePerAsset = accountBalancePerAsset;
51
- this.groupedByCollateral = groupedByCollateral;
52
- this.riskMultipliers = riskMultipliers;
53
- this.riskMatrices = riskMatrices;
54
- this.exchangeInfoPerAsset = exchangeInfoPerAsset;
55
- this.positionInfoMarketConfiguration = positionInfoMarketConfiguration;
56
- this.uniqueTokenAddresses = uniqueTokenAddresses;
57
- this.uniqueQuoteCollaterals = uniqueQuoteCollaterals;
58
- this.tokenMarginInfoPerAsset = tokenMarginInfoPerAsset;
59
- this.realizedPnLSum = realizedPnLSum;
60
- this.unrealizedPnLSum = unrealizedPnLSum;
61
- }
62
-
63
- getState(): ExposureCommandState {
64
- return {
65
- rootCollateralPoolId: this.rootCollateralPoolId,
66
- oraclePricePerMarket: this.oraclePricePerMarket,
67
- accountBalancePerAsset: this.accountBalancePerAsset,
68
- groupedByCollateral: this.groupedByCollateral,
69
- riskMultipliers: this.riskMultipliers,
70
- riskMatrices: this.riskMatrices,
71
- exchangeInfoPerAsset: this.exchangeInfoPerAsset,
72
- positionInfoMarketConfiguration: this.positionInfoMarketConfiguration,
73
- uniqueTokenAddresses: this.uniqueTokenAddresses,
74
- uniqueQuoteCollaterals: this.uniqueQuoteCollaterals,
75
- tokenMarginInfoPerAsset: this.tokenMarginInfoPerAsset,
76
- realizedPnLSum: this.realizedPnLSum,
77
- unrealizedPnLSum: this.unrealizedPnLSum,
78
- };
79
- }
80
-
81
- get getUsdNodeMarginInfo() {
82
- return ExposureCommand.getUsdNodeMarginInfo(
83
- this.rootCollateralPoolId,
84
- this.uniqueTokenAddresses,
85
- this.exchangeInfoPerAsset,
86
- this.tokenMarginInfoPerAsset,
87
- );
88
- }
89
-
90
- get balancePerAsset() {
91
- return this.tokenMarginInfoPerAsset;
92
- }
93
- get exchangePricePerAsset() {
94
- return this.exchangeInfoPerAsset;
95
- }
96
-
97
- getUsdNodeMarginInfoPostTrade(
98
- positionAmount: number,
99
- collateralAddress: string,
100
- marketConfiguration: MarketConfiguration,
101
- ) {
102
- // perform deep copy of the object
103
- const positionInfoMarketConfiguration: PositionInfoMarketConfiguration[] =
104
- _.cloneDeep(this.positionInfoMarketConfiguration);
105
-
106
- // Check if the market_id already exists in the array
107
- const existingConfigIndex = positionInfoMarketConfiguration.findIndex(
108
- (config) =>
109
- config.market_id ===
110
- BigNumber(String(marketConfiguration.market_id)).toNumber(),
111
- );
112
-
113
- if (existingConfigIndex !== -1) {
114
- // If it exists, update the amount
115
- positionInfoMarketConfiguration[existingConfigIndex].base = BigNumber(
116
- positionInfoMarketConfiguration[existingConfigIndex].base,
117
- ).plus(positionAmount);
118
- } else {
119
- // If it doesn't exist, add a new element
120
- positionInfoMarketConfiguration.push({
121
- base: BigNumber(positionAmount),
122
- realized_pnl: BigNumber(0),
123
- last_price: BigNumber(0),
124
- last_timestamp: BigNumber(0),
125
- funding_value: BigNumber(0),
126
- base_multiplier: BigNumber(0),
127
- adl_unwind_price: BigNumber(0),
128
- market_id: BigNumber(String(marketConfiguration.market_id)).toNumber(),
129
- market_configuration: marketConfiguration,
130
- });
131
- }
132
-
133
- const uniqueQuoteCollaterals = new Set(this.uniqueQuoteCollaterals);
134
- uniqueQuoteCollaterals.add(collateralAddress);
135
-
136
- const tokenMarginInfoPerAsset =
137
- ExposureCommand.calculateTokenMarginInfoPerAsset(
138
- this.groupedByCollateral,
139
- this.rootCollateralPoolId,
140
- this.riskMatrices,
141
- this.riskMultipliers,
142
- uniqueQuoteCollaterals,
143
- this.realizedPnLSum,
144
- this.unrealizedPnLSum,
145
- positionInfoMarketConfiguration,
146
- this.oraclePricePerMarket,
147
- );
148
-
149
- const uniqueTokenAddresses = [...this.uniqueTokenAddresses];
150
- if (!this.uniqueTokenAddresses.includes(collateralAddress)) {
151
- uniqueTokenAddresses.push(collateralAddress);
152
- }
153
-
154
- return ExposureCommand.getUsdNodeMarginInfo(
155
- this.rootCollateralPoolId,
156
- uniqueTokenAddresses,
157
- this.exchangeInfoPerAsset,
158
- tokenMarginInfoPerAsset,
159
- );
160
- }
161
-
162
- static calculateTokenMarginInfoPerAsset(
163
- groupedByCollateral: Record<string, AccountAssetBalance>,
164
- rootCollateralPoolId: number,
165
- riskMatrices: RiskMatrix[],
166
- riskMultipliers: RiskMultipliersConfiguration,
167
- uniqueQuoteCollaterals: Set<string>,
168
- realizedPnLSum: BigNumber,
169
- unrealizedPnLSum: BigNumber,
170
- positionInfoMarketConfiguration: PositionInfoMarketConfiguration[],
171
- oraclePricePerMarket: MarketIdToOraclePriceMap,
172
- ): MarginInfo[] {
173
- const tokenMarginInfoPerAsset: MarginInfo[] = [];
174
-
175
- const uniqueQuoteTokens: string[] = Array.from(uniqueQuoteCollaterals);
176
-
177
- const tokenUnion = new Set([
178
- ...Object.keys(groupedByCollateral),
179
- ...uniqueQuoteTokens,
180
- ]); // get unique union of those arrays
181
- const uniqueTokenAddresses: string[] = Array.from(tokenUnion);
182
-
183
- for (const token of uniqueTokenAddresses) {
184
- tokenMarginInfoPerAsset.push(
185
- ExposureCommand.getTokenMarginInfo(
186
- rootCollateralPoolId,
187
- riskMatrices,
188
- riskMultipliers,
189
- ExposureCommand.getCollateralInfo(
190
- token,
191
- uniqueQuoteCollaterals.has(token) ? realizedPnLSum : BigNumber(0),
192
- uniqueQuoteCollaterals.has(token) ? unrealizedPnLSum : BigNumber(0),
193
- groupedByCollateral[token]?.amount || 0,
194
- ),
195
- token,
196
- positionInfoMarketConfiguration,
197
- oraclePricePerMarket,
198
- uniqueQuoteTokens,
199
- ),
200
- );
201
- }
202
-
203
- return tokenMarginInfoPerAsset;
204
- }
205
- static calculateLiquidation(
206
- globalMarginInfo: MarginInfo,
207
- oraclePrice: number,
208
- positionBase: number,
209
- ): BigNumber {
210
- const liquidationPrice = BigNumber(oraclePrice).minus(
211
- BigNumber(globalMarginInfo.marginBalance)
212
- .minus(globalMarginInfo.liquidationMarginRequirement)
213
- .div(positionBase),
214
- );
215
-
216
- return BigNumber.max(0, liquidationPrice);
217
- }
218
-
219
- static calculateImpliedLeverage(
220
- notionalExposure: number,
221
- oldIMR: number,
222
- newIMR: number,
223
- ): number {
224
- const changeInImr = BigNumber(newIMR).minus(oldIMR);
225
-
226
- if (changeInImr.eq(0)) {
227
- return 0;
228
- }
229
- return BigNumber(notionalExposure).div(changeInImr).toNumber();
230
- }
231
-
232
- static combineMarginInfo(
233
- parentMarginInfo: MarginInfo,
234
- sonMarginInfo: MarginInfo,
235
- sonParentExchangeInfo: ExchangeInfo,
236
- ): MarginInfo {
237
- return {
238
- assetAddress: parentMarginInfo.assetAddress,
239
- marginBalance: BigNumber(parentMarginInfo.marginBalance)
240
- .plus(
241
- ExposureCommand.exchangeWithPriceHaircut(
242
- sonMarginInfo.marginBalance,
243
- sonParentExchangeInfo.price,
244
- sonParentExchangeInfo.priceHaircut,
245
- ),
246
- )
247
- .toNumber(),
248
- realBalance: BigNumber(parentMarginInfo.realBalance)
249
- .plus(
250
- ExposureCommand.exchangeWithPriceHaircut(
251
- sonMarginInfo.realBalance,
252
- sonParentExchangeInfo.price,
253
- sonParentExchangeInfo.priceHaircut,
254
- ),
255
- )
256
- .toNumber(),
257
- initialDelta: BigNumber(parentMarginInfo.initialDelta)
258
- .plus(
259
- ExposureCommand.exchangeWithPriceHaircut(
260
- BigNumber.min(
261
- sonMarginInfo.realBalance,
262
- sonMarginInfo.initialDelta,
263
- ).toNumber(),
264
- sonParentExchangeInfo.price,
265
- sonParentExchangeInfo.priceHaircut,
266
- ),
267
- )
268
- .toNumber(),
269
- maintenanceDelta: BigNumber(parentMarginInfo.maintenanceDelta)
270
- .plus(
271
- ExposureCommand.exchangeWithPriceHaircut(
272
- BigNumber.min(
273
- sonMarginInfo.maintenanceDelta,
274
- sonMarginInfo.realBalance,
275
- ).toNumber(),
276
- sonParentExchangeInfo.price,
277
- sonParentExchangeInfo.priceHaircut,
278
- ),
279
- )
280
- .toNumber(),
281
- liquidationDelta: BigNumber(parentMarginInfo.liquidationDelta)
282
- .plus(
283
- ExposureCommand.exchangeWithPriceHaircut(
284
- BigNumber.min(
285
- sonMarginInfo.liquidationDelta,
286
- sonMarginInfo.realBalance,
287
- ).toNumber(),
288
- sonParentExchangeInfo.price,
289
- sonParentExchangeInfo.priceHaircut,
290
- ),
291
- )
292
- .toNumber(),
293
- dutchDelta: BigNumber(parentMarginInfo.dutchDelta)
294
- .plus(
295
- ExposureCommand.exchangeWithPriceHaircut(
296
- BigNumber.min(
297
- sonMarginInfo.dutchDelta,
298
- sonMarginInfo.realBalance,
299
- ).toNumber(),
300
- sonParentExchangeInfo.price,
301
- sonParentExchangeInfo.priceHaircut,
302
- ),
303
- )
304
- .toNumber(),
305
- adlDelta: BigNumber(parentMarginInfo.adlDelta)
306
- .plus(
307
- ExposureCommand.exchangeWithPriceHaircut(
308
- BigNumber.min(
309
- sonMarginInfo.adlDelta,
310
- sonMarginInfo.realBalance,
311
- ).toNumber(),
312
- sonParentExchangeInfo.price,
313
- sonParentExchangeInfo.priceHaircut,
314
- ),
315
- )
316
- .toNumber(),
317
-
318
- initialBufferDelta: BigNumber(parentMarginInfo.initialBufferDelta)
319
- .plus(
320
- ExposureCommand.exchangeWithPriceHaircut(
321
- BigNumber.min(
322
- sonMarginInfo.initialBufferDelta,
323
- sonMarginInfo.realBalance,
324
- ).toNumber(),
325
- sonParentExchangeInfo.price,
326
- sonParentExchangeInfo.priceHaircut,
327
- ),
328
- )
329
- .toNumber(),
330
- liquidationMarginRequirement: BigNumber(
331
- parentMarginInfo.liquidationMarginRequirement,
332
- )
333
- .plus(
334
- ExposureCommand.exchangeWithPriceHaircut(
335
- sonMarginInfo.liquidationMarginRequirement,
336
- sonParentExchangeInfo.price,
337
- sonParentExchangeInfo.priceHaircut,
338
- ),
339
- )
340
- .toNumber(),
341
- };
342
- }
343
-
344
- static getUsdNodeMarginInfo(
345
- accountCollateralPoolId: number,
346
- quoteTokens: string[],
347
- exchangeInfoPerAsset: ExchangeInfo[],
348
- marginInfoPerToken: MarginInfo[],
349
- ) {
350
- let usdNodeMarginInfo: MarginInfo = {
351
- assetAddress: '',
352
- marginBalance: 0,
353
- realBalance: 0,
354
- initialDelta: 0,
355
- maintenanceDelta: 0,
356
- liquidationDelta: 0,
357
- dutchDelta: 0,
358
- adlDelta: 0,
359
- initialBufferDelta: 0,
360
- liquidationMarginRequirement: 0,
361
- };
362
- for (const quoteToken of quoteTokens) {
363
- const exchangeInfo = exchangeInfoPerAsset.find((exchangeInfo) => {
364
- return quoteToken === exchangeInfo.tokenAddress;
365
- });
366
-
367
- const marginInfo = marginInfoPerToken.find((marginInfo) => {
368
- return quoteToken === marginInfo.assetAddress;
369
- });
370
-
371
- if (!exchangeInfo || !marginInfo) {
372
- throw Error('Missing exchangeInfo/marginInfo');
373
- }
374
-
375
- usdNodeMarginInfo = ExposureCommand.combineMarginInfo(
376
- usdNodeMarginInfo,
377
- marginInfo,
378
- exchangeInfo,
379
- );
380
- }
381
-
382
- return usdNodeMarginInfo;
383
- }
384
- static getCollateralInfo(
385
- collateralAddress: string,
386
- realisedPnl: BigNumber,
387
- unrealizedPnL: BigNumber,
388
- netDeposits: number,
389
- ): CollateralInfo {
390
- return {
391
- netDeposits: netDeposits,
392
- marginBalance: BigNumber(netDeposits)
393
- .plus(realisedPnl)
394
- .plus(unrealizedPnL)
395
- .toNumber(),
396
- realBalance: BigNumber(netDeposits).plus(realisedPnl).toNumber(),
397
- };
398
- }
399
-
400
- static getTokenMarginInfo(
401
- rootCollateralPoolId: number,
402
- riskMatrices: RiskMatrix[],
403
- riskMultipliers: RiskMultipliersConfiguration,
404
- collateralInfo: CollateralInfo,
405
- collateralAddress: string,
406
- positions: PositionInfoMarketConfiguration[],
407
- oraclePricePerMarket: MarketIdToOraclePriceMap,
408
- uniqueQuoteTokens: string[],
409
- ): MarginInfo {
410
- const marginRequirements = {
411
- liquidationMarginRequirement: 0,
412
- initialMarginRequirement: 0,
413
- maintenanceMarginRequirement: 0,
414
- dutchMarginRequirement: 0,
415
- adlMarginRequirement: 0,
416
- initialBufferMarginRequirement: 0,
417
- };
418
- if (uniqueQuoteTokens.includes(collateralAddress)) {
419
- // uniqueQuoteTokens is list is active markets tokens
420
- for (const riskMatrix of riskMatrices) {
421
- if (Number(riskMatrix.risk_block_id) === 1) continue; // @todo remove and implement correct logic!
422
- const filledExposures = ExposureCommand.getBlockExposures(
423
- positions,
424
- oraclePricePerMarket,
425
- );
426
-
427
- marginRequirements.liquidationMarginRequirement = BigNumber(
428
- marginRequirements.liquidationMarginRequirement,
429
- )
430
- .plus(
431
- ExposureCommand.computeLiquidationMarginRequirement(
432
- riskMatrix.matrix,
433
- filledExposures,
434
- ),
435
- )
436
- .toNumber();
437
- }
438
-
439
- // Get the initial margin requirement
440
- marginRequirements.initialMarginRequirement = amountNormalizer(
441
- String(riskMultipliers.im_multiplier),
442
- )
443
- .multipliedBy(marginRequirements.liquidationMarginRequirement)
444
- .toNumber();
445
- // Get the maintenance margin requirement
446
- marginRequirements.maintenanceMarginRequirement = amountNormalizer(
447
- String(riskMultipliers.mmr_multiplier),
448
- )
449
- .multipliedBy(marginRequirements.liquidationMarginRequirement)
450
- .toNumber();
451
- // Get the dutch margin requirement
452
- marginRequirements.dutchMarginRequirement = amountNormalizer(
453
- String(riskMultipliers.dutch_multiplier),
454
- )
455
- .multipliedBy(marginRequirements.liquidationMarginRequirement)
456
- .toNumber();
457
-
458
- // Get the adl margin requirement
459
- marginRequirements.adlMarginRequirement = amountNormalizer(
460
- String(riskMultipliers.adl_multiplier),
461
- )
462
- .multipliedBy(marginRequirements.liquidationMarginRequirement)
463
- .toNumber();
464
-
465
- // Get the initial buffer margin requirement
466
- marginRequirements.initialBufferMarginRequirement = amountNormalizer(
467
- String(riskMultipliers.im_buffer_multiplier),
468
- )
469
- .multipliedBy(marginRequirements.liquidationMarginRequirement)
470
- .toNumber();
471
- }
472
- return {
473
- assetAddress: collateralAddress,
474
- marginBalance: collateralInfo.marginBalance,
475
- realBalance: collateralInfo.realBalance,
476
- initialDelta: BigNumber(collateralInfo.marginBalance)
477
- .minus(marginRequirements.initialMarginRequirement)
478
- .toNumber(),
479
- maintenanceDelta: BigNumber(collateralInfo.marginBalance)
480
- .minus(marginRequirements.maintenanceMarginRequirement)
481
- .toNumber(),
482
- liquidationDelta: BigNumber(collateralInfo.marginBalance)
483
- .minus(marginRequirements.liquidationMarginRequirement)
484
- .toNumber(),
485
- dutchDelta: BigNumber(collateralInfo.marginBalance)
486
- .minus(marginRequirements.dutchMarginRequirement)
487
- .toNumber(),
488
- adlDelta: BigNumber(collateralInfo.marginBalance)
489
- .minus(marginRequirements.adlMarginRequirement)
490
- .toNumber(),
491
- initialBufferDelta: BigNumber(collateralInfo.marginBalance)
492
- .minus(marginRequirements.initialBufferMarginRequirement)
493
- .toNumber(),
494
- liquidationMarginRequirement:
495
- marginRequirements.liquidationMarginRequirement,
496
- };
497
- }
498
-
499
- static computeLiquidationMarginRequirement(
500
- matrix: BigNumber[][],
501
- filledExposures: BigNumber[],
502
- ): number {
503
- let lmrFilledSquared = 0;
504
-
505
- for (let i = 0; i < filledExposures.length; i++) {
506
- if (BigNumber(filledExposures[i]).eq(0)) {
507
- continue;
508
- }
509
- for (let j = 0; j < filledExposures.length; j++) {
510
- const riskParam = matrix[i][j];
511
-
512
- if (BigNumber(filledExposures[j]).eq(0) || BigNumber(riskParam).eq(0)) {
513
- continue;
514
- }
515
-
516
- lmrFilledSquared = BigNumber(lmrFilledSquared)
517
- .plus(
518
- BigNumber(filledExposures[i])
519
- .multipliedBy(filledExposures[j])
520
- .multipliedBy(riskParam),
521
- )
522
- .toNumber();
523
- }
524
- }
525
- return BigNumber(lmrFilledSquared).sqrt().toNumber();
526
- }
527
-
528
- static getBlockExposures(
529
- positions: PositionInfoMarketConfiguration[],
530
- oraclePricePerMarket: MarketIdToOraclePriceMap,
531
- ): BigNumber[] {
532
- const filledExposures: number[] = [];
533
-
534
- for (const position of positions) {
535
- const marketFilledExposure = ExposureCommand.getAccountFilledExposures(
536
- position,
537
- position.market_configuration,
538
- oraclePricePerMarket[position.market_id],
539
- );
540
- filledExposures[marketFilledExposure.riskMatrixIndex] = BigNumber(
541
- filledExposures[marketFilledExposure.riskMatrixIndex] || 0,
542
- )
543
- .plus(marketFilledExposure.exposure)
544
- .toNumber();
545
- }
546
-
547
- return filledExposures.map((num) => BigNumber(num));
548
- }
549
-
550
- static getAccountFilledExposures(
551
- position: PositionInfo,
552
- marketConfiguration: MarketConfiguration,
553
- oraclePrice: number,
554
- ) {
555
- const base = position.base;
556
-
557
- return {
558
- exposure: BigNumber(oraclePrice).multipliedBy(base),
559
- riskMatrixIndex: BigNumber(
560
- String(marketConfiguration.risk_matrix_index),
561
- ).toNumber(),
562
- };
563
- }
564
-
565
- static computePricePnL(
566
- openBase: BigNumber,
567
- openPrice: BigNumber,
568
- exitPrice: BigNumber,
569
- ) {
570
- return BigNumber(
571
- BigNumber(exitPrice).minus(openPrice).multipliedBy(openBase),
572
- );
573
- }
574
-
575
- static getMarginRatio(marginInfo: MarginInfo) {
576
- if (marginInfo.liquidationMarginRequirement === 0) {
577
- return 0;
578
- }
579
-
580
- if (marginInfo.marginBalance <= 0) {
581
- return 1;
582
- }
583
-
584
- const health = BigNumber(marginInfo.liquidationMarginRequirement).div(
585
- marginInfo.marginBalance,
586
- );
587
-
588
- if (health.gt(1)) {
589
- return 1;
590
- }
591
- return health.toNumber();
592
- }
593
-
594
- static exchangeWithPriceHaircut(
595
- quantity: number,
596
- price: number,
597
- haircut: number,
598
- ) {
599
- // For positive quantities, the haircut is `quantity * (1 - haircut)`
600
- // For negative values, the haircut is `quantity / (1 - haircut)` because a negative value means the haircut should be applied from B to A.
601
- const calHelper = BigNumber(quantity).gt(0)
602
- ? BigNumber(1).minus(haircut)
603
- : BigNumber(1).div(BigNumber(1).minus(haircut));
604
- const haircutPrice = BigNumber(price).multipliedBy(calHelper);
605
-
606
- return haircutPrice.multipliedBy(quantity).toNumber();
607
- }
608
-
609
- getSlippage(
610
- deltaBase: number,
611
- marketConfiguration: MarketConfiguration,
612
- marketStorage: MarketStorage,
613
- ): number {
614
- const deltaExposure = BigNumber(
615
- this.oraclePricePerMarket[marketConfiguration.market_id],
616
- )
617
- .times(deltaBase)
618
- .toNumber();
619
-
620
- const riskMatrixIndex = BigNumber(
621
- String(marketConfiguration.risk_matrix_index),
622
- ).toNumber();
623
-
624
- const { maxExposureShort, maxExposureLong, exposures } =
625
- this.getMaxExposure(marketConfiguration, marketStorage);
626
-
627
- const netExposure = exposures[riskMatrixIndex].plus(deltaExposure);
628
- const maxExposure = netExposure.lt(0) ? maxExposureShort : maxExposureLong;
629
-
630
- return BigNumber(netExposure)
631
- .negated()
632
- .div(BigNumber(maxExposure).plus(netExposure))
633
- .toNumber();
634
- }
635
-
636
- getMaxExposure(
637
- marketConfiguration: MarketConfiguration,
638
- marketStorage: MarketStorage,
639
- ) {
640
- const riskMatrix = this.riskMatrices.find((riskMatrix) => {
641
- return (
642
- riskMatrix.risk_block_id ===
643
- BigNumber(String(marketStorage.risk_block_id)).toNumber()
644
- );
645
- });
646
-
647
- if (!riskMatrix) {
648
- throw new Error("RiskMatrix Doesn't exist");
649
- }
650
-
651
- const riskMatrixIndex = BigNumber(
652
- String(marketConfiguration.risk_matrix_index),
653
- ).toNumber();
654
-
655
- const imrMultiplier = amountNormalizer(
656
- String(this.riskMultipliers.im_multiplier),
657
- ).toNumber();
658
-
659
- const marginInfo = this.tokenMarginInfoPerAsset.find((marginInfo) => {
660
- return marginInfo.assetAddress === marketStorage.quote_collateral;
661
- });
662
-
663
- if (!marginInfo) {
664
- throw new Error("marginInfo doesn't exist");
665
- }
666
-
667
- const exposures = ExposureCommand.getBlockExposures(
668
- this.positionInfoMarketConfiguration,
669
- this.oraclePricePerMarket,
670
- );
671
-
672
- const { maxExposureShort, maxExposureLong } =
673
- ExposureCommand.computeMaxExposures(
674
- riskMatrix.matrix,
675
- exposures,
676
- marginInfo.liquidationMarginRequirement,
677
- marginInfo.marginBalance < 0 ? 0 : marginInfo.marginBalance,
678
- imrMultiplier,
679
- riskMatrixIndex,
680
- );
681
-
682
- return {
683
- maxExposureShort,
684
- maxExposureLong,
685
- exposures,
686
- };
687
- }
688
-
689
- static computeMaxExposures(
690
- riskMatrix: BigNumber[][],
691
- exposures: BigNumber[],
692
- lmr: number,
693
- balance: number,
694
- imrMultiplier: number,
695
- exposureIndex: number,
696
- ) {
697
- let b = BigNumber(0);
698
-
699
- for (let i = 0; i < exposures.length; i++) {
700
- b = BigNumber(b).plus(
701
- BigNumber(exposures[i]).multipliedBy(
702
- BigNumber(riskMatrix[exposureIndex][i]).plus(
703
- riskMatrix[i][exposureIndex],
704
- ),
705
- ),
706
- );
707
- }
708
- const { x1, x2 } = this.solveQuadraticEquation(
709
- BigNumber(riskMatrix[exposureIndex][exposureIndex]).toNumber(), // changes here
710
- b.toNumber(),
711
- this.computeC(lmr, balance, imrMultiplier),
712
- );
713
-
714
- const maxShortExposure = BigNumber(x1).plus(exposures[exposureIndex]);
715
- const maxLongExposure = BigNumber(x2).plus(exposures[exposureIndex]);
716
-
717
- const availableShortExposure = maxShortExposure.lt(0)
718
- ? maxShortExposure.negated().toNumber()
719
- : 0;
720
-
721
- const availableLongExposure = maxLongExposure.gt(0)
722
- ? maxLongExposure.toNumber()
723
- : 0;
724
-
725
- return {
726
- maxExposureShort: availableShortExposure,
727
- maxExposureLong: availableLongExposure,
728
- };
729
- }
730
-
731
- static solveQuadraticEquation(a: number, b: number, c: number) {
732
- if (BigNumber(a).eq(0)) {
733
- throw new Error('ZeroQuadraticCoefficient');
734
- }
735
-
736
- const delta = BigNumber(b)
737
- .multipliedBy(b)
738
- .minus(BigNumber(4).multipliedBy(a).multipliedBy(c));
739
-
740
- if (delta.lt(0)) {
741
- throw new Error('ComplexQuadraticRoots(a, b, c)');
742
- }
743
-
744
- const rootDelta = delta.sqrt();
745
-
746
- const x1 = BigNumber(b)
747
- .multipliedBy(-1)
748
- .minus(rootDelta)
749
- .div(BigNumber(2).multipliedBy(a));
750
-
751
- const x2 = BigNumber(b)
752
- .multipliedBy(-1)
753
- .plus(rootDelta)
754
- .div(BigNumber(2).multipliedBy(a));
755
-
756
- return {
757
- x1,
758
- x2,
759
- };
760
- }
761
-
762
- static computeC(lmr: number, balance: number, imrMultiplier: number): number {
763
- const lmrSD = BigNumber(lmr);
764
- const lmrSquared = lmrSD.multipliedBy(lmrSD);
765
-
766
- const balanceSD = BigNumber(balance);
767
- const balanceSquared = balanceSD.multipliedBy(balanceSD);
768
-
769
- const imrMultiplierSD = BigNumber(imrMultiplier);
770
- const imrMultiplierSquared = imrMultiplierSD.multipliedBy(imrMultiplierSD);
771
-
772
- return lmrSquared
773
- .minus(balanceSquared.div(imrMultiplierSquared))
774
- .toNumber();
775
- }
776
-
777
- static calculateFee(
778
- price: number,
779
- amount: number,
780
- feeParameter: BigNumber,
781
- ): number {
782
- return BigNumber(price).times(amount).times(feeParameter).abs().toNumber(); // @todo abs value
783
- }
784
-
785
- static calculateEstimatedPrice(price: number, slippage: number): number {
786
- return BigNumber(price).times(BigNumber(1).plus(slippage)).toNumber();
787
- }
788
-
789
- static evaluateHealthStatus(number: number) {
790
- // todo update logic
791
- if (number >= 67) {
792
- return 'danger';
793
- } else if (number >= 34) {
794
- return 'warning';
795
- } else {
796
- return 'healthy';
797
- }
798
- }
799
- }