avantis-trader-sdk 0.8.2__py3-none-any.whl → 0.8.4__py3-none-any.whl

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 (40) hide show
  1. avantis_trader_sdk/__init__.py +5 -5
  2. avantis_trader_sdk/abis/AggregatorV3Interface.json +606 -606
  3. avantis_trader_sdk/abis/IPyth.sol/IPyth.dbg.json +4 -4
  4. avantis_trader_sdk/abis/Referral.sol/ReferralStorage.json +7132 -7132
  5. avantis_trader_sdk/abis/Sanctions.json +190 -190
  6. avantis_trader_sdk/abis/Trading.sol/Trading.json +1 -1
  7. avantis_trader_sdk/abis/USDC.sol/USDC.dbg.json +4 -4
  8. avantis_trader_sdk/abis/interfaces/ICallbacks.sol/ICallbacks.json +2637 -2637
  9. avantis_trader_sdk/abis/interfaces/IExecute.sol/IExecute.json +1628 -1628
  10. avantis_trader_sdk/abis/interfaces/IPairInfos.sol/IPairInfos.json +2781 -2781
  11. avantis_trader_sdk/abis/interfaces/IPairStorage.sol/IPairStorage.json +3729 -3729
  12. avantis_trader_sdk/abis/interfaces/IPriceAggregator.sol/IPriceAggregator.json +2330 -2330
  13. avantis_trader_sdk/abis/interfaces/IReferral.sol/IReferral.json +1890 -1890
  14. avantis_trader_sdk/abis/interfaces/ITradingStorage.sol/ITradingStorage.json +7022 -7022
  15. avantis_trader_sdk/abis/interfaces/ITranche.sol/ITranche.json +1283 -1283
  16. avantis_trader_sdk/abis/interfaces/IVaultManager.sol/IVaultManager.json +2424 -2424
  17. avantis_trader_sdk/abis/interfaces/IVeTranche.sol/IVeTranche.json +855 -855
  18. avantis_trader_sdk/abis/library/PositionMath.sol/PositionMath.dbg.json +4 -4
  19. avantis_trader_sdk/abis/library/PositionMath.sol/PositionMath.json +10 -10
  20. avantis_trader_sdk/abis/testnet/USDC.sol/USDC.dbg.json +4 -4
  21. avantis_trader_sdk/abis/testnet/USDC.sol/USDC.json +320 -320
  22. avantis_trader_sdk/client.py +369 -367
  23. avantis_trader_sdk/config.py +14 -14
  24. avantis_trader_sdk/feed/feed_client.py +263 -261
  25. avantis_trader_sdk/rpc/asset_parameters.py +499 -499
  26. avantis_trader_sdk/rpc/blended.py +71 -71
  27. avantis_trader_sdk/rpc/category_parameters.py +216 -216
  28. avantis_trader_sdk/rpc/fee_parameters.py +237 -237
  29. avantis_trader_sdk/rpc/pairs_cache.py +130 -130
  30. avantis_trader_sdk/rpc/rpc_helpers.py +8 -8
  31. avantis_trader_sdk/rpc/snapshot.py +142 -142
  32. avantis_trader_sdk/rpc/trade.py +701 -710
  33. avantis_trader_sdk/rpc/trading_parameters.py +139 -139
  34. avantis_trader_sdk/types.py +462 -462
  35. avantis_trader_sdk/utils.py +78 -78
  36. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/METADATA +124 -113
  37. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/RECORD +39 -40
  38. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/WHEEL +1 -1
  39. avantis_trader_sdk/feed/feedIds.json +0 -214
  40. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/top_level.txt +0 -0
