avantis-trader-sdk 0.8.2__py3-none-any.whl → 0.8.3__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 (39) 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/USDC.sol/USDC.dbg.json +4 -4
  7. avantis_trader_sdk/abis/interfaces/ICallbacks.sol/ICallbacks.json +2637 -2637
  8. avantis_trader_sdk/abis/interfaces/IExecute.sol/IExecute.json +1628 -1628
  9. avantis_trader_sdk/abis/interfaces/IPairInfos.sol/IPairInfos.json +2781 -2781
  10. avantis_trader_sdk/abis/interfaces/IPairStorage.sol/IPairStorage.json +3729 -3729
  11. avantis_trader_sdk/abis/interfaces/IPriceAggregator.sol/IPriceAggregator.json +2330 -2330
  12. avantis_trader_sdk/abis/interfaces/IReferral.sol/IReferral.json +1890 -1890
  13. avantis_trader_sdk/abis/interfaces/ITradingStorage.sol/ITradingStorage.json +7022 -7022
  14. avantis_trader_sdk/abis/interfaces/ITranche.sol/ITranche.json +1283 -1283
  15. avantis_trader_sdk/abis/interfaces/IVaultManager.sol/IVaultManager.json +2424 -2424
  16. avantis_trader_sdk/abis/interfaces/IVeTranche.sol/IVeTranche.json +855 -855
  17. avantis_trader_sdk/abis/library/PositionMath.sol/PositionMath.dbg.json +4 -4
  18. avantis_trader_sdk/abis/library/PositionMath.sol/PositionMath.json +10 -10
  19. avantis_trader_sdk/abis/testnet/USDC.sol/USDC.dbg.json +4 -4
  20. avantis_trader_sdk/abis/testnet/USDC.sol/USDC.json +320 -320
  21. avantis_trader_sdk/client.py +369 -367
  22. avantis_trader_sdk/config.py +14 -14
  23. avantis_trader_sdk/feed/feed_client.py +263 -261
  24. avantis_trader_sdk/rpc/asset_parameters.py +499 -499
  25. avantis_trader_sdk/rpc/blended.py +71 -71
  26. avantis_trader_sdk/rpc/category_parameters.py +216 -216
  27. avantis_trader_sdk/rpc/fee_parameters.py +237 -237
  28. avantis_trader_sdk/rpc/pairs_cache.py +130 -130
  29. avantis_trader_sdk/rpc/rpc_helpers.py +8 -8
  30. avantis_trader_sdk/rpc/snapshot.py +142 -142
  31. avantis_trader_sdk/rpc/trade.py +701 -710
  32. avantis_trader_sdk/rpc/trading_parameters.py +139 -139
  33. avantis_trader_sdk/types.py +462 -462
  34. avantis_trader_sdk/utils.py +78 -78
  35. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.3.dist-info}/METADATA +124 -113
  36. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.3.dist-info}/RECORD +38 -39
  37. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.3.dist-info}/WHEEL +1 -1
  38. avantis_trader_sdk/feed/feedIds.json +0 -214
  39. {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.3.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
+ )