@@ -1,499 +1,499 @@
1
- import asyncio
2
- from .rpc_helpers import map_output_to_pairs
3
- from ..types import (
4
- OpenInterest,
5
- OpenInterestLimits,
6
- Utilization,
7
- Skew,
8
- Spread,
9
- Depth,
10
- )
11
- from typing import Optional
12
-
13
-
14
- class AssetParametersRPC:
15
- """
16
- This class provides methods to retrieve and calculate various asset parameters
17
- related to open interest, open interest limits, and asset utilization.
18
- """
19
-
20
- def __init__(self, client):
21
- """
22
- Constructor for the AssetParametersRPC class.
23
-
24
- Args:
25
- client: The TraderClient object.
26
- """
27
- self.client = client
28
-
29
- async def get_oi_limits(self):
30
- """
31
- Retrieves the open interest limits for all trading pairs.
32
-
33
- Returns:
34
- An OpenInterestLimits instance containing the open interest limits
35
- for each trading pair.
36
- """
37
- PairStorage = self.client.contracts.get("PairStorage")
38
- Multicall = self.client.contracts.get("Multicall")
39
- pairs_info = await self.client.pairs_cache.get_pairs_info()
40
- calls = []
41
- for pair_index in range(len(pairs_info)):
42
- call_data = PairStorage.encodeABI(fn_name="pairMaxOI", args=[pair_index])
43
- calls.append((PairStorage.address, call_data))
44
-
45
- response = await Multicall.functions.aggregate(calls).call()
46
- decoded_response = [
47
- int.from_bytes(value, byteorder="big") / 10**6 for value in response[1]
48
- ]
49
-
50
- return OpenInterestLimits(
51
- limits=map_output_to_pairs(pairs_info, decoded_response)
52
- )
53
-
54
- async def get_oi(self):
55
- """
56
- Retrieves the current open interest for all trading pairs.
57
-
58
- Returns:
59
- An OpenInterest instance containing the long and short open interest
60
- ratios for each trading pair.
61
- """
62
- Multicall = self.client.contracts.get("Multicall")
63
- pairs_info = await self.client.pairs_cache.get_pairs_info()
64
- raw_data = await Multicall.functions.getLongShortRatios().call()
65
- decoded = self.client.utils["decoder"](
66
- Multicall, "getLongShortRatios", raw_data
67
- )
68
-
69
- return OpenInterest(
70
- long=map_output_to_pairs(
71
- pairs_info, [val / 10**6 for val in decoded["longRatio"]]
72
- ),
73
- short=map_output_to_pairs(
74
- pairs_info, [val / 10**6 for val in decoded["shortRatio"]]
75
- ),
76
- )
77
-
78
- async def get_utilization(self):
79
- """
80
- Calculates the asset utilization for all trading pairs.
81
-
82
- Returns:
83
- A Utilization instance containing the asset utilization
84
- absolute value for each trading pair.
85
- """
86
- TradingStorage = self.client.contracts.get("TradingStorage")
87
- Multicall = self.client.contracts.get("Multicall")
88
- pairs_info = await self.client.pairs_cache.get_pairs_info()
89
- calls = []
90
- for pair_index in range(len(pairs_info)):
91
- call_data = TradingStorage.encodeABI(fn_name="pairOI", args=[pair_index])
92
- calls.append((TradingStorage.address, call_data))
93
-
94
- oi_limits_task = self.get_oi_limits()
95
- aggregate_task = Multicall.functions.aggregate(calls).call()
96
-
97
- oi_limits, aggregate_response = await asyncio.gather(
98
- oi_limits_task, aggregate_task
99
- )
100
-
101
- utilization = {}
102
- for pair_index, (pair_data, oi_limit) in enumerate(
103
- zip(aggregate_response[1], oi_limits.limits.values())
104
- ):
105
- pair_name = f"{pairs_info[pair_index].from_}/{pairs_info[pair_index].to}"
106
- current_oi = int.from_bytes(pair_data, byteorder="big") / 10**6
107
- limit = oi_limit
108
- utilization[pair_name] = current_oi / limit if limit else 0
109
-
110
- return Utilization(utilization=utilization)
111
-
112
- async def get_asset_skew(self):
113
- """
114
- Calculates the asset skew for all trading pairs.
115
-
116
- Returns:
117
- An Skew instance containing the asset skew
118
- absolute value for each trading pair.
119
- """
120
- oi = await self.get_oi()
121
-
122
- skew = {}
123
- for pair, long_ratio in oi.long.items():
124
- short_ratio = oi.short[pair]
125
- skew[pair] = (
126
- long_ratio / (long_ratio + short_ratio)
127
- if long_ratio + short_ratio
128
- else 0
129
- )
130
-
131
- return Skew(skew=skew)
132
-
133
- async def get_price_impact_spread(
134
- self, position_size: int = 0, is_long: Optional[bool] = None, pair: str = None
135
- ):
136
- """
137
- Retrieves the price impact spread for all trading pairs.
138
-
139
- Args:
140
- is_long: A boolean indicating if the position is a buy or sell. Defaults to None. If None, the price impact spread for both buy and sell will be returned.
141
- position_size: The size of the position (collateral * leverage). Supports upto 6 decimals. Defaults to 0.
142
- pair: The trading pair for which the price impact spread is to be calculated. Defaults to None. If None, the price impact spread for all trading pairs will be returned.
143
-
144
- Returns:
145
- A Spread instance containing the price impact spread for each trading pair in bps.
146
- """
147
- position_size = int(position_size * 10**6)
148
-
149
- Multicall = self.client.contracts.get("Multicall")
150
-
151
- calls = []
152
- response = None
153
-
154
- if pair is not None:
155
- pair_index = await self.client.pairs_cache.get_pair_index(pair)
156
- PairInfos = self.client.contracts.get("PairInfos")
157
- if is_long is None:
158
- calls.extend(
159
- [
160
- (
161
- PairInfos.address,
162
- PairInfos.encodeABI(
163
- fn_name="getPriceImpactSpread",
164
- args=[pair_index, True, position_size, False],
165
- ),
166
- ),
167
- (
168
- PairInfos.address,
169
- PairInfos.encodeABI(
170
- fn_name="getPriceImpactSpread",
171
- args=[pair_index, False, position_size, False],
172
- ),
173
- ),
174
- ]
175
- )
176
- else:
177
- response = await PairInfos.functions.getPriceImpactSpread(
178
- pair_index, is_long, position_size, False
179
- ).call()
180
- else:
181
- pairs_info = await self.client.pairs_cache.get_pairs_info()
182
- PairInfos = self.client.contracts.get("PairInfos")
183
- for pair_index in range(len(pairs_info)):
184
-
185
- if is_long is None:
186
- calls.extend(
187
- [
188
- (
189
- PairInfos.address,
190
- PairInfos.encodeABI(
191
- fn_name="getPriceImpactSpread",
192
- args=[pair_index, True, position_size, False],
193
- ),
194
- ),
195
- (
196
- PairInfos.address,
197
- PairInfos.encodeABI(
198
- fn_name="getPriceImpactSpread",
199
- args=[pair_index, False, position_size, False],
200
- ),
201
- ),
202
- ]
203
- )
204
- else:
205
- calls.append(
206
- (
207
- PairInfos.address,
208
- PairInfos.encodeABI(
209
- fn_name="getPriceImpactSpread",
210
- args=[pair_index, is_long, position_size, False],
211
- ),
212
- )
213
- )
214
-
215
- if response is None:
216
- response = await Multicall.functions.tryAggregate(False, calls).call()
217
- if is_long is None:
218
- decoded_response = [
219
- (
220
- (int.from_bytes(value, byteorder="big") / 10**10 * 100)
221
- if success
222
- else 0
223
- )
224
- for success, value in response
225
- ]
226
- if pair is None:
227
- return Spread(
228
- long=map_output_to_pairs(pairs_info, decoded_response[::2]),
229
- short=map_output_to_pairs(pairs_info, decoded_response[1::2]),
230
- )
231
- else:
232
- return Spread(
233
- long={pair: decoded_response[0]},
234
- short={pair: decoded_response[1]},
235
- )
236
- elif is_long:
237
- decoded_response = map_output_to_pairs(
238
- pairs_info,
239
- [
240
- (
241
- (int.from_bytes(value, byteorder="big") / 10**10 * 100)
242
- if success
243
- else 0
244
- )
245
- for success, value in response
246
- ],
247
- )
248
- return Spread(long=decoded_response)
249
- else:
250
- decoded_response = map_output_to_pairs(
251
- pairs_info,
252
- [
253
- (
254
- (int.from_bytes(value, byteorder="big") / 10**10 * 100)
255
- if success
256
- else 0
257
- )
258
- for success, value in response
259
- ],
260
- )
261
- return Spread(short=decoded_response)
262
- elif is_long:
263
- return Spread(long={pair: response / 10**10 * 100})
264
- else:
265
- return Spread(short={pair: response / 10**10 * 100})
266
-
267
- async def get_skew_impact_spread(
268
- self, position_size: int = 0, is_long: Optional[bool] = None, pair: str = None
269
- ):
270
- """
271
- Retrieves the skew impact spread for all trading pairs.
272
-
273
- Args:
274
- is_long: A boolean indicating if the position is a buy or sell. Defaults to None. If None, the skew impact spread for both buy and sell will be returned.
275
- position_size: The size of the position (collateral * leverage). Supports upto 6 decimals. Defaults to 0.
276
- pair: The trading pair for which the skew impact spread is to be calculated. Defaults to None. If None, the skew impact spread for all trading pairs will be returned.
277
-
278
- Returns:
279
- A Spread instance containing the skew impact spread for each trading pair in bps.
280
- """
281
- position_size = int(position_size * 10**6)
282
-
283
- Multicall = self.client.contracts.get("Multicall")
284
-
285
- calls = []
286
- response = None
287
-
288
- if pair is not None:
289
- pair_index = await self.client.pairs_cache.get_pair_index(pair)
290
- PairInfos = self.client.contracts.get("PairInfos")
291
- if is_long is None:
292
- calls.extend(
293
- [
294
- (
295
- PairInfos.address,
296
- PairInfos.encodeABI(
297
- fn_name="getSkewImpactSpread",
298
- args=[pair_index, True, position_size, False],
299
- ),
300
- ),
301
- (
302
- PairInfos.address,
303
- PairInfos.encodeABI(
304
- fn_name="getSkewImpactSpread",
305
- args=[pair_index, False, position_size, False],
306
- ),
307
- ),
308
- ]
309
- )
310
- else:
311
- response = await PairInfos.functions.getSkewImpactSpread(
312
- pair_index, is_long, position_size, False
313
- ).call()
314
- else:
315
- pairs_info = await self.client.pairs_cache.get_pairs_info()
316
- PairInfos = self.client.contracts.get("PairInfos")
317
- for pair_index in range(len(pairs_info)):
318
- if is_long is None:
319
- calls.extend(
320
- [
321
- (
322
- PairInfos.address,
323
- PairInfos.encodeABI(
324
- fn_name="getSkewImpactSpread",
325
- args=[pair_index, True, position_size, False],
326
- ),
327
- ),
328
- (
329
- PairInfos.address,
330
- PairInfos.encodeABI(
331
- fn_name="getSkewImpactSpread",
332
- args=[pair_index, False, position_size, False],
333
- ),
334
- ),
335
- ]
336
- )
337
- else:
338
- calls.append(
339
- (
340
- PairInfos.address,
341
- PairInfos.encodeABI(
342
- fn_name="getSkewImpactSpread",
343
- args=[pair_index, is_long, position_size, False],
344
- ),
345
- )
346
- )
347
-
348
- if response is None:
349
- response = await Multicall.functions.aggregate(calls).call()
350
- if is_long is None:
351
-
352
- decoded_response = [
353
- int.from_bytes(value, byteorder="big", signed=True) / 10**10 * 100
354
- for value in response[1]
355
- ]
356
- if pair is None:
357
- return Spread(
358
- long=map_output_to_pairs(pairs_info, decoded_response[::2]),
359
- short=map_output_to_pairs(pairs_info, decoded_response[1::2]),
360
- )
361
- else:
362
- return Spread(
363
- long={pair: decoded_response[0]},
364
- short={pair: decoded_response[1]},
365
- )
366
- elif is_long:
367
- decoded_response = map_output_to_pairs(
368
- pairs_info,
369
- [
370
- int.from_bytes(value, byteorder="big") / 10**10 * 100
371
- for value in response[1]
372
- ],
373
- )
374
- return Spread(long=decoded_response)
375
- else:
376
- decoded_response = map_output_to_pairs(
377
- pairs_info,
378
- [
379
- int.from_bytes(value, byteorder="big") / 10**10 * 100
380
- for value in response[1]
381
- ],
382
- )
383
- return Spread(short=decoded_response)
384
- elif is_long:
385
- return Spread(long={pair: response / 10**10 * 100})
386
- else:
387
- return Spread(short={pair: response / 10**10 * 100})
388
-
389
- async def get_opening_price_impact_spread(
390
- self,
391
- pair: str,
392
- position_size: int = 0,
393
- open_price: float = 0,
394
- is_long: Optional[bool] = None,
395
- ):
396
- """
397
- Retrieves the trade price impact spread for pair.
398
-
399
- Args:
400
- pair: The trading pair for which the price impact is to be calculated.
401
- position_size: The size of the position (collateral * leverage). Supports upto 6 decimals. Defaults to 0.
402
- open_price: The price at which the position was opened. Supports upto 10 decimals. Defaults to 0.
403
- is_long: A boolean indicating if the position is a buy or sell. Defaults to None. If None, the price impact for both buy and sell will be returned.
404
-
405
-
406
- Returns:
407
- A Spread instance containing the trade price impact for pair in bps.
408
- """
409
- position_size = int(position_size * 10**6)
410
- open_price = int(open_price * 10**10)
411
-
412
- Multicall = self.client.contracts.get("Multicall")
413
-
414
- calls = []
415
- response = None
416
-
417
- pair_index = await self.client.pairs_cache.get_pair_index(pair)
418
- PairInfos = self.client.contracts.get("PairInfos")
419
- if is_long is None:
420
- calls.extend(
421
- [
422
- (
423
- PairInfos.address,
424
- PairInfos.encodeABI(
425
- fn_name="getTradePriceImpact",
426
- args=[open_price, pair_index, True, position_size, False],
427
- ),
428
- ),
429
- (
430
- PairInfos.address,
431
- PairInfos.encodeABI(
432
- fn_name="getTradePriceImpact",
433
- args=[open_price, pair_index, False, position_size, False],
434
- ),
435
- ),
436
- ]
437
- )
438
- else:
439
- response = await PairInfos.functions.getTradePriceImpact(
440
- open_price, pair_index, is_long, position_size, False
441
- ).call()
442
-
443
- if response is None:
444
- response = await Multicall.functions.aggregate(calls).call()
445
- decoded_response = [
446
- int.from_bytes(value, byteorder="big") / 10**10 * 100
447
- for value in response[1]
448
- ]
449
- return Spread(
450
- long={pair: decoded_response[0]},
451
- short={pair: decoded_response[1]},
452
- )
453
- elif is_long:
454
- return Spread(long={pair: response / 10**10 * 100})
455
- else:
456
- return Spread(short={pair: response / 10**10 * 100})
457
-
458
- async def get_one_percent_depth(self):
459
- """
460
- Retrieves the one percent depth for all trading pairs.
461
-
462
- Returns:
463
- A Depth instance containing the one percent depth for each trading pair.
464
- """
465
-
466
- Multicall = self.client.contracts.get("Multicall")
467
- PairInfos = self.client.contracts.get("PairInfos")
468
- pairs_info = await self.client.pairs_cache.get_pairs_info()
469
- calls = []
470
- for pair_index in range(len(pairs_info)):
471
- calls.extend(
472
- [
473
- (
474
- PairInfos.address,
475
- PairInfos.encodeABI(
476
- fn_name="getOnePercentDepthAbove",
477
- args=[pair_index],
478
- ),
479
- ),
480
- (
481
- PairInfos.address,
482
- PairInfos.encodeABI(
483
- fn_name="getOnePercentDepthBelow",
484
- args=[pair_index],
485
- ),
486
- ),
487
- ]
488
- )
489
-
490
- response = await Multicall.functions.aggregate(calls).call()
491
-
492
- decoded_response = [
493
- int.from_bytes(value, byteorder="big") / 10**6 for value in response[1]
494
- ]
495
-
496
- return Depth(
497
- above=map_output_to_pairs(pairs_info, decoded_response[::2]),
498
- below=map_output_to_pairs(pairs_info, decoded_response[1::2]),
499
- )
1
+ import asyncio
2
+ from .rpc_helpers import map_output_to_pairs
3
+ from ..types import (
4
+ OpenInterest,
5
+ OpenInterestLimits,
6
+ Utilization,
7
+ Skew,
8
+ Spread,
9
+ Depth,
10
+ )
11
+ from typing import Optional
12
+
13
+
14
+ class AssetParametersRPC:
15
+ """
16
+ This class provides methods to retrieve and calculate various asset parameters
17
+ related to open interest, open interest limits, and asset utilization.
18
+ """
19
+
20
+ def __init__(self, client):
21
+ """
22
+ Constructor for the AssetParametersRPC class.
23
+
24
+ Args:
25
+ client: The TraderClient object.
26
+ """
27
+ self.client = client
28
+
29
+ async def get_oi_limits(self):
30
+ """
31
+ Retrieves the open interest limits for all trading pairs.
32
+
33
+ Returns:
34
+ An OpenInterestLimits instance containing the open interest limits
35
+ for each trading pair.
36
+ """
37
+ PairStorage = self.client.contracts.get("PairStorage")
38
+ Multicall = self.client.contracts.get("Multicall")
39
+ pairs_info = await self.client.pairs_cache.get_pairs_info()
40
+ calls = []
41
+ for pair_index in range(len(pairs_info)):
42
+ call_data = PairStorage.encodeABI(fn_name="pairMaxOI", args=[pair_index])
43
+ calls.append((PairStorage.address, call_data))
44
+
45
+ response = await Multicall.functions.aggregate(calls).call()
46
+ decoded_response = [
47
+ int.from_bytes(value, byteorder="big") / 10**6 for value in response[1]
48
+ ]
49
+
50
+ return OpenInterestLimits(
51
+ limits=map_output_to_pairs(pairs_info, decoded_response)
52
+ )
53
+
54
+ async def get_oi(self):
55
+ """
56
+ Retrieves the current open interest for all trading pairs.
57
+
58
+ Returns:
59
+ An OpenInterest instance containing the long and short open interest
60
+ ratios for each trading pair.
61
+ """
62
+ Multicall = self.client.contracts.get("Multicall")
63
+ pairs_info = await self.client.pairs_cache.get_pairs_info()
64
+ raw_data = await Multicall.functions.getLongShortRatios().call()
65
+ decoded = self.client.utils["decoder"](
66
+ Multicall, "getLongShortRatios", raw_data
67
+ )
68
+
69
+ return OpenInterest(
70
+ long=map_output_to_pairs(
71
+ pairs_info, [val / 10**6 for val in decoded["longRatio"]]
72
+ ),
73
+ short=map_output_to_pairs(
74
+ pairs_info, [val / 10**6 for val in decoded["shortRatio"]]
75
+ ),
76
+ )
77
+
78
+ async def get_utilization(self):
79
+ """
80
+ Calculates the asset utilization for all trading pairs.
81
+
82
+ Returns:
83
+ A Utilization instance containing the asset utilization
84
+ absolute value for each trading pair.
85
+ """
86
+ TradingStorage = self.client.contracts.get("TradingStorage")
87
+ Multicall = self.client.contracts.get("Multicall")
88
+ pairs_info = await self.client.pairs_cache.get_pairs_info()
89
+ calls = []
90
+ for pair_index in range(len(pairs_info)):
91
+ call_data = TradingStorage.encodeABI(fn_name="pairOI", args=[pair_index])
92
+ calls.append((TradingStorage.address, call_data))
93
+
94
+ oi_limits_task = self.get_oi_limits()
95
+ aggregate_task = Multicall.functions.aggregate(calls).call()
96
+
97
+ oi_limits, aggregate_response = await asyncio.gather(
98
+ oi_limits_task, aggregate_task
99
+ )
100
+
101
+ utilization = {}
102
+ for pair_index, (pair_data, oi_limit) in enumerate(
103
+ zip(aggregate_response[1], oi_limits.limits.values())
104
+ ):
105
+ pair_name = f"{pairs_info[pair_index].from_}/{pairs_info[pair_index].to}"
106
+ current_oi = int.from_bytes(pair_data, byteorder="big") / 10**6
107
+ limit = oi_limit
108
+ utilization[pair_name] = current_oi / limit if limit else 0
109
+
110
+ return Utilization(utilization=utilization)
111
+
112
+ async def get_asset_skew(self):
113
+ """
114
+ Calculates the asset skew for all trading pairs.
115
+
116
+ Returns:
117
+ An Skew instance containing the asset skew
118
+ absolute value for each trading pair.
119
+ """
120
+ oi = await self.get_oi()
121
+
122
+ skew = {}
123
+ for pair, long_ratio in oi.long.items():
124
+ short_ratio = oi.short[pair]
125
+ skew[pair] = (
126
+ long_ratio / (long_ratio + short_ratio)
127
+ if long_ratio + short_ratio
128
+ else 0
129
+ )
130
+
131
+ return Skew(skew=skew)
132
+
133
+ async def get_price_impact_spread(
134
+ self, position_size: int = 0, is_long: Optional[bool] = None, pair: str = None
135
+ ):
136
+ """
137
+ Retrieves the price impact spread for all trading pairs.
138
+
139
+ Args:
140
+ is_long: A boolean indicating if the position is a buy or sell. Defaults to None. If None, the price impact spread for both buy and sell will be returned.
141
+ position_size: The size of the position (collateral * leverage). Supports upto 6 decimals. Defaults to 0.
142
+ pair: The trading pair for which the price impact spread is to be calculated. Defaults to None. If None, the price impact spread for all trading pairs will be returned.
143
+
144
+ Returns:
145
+ A Spread instance containing the price impact spread for each trading pair in bps.
146
+ """
147
+ position_size = int(position_size * 10**6)
148
+
149
+ Multicall = self.client.contracts.get("Multicall")
150
+
151
+ calls = []
152
+ response = None
153
+
154
+ if pair is not None:
155
+ pair_index = await self.client.pairs_cache.get_pair_index(pair)
156
+ PairInfos = self.client.contracts.get("PairInfos")
157
+ if is_long is None:
158
+ calls.extend(
159
+ [
160
+ (
161
+ PairInfos.address,
162
+ PairInfos.encodeABI(
163
+ fn_name="getPriceImpactSpread",
164
+ args=[pair_index, True, position_size, False],
165
+ ),
166
+ ),
167
+ (
168
+ PairInfos.address,
169
+ PairInfos.encodeABI(
170
+ fn_name="getPriceImpactSpread",
171
+ args=[pair_index, False, position_size, False],
172
+ ),
173
+ ),
174
+ ]
175
+ )
176
+ else:
177
+ response = await PairInfos.functions.getPriceImpactSpread(
178
+ pair_index, is_long, position_size, False
179
+ ).call()
180
+ else:
181
+ pairs_info = await self.client.pairs_cache.get_pairs_info()
182
+ PairInfos = self.client.contracts.get("PairInfos")
183
+ for pair_index in range(len(pairs_info)):
184
+
185
+ if is_long is None:
186
+ calls.extend(
187
+ [
188
+ (
189
+ PairInfos.address,
190
+ PairInfos.encodeABI(
191
+ fn_name="getPriceImpactSpread",
192
+ args=[pair_index, True, position_size, False],
193
+ ),
194
+ ),
195
+ (
196
+ PairInfos.address,
197
+ PairInfos.encodeABI(
198
+ fn_name="getPriceImpactSpread",
199
+ args=[pair_index, False, position_size, False],
200
+ ),
201
+ ),
202
+ ]
203
+ )
204
+ else:
205
+ calls.append(
206
+ (
207
+ PairInfos.address,
208
+ PairInfos.encodeABI(
209
+ fn_name="getPriceImpactSpread",
210
+ args=[pair_index, is_long, position_size, False],
211
+ ),
212
+ )
213
+ )
214
+
215
+ if response is None:
216
+ response = await Multicall.functions.tryAggregate(False, calls).call()
217
+ if is_long is None:
218
+ decoded_response = [
219
+ (
220
+ (int.from_bytes(value, byteorder="big") / 10**10 * 100)
221
+ if success
222
+ else 0
223
+ )
224
+ for success, value in response
225
+ ]
226
+ if pair is None:
227
+ return Spread(
228
+ long=map_output_to_pairs(pairs_info, decoded_response[::2]),
229
+ short=map_output_to_pairs(pairs_info, decoded_response[1::2]),
230
+ )
231
+ else:
232
+ return Spread(
233
+ long={pair: decoded_response[0]},
234
+ short={pair: decoded_response[1]},
235
+ )
236
+ elif is_long:
237
+ decoded_response = map_output_to_pairs(
238
+ pairs_info,
239
+ [
240
+ (
241
+ (int.from_bytes(value, byteorder="big") / 10**10 * 100)
242
+ if success
243
+ else 0
244
+ )
245
+ for success, value in response
246
+ ],
247
+ )
248
+ return Spread(long=decoded_response)
249
+ else:
250
+ decoded_response = map_output_to_pairs(
251
+ pairs_info,
252
+ [
253
+ (
254
+ (int.from_bytes(value, byteorder="big") / 10**10 * 100)
255
+ if success
256
+ else 0
257
+ )
258
+ for success, value in response
259
+ ],
260
+ )
261
+ return Spread(short=decoded_response)
262
+ elif is_long:
263
+ return Spread(long={pair: response / 10**10 * 100})
264
+ else:
265
+ return Spread(short={pair: response / 10**10 * 100})
266
+
267
+ async def get_skew_impact_spread(
268
+ self, position_size: int = 0, is_long: Optional[bool] = None, pair: str = None
269
+ ):
270
+ """
271
+ Retrieves the skew impact spread for all trading pairs.
272
+
273
+ Args:
274
+ is_long: A boolean indicating if the position is a buy or sell. Defaults to None. If None, the skew impact spread for both buy and sell will be returned.
275
+ position_size: The size of the position (collateral * leverage). Supports upto 6 decimals. Defaults to 0.
276
+ pair: The trading pair for which the skew impact spread is to be calculated. Defaults to None. If None, the skew impact spread for all trading pairs will be returned.
277
+
278
+ Returns:
279
+ A Spread instance containing the skew impact spread for each trading pair in bps.
280
+ """
281
+ position_size = int(position_size * 10**6)
282
+
283
+ Multicall = self.client.contracts.get("Multicall")
284
+
285
+ calls = []
286
+ response = None
287
+
288
+ if pair is not None:
289
+ pair_index = await self.client.pairs_cache.get_pair_index(pair)
290
+ PairInfos = self.client.contracts.get("PairInfos")
291
+ if is_long is None:
292
+ calls.extend(
293
+ [
294
+ (
295
+ PairInfos.address,
296
+ PairInfos.encodeABI(
297
+ fn_name="getSkewImpactSpread",
298
+ args=[pair_index, True, position_size, False],
299
+ ),
300
+ ),
301
+ (
302
+ PairInfos.address,
303
+ PairInfos.encodeABI(
304
+ fn_name="getSkewImpactSpread",
305
+ args=[pair_index, False, position_size, False],
306
+ ),
307
+ ),
308
+ ]
309
+ )
310
+ else:
311
+ response = await PairInfos.functions.getSkewImpactSpread(
312
+ pair_index, is_long, position_size, False
313
+ ).call()
314
+ else:
315
+ pairs_info = await self.client.pairs_cache.get_pairs_info()
316
+ PairInfos = self.client.contracts.get("PairInfos")
317
+ for pair_index in range(len(pairs_info)):
318
+ if is_long is None:
319
+ calls.extend(
320
+ [
321
+ (
322
+ PairInfos.address,
323
+ PairInfos.encodeABI(
324
+ fn_name="getSkewImpactSpread",
325
+ args=[pair_index, True, position_size, False],
326
+ ),
327
+ ),
328
+ (
329
+ PairInfos.address,
330
+ PairInfos.encodeABI(
331
+ fn_name="getSkewImpactSpread",
332
+ args=[pair_index, False, position_size, False],
333
+ ),
334
+ ),
335
+ ]
336
+ )
337
+ else:
338
+ calls.append(
339
+ (
340
+ PairInfos.address,
341
+ PairInfos.encodeABI(
342
+ fn_name="getSkewImpactSpread",
343
+ args=[pair_index, is_long, position_size, False],
344
+ ),
345
+ )
346
+ )
347
+
348
+ if response is None:
349
+ response = await Multicall.functions.aggregate(calls).call()
350
+ if is_long is None:
351
+
352
+ decoded_response = [
353
+ int.from_bytes(value, byteorder="big", signed=True) / 10**10 * 100
354
+ for value in response[1]
355
+ ]
356
+ if pair is None:
357
+ return Spread(
358
+ long=map_output_to_pairs(pairs_info, decoded_response[::2]),
359
+ short=map_output_to_pairs(pairs_info, decoded_response[1::2]),
360
+ )
361
+ else:
362
+ return Spread(
363
+ long={pair: decoded_response[0]},
364
+ short={pair: decoded_response[1]},
365
+ )
366
+ elif is_long:
367
+ decoded_response = map_output_to_pairs(
368
+ pairs_info,
369
+ [
370
+ int.from_bytes(value, byteorder="big") / 10**10 * 100
371
+ for value in response[1]
372
+ ],
373
+ )
374
+ return Spread(long=decoded_response)
375
+ else:
376
+ decoded_response = map_output_to_pairs(
377
+ pairs_info,
378
+ [
379
+ int.from_bytes(value, byteorder="big") / 10**10 * 100
380
+ for value in response[1]
381
+ ],
382
+ )
383
+ return Spread(short=decoded_response)
384
+ elif is_long:
385
+ return Spread(long={pair: response / 10**10 * 100})
386
+ else:
387
+ return Spread(short={pair: response / 10**10 * 100})
388
+
389
+ async def get_opening_price_impact_spread(
390
+ self,
391
+ pair: str,
392
+ position_size: int = 0,
393
+ open_price: float = 0,
394
+ is_long: Optional[bool] = None,
395
+ ):
396
+ """
397
+ Retrieves the trade price impact spread for pair.
398
+
399
+ Args:
400
+ pair: The trading pair for which the price impact is to be calculated.
401
+ position_size: The size of the position (collateral * leverage). Supports upto 6 decimals. Defaults to 0.
402
+ open_price: The price at which the position was opened. Supports upto 10 decimals. Defaults to 0.
403
+ is_long: A boolean indicating if the position is a buy or sell. Defaults to None. If None, the price impact for both buy and sell will be returned.
404
+
405
+
406
+ Returns:
407
+ A Spread instance containing the trade price impact for pair in bps.
408
+ """
409
+ position_size = int(position_size * 10**6)
410
+ open_price = int(open_price * 10**10)
411
+
412
+ Multicall = self.client.contracts.get("Multicall")
413
+
414
+ calls = []
415
+ response = None
416
+
417
+ pair_index = await self.client.pairs_cache.get_pair_index(pair)
418
+ PairInfos = self.client.contracts.get("PairInfos")
419
+ if is_long is None:
420
+ calls.extend(
421
+ [
422
+ (
423
+ PairInfos.address,
424
+ PairInfos.encodeABI(
425
+ fn_name="getTradePriceImpact",
426
+ args=[open_price, pair_index, True, position_size, False],
427
+ ),
428
+ ),
429
+ (
430
+ PairInfos.address,
431
+ PairInfos.encodeABI(
432
+ fn_name="getTradePriceImpact",
433
+ args=[open_price, pair_index, False, position_size, False],
434
+ ),
435
+ ),
436
+ ]
437
+ )
438
+ else:
439
+ response = await PairInfos.functions.getTradePriceImpact(
440
+ open_price, pair_index, is_long, position_size, False
441
+ ).call()
442
+
443
+ if response is None:
444
+ response = await Multicall.functions.aggregate(calls).call()
445
+ decoded_response = [
446
+ int.from_bytes(value, byteorder="big") / 10**10 * 100
447
+ for value in response[1]
448
+ ]
449
+ return Spread(
450
+ long={pair: decoded_response[0]},
451
+ short={pair: decoded_response[1]},
452
+ )
453
+ elif is_long:
454
+ return Spread(long={pair: response / 10**10 * 100})
455
+ else:
456
+ return Spread(short={pair: response / 10**10 * 100})
457
+
458
+ async def get_one_percent_depth(self):
459
+ """
460
+ Retrieves the one percent depth for all trading pairs.
461
+
462
+ Returns:
463
+ A Depth instance containing the one percent depth for each trading pair.
464
+ """
465
+
466
+ Multicall = self.client.contracts.get("Multicall")
467
+ PairInfos = self.client.contracts.get("PairInfos")
468
+ pairs_info = await self.client.pairs_cache.get_pairs_info()
469
+ calls = []
470
+ for pair_index in range(len(pairs_info)):
471
+ calls.extend(
472
+ [
473
+ (
474
+ PairInfos.address,
475
+ PairInfos.encodeABI(
476
+ fn_name="getOnePercentDepthAbove",
477
+ args=[pair_index],
478
+ ),
479
+ ),
480
+ (
481
+ PairInfos.address,
482
+ PairInfos.encodeABI(
483
+ fn_name="getOnePercentDepthBelow",
484
+ args=[pair_index],
485
+ ),
486
+ ),
487
+ ]
488
+ )
489
+
490
+ response = await Multicall.functions.aggregate(calls).call()
491
+
492
+ decoded_response = [
493
+ int.from_bytes(value, byteorder="big") / 10**6 for value in response[1]
494
+ ]
495
+
496
+ return Depth(
497
+ above=map_output_to_pairs(pairs_info, decoded_response[::2]),
498
+ below=map_output_to_pairs(pairs_info, decoded_response[1::2]),
499
+ )