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.
- avantis_trader_sdk/__init__.py +5 -5
- avantis_trader_sdk/abis/AggregatorV3Interface.json +606 -606
- avantis_trader_sdk/abis/IPyth.sol/IPyth.dbg.json +4 -4
- avantis_trader_sdk/abis/Referral.sol/ReferralStorage.json +7132 -7132
- avantis_trader_sdk/abis/Sanctions.json +190 -190
- avantis_trader_sdk/abis/Trading.sol/Trading.json +1 -1
- avantis_trader_sdk/abis/USDC.sol/USDC.dbg.json +4 -4
- avantis_trader_sdk/abis/interfaces/ICallbacks.sol/ICallbacks.json +2637 -2637
- avantis_trader_sdk/abis/interfaces/IExecute.sol/IExecute.json +1628 -1628
- avantis_trader_sdk/abis/interfaces/IPairInfos.sol/IPairInfos.json +2781 -2781
- avantis_trader_sdk/abis/interfaces/IPairStorage.sol/IPairStorage.json +3729 -3729
- avantis_trader_sdk/abis/interfaces/IPriceAggregator.sol/IPriceAggregator.json +2330 -2330
- avantis_trader_sdk/abis/interfaces/IReferral.sol/IReferral.json +1890 -1890
- avantis_trader_sdk/abis/interfaces/ITradingStorage.sol/ITradingStorage.json +7022 -7022
- avantis_trader_sdk/abis/interfaces/ITranche.sol/ITranche.json +1283 -1283
- avantis_trader_sdk/abis/interfaces/IVaultManager.sol/IVaultManager.json +2424 -2424
- avantis_trader_sdk/abis/interfaces/IVeTranche.sol/IVeTranche.json +855 -855
- avantis_trader_sdk/abis/library/PositionMath.sol/PositionMath.dbg.json +4 -4
- avantis_trader_sdk/abis/library/PositionMath.sol/PositionMath.json +10 -10
- avantis_trader_sdk/abis/testnet/USDC.sol/USDC.dbg.json +4 -4
- avantis_trader_sdk/abis/testnet/USDC.sol/USDC.json +320 -320
- avantis_trader_sdk/client.py +369 -367
- avantis_trader_sdk/config.py +14 -14
- avantis_trader_sdk/feed/feed_client.py +263 -261
- avantis_trader_sdk/rpc/asset_parameters.py +499 -499
- avantis_trader_sdk/rpc/blended.py +71 -71
- avantis_trader_sdk/rpc/category_parameters.py +216 -216
- avantis_trader_sdk/rpc/fee_parameters.py +237 -237
- avantis_trader_sdk/rpc/pairs_cache.py +130 -130
- avantis_trader_sdk/rpc/rpc_helpers.py +8 -8
- avantis_trader_sdk/rpc/snapshot.py +142 -142
- avantis_trader_sdk/rpc/trade.py +701 -710
- avantis_trader_sdk/rpc/trading_parameters.py +139 -139
- avantis_trader_sdk/types.py +462 -462
- avantis_trader_sdk/utils.py +78 -78
- {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/METADATA +124 -113
- {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/RECORD +39 -40
- {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/WHEEL +1 -1
- avantis_trader_sdk/feed/feedIds.json +0 -214
- {avantis_trader_sdk-0.8.2.dist-info → avantis_trader_sdk-0.8.4.dist-info}/top_level.txt +0 -0
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
from ..types import PairInfoWithData
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class PairsCache:
|
|
5
|
-
"""
|
|
6
|
-
This class provides methods to retrieve pairs information from the blockchain.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
def __init__(self, client):
|
|
10
|
-
"""
|
|
11
|
-
Constructor for the PairsCache class.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
client: The TraderClient object.
|
|
15
|
-
"""
|
|
16
|
-
self.client = client
|
|
17
|
-
self._pair_info_cache = {}
|
|
18
|
-
self._group_indexes_cache = {}
|
|
19
|
-
self._pair_mapping = {}
|
|
20
|
-
|
|
21
|
-
async def get_pairs_info(self, force_update=False):
|
|
22
|
-
"""
|
|
23
|
-
Retrieves the pairs information from the blockchain. The information is cached and will be returned from the cache if it is available and force_update is False. This is to avoid unnecessary calls to the blockchain.
|
|
24
|
-
|
|
25
|
-
Args:
|
|
26
|
-
force_update: If True, the cache will be ignored and the information will be retrieved from the blockchain. Defaults to False.
|
|
27
|
-
|
|
28
|
-
Returns:
|
|
29
|
-
A dictionary containing the pairs information.
|
|
30
|
-
"""
|
|
31
|
-
if not force_update and not self._pair_info_cache:
|
|
32
|
-
Multicall = self.client.contracts.get("Multicall")
|
|
33
|
-
PairStorage = self.client.contracts.get("PairStorage")
|
|
34
|
-
pairs_count = await self.get_pairs_count()
|
|
35
|
-
|
|
36
|
-
calls = []
|
|
37
|
-
for pair_index in range(pairs_count):
|
|
38
|
-
core_call_data = PairStorage.encodeABI(
|
|
39
|
-
fn_name="pairs", args=[pair_index]
|
|
40
|
-
)
|
|
41
|
-
pair_data_call_data = PairStorage.encodeABI(
|
|
42
|
-
fn_name="getPairData", args=[pair_index]
|
|
43
|
-
)
|
|
44
|
-
calls.extend(
|
|
45
|
-
[
|
|
46
|
-
(PairStorage.address, core_call_data),
|
|
47
|
-
(PairStorage.address, pair_data_call_data),
|
|
48
|
-
]
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
_, raw_data = await Multicall.functions.aggregate(calls).call()
|
|
52
|
-
|
|
53
|
-
decoded_data = []
|
|
54
|
-
for i in range(0, len(raw_data), 2):
|
|
55
|
-
pair_info = self.client.utils["decoder"](
|
|
56
|
-
PairStorage, "pairs", raw_data[i]
|
|
57
|
-
)
|
|
58
|
-
pair_data = self.client.utils["decoder"](
|
|
59
|
-
PairStorage, "getPairData", raw_data[i + 1]
|
|
60
|
-
)
|
|
61
|
-
pair_info.update(pair_data)
|
|
62
|
-
decoded_data.append(PairInfoWithData(**pair_info))
|
|
63
|
-
|
|
64
|
-
for index, pair_info in enumerate(decoded_data):
|
|
65
|
-
if not pair_info.from_:
|
|
66
|
-
pair_info.from_ = f"DELISTED_{index}"
|
|
67
|
-
pair_info.to = f"DELISTED_{index}"
|
|
68
|
-
self._pair_info_cache[index] = pair_info
|
|
69
|
-
|
|
70
|
-
group_indexes = set([pair.group_index for pair in decoded_data])
|
|
71
|
-
self._group_indexes_cache = group_indexes
|
|
72
|
-
self._pair_mapping = {
|
|
73
|
-
f"{info.from_}/{info.to}": index
|
|
74
|
-
for index, info in self._pair_info_cache.items()
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return self._pair_info_cache
|
|
78
|
-
|
|
79
|
-
async def get_pairs_count(self):
|
|
80
|
-
"""
|
|
81
|
-
Retrieves the number of pairs from the blockchain.
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
The number of pairs as an integer.
|
|
85
|
-
"""
|
|
86
|
-
PairStorage = self.client.contracts.get("PairStorage")
|
|
87
|
-
return await PairStorage.functions.pairsCount().call()
|
|
88
|
-
|
|
89
|
-
async def get_group_indexes(self):
|
|
90
|
-
"""
|
|
91
|
-
Retrieves the group ids from the blockchain.
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
The group ids as a set.
|
|
95
|
-
"""
|
|
96
|
-
if not self._group_indexes_cache:
|
|
97
|
-
await self.get_pairs_info()
|
|
98
|
-
return self._group_indexes_cache
|
|
99
|
-
|
|
100
|
-
async def get_pair_index(self, pair):
|
|
101
|
-
"""
|
|
102
|
-
Retrieves the index of a pair from the blockchain.
|
|
103
|
-
|
|
104
|
-
Args:
|
|
105
|
-
pair: The pair to retrieve the index for. Expects a string in the format "from/to".
|
|
106
|
-
|
|
107
|
-
Returns:
|
|
108
|
-
The index of the pair as an integer.
|
|
109
|
-
|
|
110
|
-
Raises:
|
|
111
|
-
ValueError: If the pair is not found in the pairs information.
|
|
112
|
-
"""
|
|
113
|
-
pairs_info = await self.get_pairs_info()
|
|
114
|
-
for index, pair_info in pairs_info.items():
|
|
115
|
-
if pair_info.from_ + "/" + pair_info.to == pair:
|
|
116
|
-
return index
|
|
117
|
-
raise ValueError(f"Pair {pair} not found in pairs info.")
|
|
118
|
-
|
|
119
|
-
async def get_pair_name_from_index(self, pair_index):
|
|
120
|
-
"""
|
|
121
|
-
Retrieves the pair name from the index.
|
|
122
|
-
|
|
123
|
-
Args:
|
|
124
|
-
pair_index: The pair index.
|
|
125
|
-
|
|
126
|
-
Returns:
|
|
127
|
-
The pair name.
|
|
128
|
-
"""
|
|
129
|
-
pairs_info = await self.get_pairs_info()
|
|
130
|
-
return pairs_info[pair_index].from_ + "/" + pairs_info[pair_index].to
|
|
1
|
+
from ..types import PairInfoWithData
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class PairsCache:
|
|
5
|
+
"""
|
|
6
|
+
This class provides methods to retrieve pairs information from the blockchain.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
def __init__(self, client):
|
|
10
|
+
"""
|
|
11
|
+
Constructor for the PairsCache class.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
client: The TraderClient object.
|
|
15
|
+
"""
|
|
16
|
+
self.client = client
|
|
17
|
+
self._pair_info_cache = {}
|
|
18
|
+
self._group_indexes_cache = {}
|
|
19
|
+
self._pair_mapping = {}
|
|
20
|
+
|
|
21
|
+
async def get_pairs_info(self, force_update=False):
|
|
22
|
+
"""
|
|
23
|
+
Retrieves the pairs information from the blockchain. The information is cached and will be returned from the cache if it is available and force_update is False. This is to avoid unnecessary calls to the blockchain.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
force_update: If True, the cache will be ignored and the information will be retrieved from the blockchain. Defaults to False.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
A dictionary containing the pairs information.
|
|
30
|
+
"""
|
|
31
|
+
if not force_update and not self._pair_info_cache:
|
|
32
|
+
Multicall = self.client.contracts.get("Multicall")
|
|
33
|
+
PairStorage = self.client.contracts.get("PairStorage")
|
|
34
|
+
pairs_count = await self.get_pairs_count()
|
|
35
|
+
|
|
36
|
+
calls = []
|
|
37
|
+
for pair_index in range(pairs_count):
|
|
38
|
+
core_call_data = PairStorage.encodeABI(
|
|
39
|
+
fn_name="pairs", args=[pair_index]
|
|
40
|
+
)
|
|
41
|
+
pair_data_call_data = PairStorage.encodeABI(
|
|
42
|
+
fn_name="getPairData", args=[pair_index]
|
|
43
|
+
)
|
|
44
|
+
calls.extend(
|
|
45
|
+
[
|
|
46
|
+
(PairStorage.address, core_call_data),
|
|
47
|
+
(PairStorage.address, pair_data_call_data),
|
|
48
|
+
]
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
_, raw_data = await Multicall.functions.aggregate(calls).call()
|
|
52
|
+
|
|
53
|
+
decoded_data = []
|
|
54
|
+
for i in range(0, len(raw_data), 2):
|
|
55
|
+
pair_info = self.client.utils["decoder"](
|
|
56
|
+
PairStorage, "pairs", raw_data[i]
|
|
57
|
+
)
|
|
58
|
+
pair_data = self.client.utils["decoder"](
|
|
59
|
+
PairStorage, "getPairData", raw_data[i + 1]
|
|
60
|
+
)
|
|
61
|
+
pair_info.update(pair_data)
|
|
62
|
+
decoded_data.append(PairInfoWithData(**pair_info))
|
|
63
|
+
|
|
64
|
+
for index, pair_info in enumerate(decoded_data):
|
|
65
|
+
if not pair_info.from_:
|
|
66
|
+
pair_info.from_ = f"DELISTED_{index}"
|
|
67
|
+
pair_info.to = f"DELISTED_{index}"
|
|
68
|
+
self._pair_info_cache[index] = pair_info
|
|
69
|
+
|
|
70
|
+
group_indexes = set([pair.group_index for pair in decoded_data])
|
|
71
|
+
self._group_indexes_cache = group_indexes
|
|
72
|
+
self._pair_mapping = {
|
|
73
|
+
f"{info.from_}/{info.to}": index
|
|
74
|
+
for index, info in self._pair_info_cache.items()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return self._pair_info_cache
|
|
78
|
+
|
|
79
|
+
async def get_pairs_count(self):
|
|
80
|
+
"""
|
|
81
|
+
Retrieves the number of pairs from the blockchain.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
The number of pairs as an integer.
|
|
85
|
+
"""
|
|
86
|
+
PairStorage = self.client.contracts.get("PairStorage")
|
|
87
|
+
return await PairStorage.functions.pairsCount().call()
|
|
88
|
+
|
|
89
|
+
async def get_group_indexes(self):
|
|
90
|
+
"""
|
|
91
|
+
Retrieves the group ids from the blockchain.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
The group ids as a set.
|
|
95
|
+
"""
|
|
96
|
+
if not self._group_indexes_cache:
|
|
97
|
+
await self.get_pairs_info()
|
|
98
|
+
return self._group_indexes_cache
|
|
99
|
+
|
|
100
|
+
async def get_pair_index(self, pair):
|
|
101
|
+
"""
|
|
102
|
+
Retrieves the index of a pair from the blockchain.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
pair: The pair to retrieve the index for. Expects a string in the format "from/to".
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
The index of the pair as an integer.
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
ValueError: If the pair is not found in the pairs information.
|
|
112
|
+
"""
|
|
113
|
+
pairs_info = await self.get_pairs_info()
|
|
114
|
+
for index, pair_info in pairs_info.items():
|
|
115
|
+
if pair_info.from_ + "/" + pair_info.to == pair:
|
|
116
|
+
return index
|
|
117
|
+
raise ValueError(f"Pair {pair} not found in pairs info.")
|
|
118
|
+
|
|
119
|
+
async def get_pair_name_from_index(self, pair_index):
|
|
120
|
+
"""
|
|
121
|
+
Retrieves the pair name from the index.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
pair_index: The pair index.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
The pair name.
|
|
128
|
+
"""
|
|
129
|
+
pairs_info = await self.get_pairs_info()
|
|
130
|
+
return pairs_info[pair_index].from_ + "/" + pairs_info[pair_index].to
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
def map_output_to_pairs(pairs_info, decoded_response):
|
|
2
|
-
pairs_mapped_response = {}
|
|
3
|
-
for index, pair_info in pairs_info.items():
|
|
4
|
-
pairs_mapped_response[pair_info.from_ + "/" + pair_info.to] = decoded_response[
|
|
5
|
-
index
|
|
6
|
-
]
|
|
7
|
-
|
|
8
|
-
return pairs_mapped_response
|
|
1
|
+
def map_output_to_pairs(pairs_info, decoded_response):
|
|
2
|
+
pairs_mapped_response = {}
|
|
3
|
+
for index, pair_info in pairs_info.items():
|
|
4
|
+
pairs_mapped_response[pair_info.from_ + "/" + pair_info.to] = decoded_response[
|
|
5
|
+
index
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
return pairs_mapped_response
|
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from ..types import Snapshot, PairInfoExtended
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class SnapshotRPC:
|
|
6
|
-
"""
|
|
7
|
-
This class provides methods to retrieve and calculate various parameters as snapshot
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def __init__(self, client):
|
|
11
|
-
"""
|
|
12
|
-
Constructor for the SnapshotRPC class.
|
|
13
|
-
|
|
14
|
-
Args:
|
|
15
|
-
client: The TraderClient object.
|
|
16
|
-
"""
|
|
17
|
-
self.client = client
|
|
18
|
-
|
|
19
|
-
async def get_snapshot(self):
|
|
20
|
-
"""
|
|
21
|
-
Retrieves the blended utilization ratio for all trading pairs.
|
|
22
|
-
|
|
23
|
-
Returns:
|
|
24
|
-
A Snapshot instance containing several pair and group related parameters.
|
|
25
|
-
"""
|
|
26
|
-
pairs = await self.client.pairs_cache.get_pairs_info()
|
|
27
|
-
|
|
28
|
-
# Fetch all the required data in parallel
|
|
29
|
-
(
|
|
30
|
-
oi_limits,
|
|
31
|
-
oi,
|
|
32
|
-
utilization,
|
|
33
|
-
skew,
|
|
34
|
-
price_impact_spread,
|
|
35
|
-
skew_impact_spread,
|
|
36
|
-
margin_fee,
|
|
37
|
-
depth,
|
|
38
|
-
group_oi_limits,
|
|
39
|
-
group_oi,
|
|
40
|
-
group_utilization,
|
|
41
|
-
group_skew,
|
|
42
|
-
opening_fee,
|
|
43
|
-
) = await asyncio.gather(
|
|
44
|
-
self.client.asset_parameters.get_oi_limits(),
|
|
45
|
-
self.client.asset_parameters.get_oi(),
|
|
46
|
-
self.client.asset_parameters.get_utilization(),
|
|
47
|
-
self.client.asset_parameters.get_asset_skew(),
|
|
48
|
-
self.client.asset_parameters.get_price_impact_spread(1000),
|
|
49
|
-
self.client.asset_parameters.get_skew_impact_spread(1000),
|
|
50
|
-
self.client.fee_parameters.get_margin_fee(),
|
|
51
|
-
self.client.asset_parameters.get_one_percent_depth(),
|
|
52
|
-
self.client.category_parameters.get_oi_limits(),
|
|
53
|
-
self.client.category_parameters.get_oi(),
|
|
54
|
-
self.client.category_parameters.get_utilization(),
|
|
55
|
-
self.client.category_parameters.get_category_skew(),
|
|
56
|
-
self.client.fee_parameters.get_opening_fee(1000),
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
response = {}
|
|
60
|
-
|
|
61
|
-
for pairIndex in pairs:
|
|
62
|
-
pair = pairs[pairIndex]
|
|
63
|
-
key = pair.from_ + "/" + pair.to
|
|
64
|
-
pair = pair.__dict__
|
|
65
|
-
|
|
66
|
-
pair["asset_open_interest_limit"] = oi_limits.limits[key]
|
|
67
|
-
pair["asset_open_interest"] = {"long": oi.long[key], "short": oi.short[key]}
|
|
68
|
-
pair["asset_utilization"] = utilization.utilization[key]
|
|
69
|
-
pair["asset_skew"] = skew.skew[key]
|
|
70
|
-
|
|
71
|
-
pair["blended_utilization"] = (
|
|
72
|
-
utilization.utilization[key] * 0.25
|
|
73
|
-
+ group_utilization.utilization[str(pair["group_index"])] * 0.75
|
|
74
|
-
)
|
|
75
|
-
pair["blended_skew"] = (
|
|
76
|
-
skew.skew[key] * 0.25 + group_skew.skew[str(pair["group_index"])] * 0.75
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
pair["margin_fee"] = {
|
|
80
|
-
"hourly_base_fee_parameter": margin_fee.hourly_base_fee_parameter[key],
|
|
81
|
-
"hourly_margin_fee_long_bps": margin_fee.hourly_margin_fee_long_bps[
|
|
82
|
-
key
|
|
83
|
-
],
|
|
84
|
-
"hourly_margin_fee_short_bps": margin_fee.hourly_margin_fee_short_bps[
|
|
85
|
-
key
|
|
86
|
-
],
|
|
87
|
-
}
|
|
88
|
-
pair["one_percent_depth"] = {
|
|
89
|
-
"above": depth.above[key],
|
|
90
|
-
"below": depth.below[key],
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
pair["new_1k_long_opening_fee_bps"] = opening_fee.long[key]
|
|
94
|
-
pair["new_1k_short_opening_fee_bps"] = opening_fee.short[key]
|
|
95
|
-
|
|
96
|
-
pair["new_1k_long_opening_spread_bps"] = round(
|
|
97
|
-
pair["constant_spread_bps"]
|
|
98
|
-
+ price_impact_spread.long[key]
|
|
99
|
-
+ skew_impact_spread.long[key],
|
|
100
|
-
4,
|
|
101
|
-
)
|
|
102
|
-
pair["new_1k_short_opening_spread_bps"] = round(
|
|
103
|
-
pair["constant_spread_bps"]
|
|
104
|
-
+ price_impact_spread.short[key]
|
|
105
|
-
+ skew_impact_spread.short[key],
|
|
106
|
-
4,
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
pair["price_impact_spread_long_bps"] = round(
|
|
110
|
-
price_impact_spread.long[key], 4
|
|
111
|
-
)
|
|
112
|
-
pair["price_impact_spread_short_bps"] = round(
|
|
113
|
-
price_impact_spread.short[key], 4
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
pair["skew_impact_spread_long_bps"] = round(skew_impact_spread.long[key], 4)
|
|
117
|
-
pair["skew_impact_spread_short_bps"] = round(
|
|
118
|
-
skew_impact_spread.short[key], 4
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
pair["priceImpactMultiplier"] = pair.pop("price_impact_parameter") * 10**10
|
|
122
|
-
pair["skewImpactMultiplier"] = pair.pop("skew_impact_parameter") * 10**10
|
|
123
|
-
pair["spreadP"] = pair.pop("constant_spread_bps") * 10**10 / 100
|
|
124
|
-
pairs[pairIndex] = PairInfoExtended(**pair)
|
|
125
|
-
|
|
126
|
-
for group_index in group_oi_limits.limits:
|
|
127
|
-
response[group_index] = {
|
|
128
|
-
"group_open_interest_limit": group_oi_limits.limits[group_index],
|
|
129
|
-
"group_open_interest": {
|
|
130
|
-
"long": group_oi.long[group_index],
|
|
131
|
-
"short": group_oi.short[group_index],
|
|
132
|
-
},
|
|
133
|
-
"group_utilization": group_utilization.utilization[group_index],
|
|
134
|
-
"group_skew": group_skew.skew[group_index],
|
|
135
|
-
"pairs": {
|
|
136
|
-
pair.from_ + "/" + pair.to: pair
|
|
137
|
-
for _, pair in pairs.items()
|
|
138
|
-
if pair.group_index == int(group_index)
|
|
139
|
-
},
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return Snapshot(groups=response)
|
|
1
|
+
import asyncio
|
|
2
|
+
from ..types import Snapshot, PairInfoExtended
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SnapshotRPC:
|
|
6
|
+
"""
|
|
7
|
+
This class provides methods to retrieve and calculate various parameters as snapshot
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, client):
|
|
11
|
+
"""
|
|
12
|
+
Constructor for the SnapshotRPC class.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
client: The TraderClient object.
|
|
16
|
+
"""
|
|
17
|
+
self.client = client
|
|
18
|
+
|
|
19
|
+
async def get_snapshot(self):
|
|
20
|
+
"""
|
|
21
|
+
Retrieves the blended utilization ratio for all trading pairs.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
A Snapshot instance containing several pair and group related parameters.
|
|
25
|
+
"""
|
|
26
|
+
pairs = await self.client.pairs_cache.get_pairs_info()
|
|
27
|
+
|
|
28
|
+
# Fetch all the required data in parallel
|
|
29
|
+
(
|
|
30
|
+
oi_limits,
|
|
31
|
+
oi,
|
|
32
|
+
utilization,
|
|
33
|
+
skew,
|
|
34
|
+
price_impact_spread,
|
|
35
|
+
skew_impact_spread,
|
|
36
|
+
margin_fee,
|
|
37
|
+
depth,
|
|
38
|
+
group_oi_limits,
|
|
39
|
+
group_oi,
|
|
40
|
+
group_utilization,
|
|
41
|
+
group_skew,
|
|
42
|
+
opening_fee,
|
|
43
|
+
) = await asyncio.gather(
|
|
44
|
+
self.client.asset_parameters.get_oi_limits(),
|
|
45
|
+
self.client.asset_parameters.get_oi(),
|
|
46
|
+
self.client.asset_parameters.get_utilization(),
|
|
47
|
+
self.client.asset_parameters.get_asset_skew(),
|
|
48
|
+
self.client.asset_parameters.get_price_impact_spread(1000),
|
|
49
|
+
self.client.asset_parameters.get_skew_impact_spread(1000),
|
|
50
|
+
self.client.fee_parameters.get_margin_fee(),
|
|
51
|
+
self.client.asset_parameters.get_one_percent_depth(),
|
|
52
|
+
self.client.category_parameters.get_oi_limits(),
|
|
53
|
+
self.client.category_parameters.get_oi(),
|
|
54
|
+
self.client.category_parameters.get_utilization(),
|
|
55
|
+
self.client.category_parameters.get_category_skew(),
|
|
56
|
+
self.client.fee_parameters.get_opening_fee(1000),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
response = {}
|
|
60
|
+
|
|
61
|
+
for pairIndex in pairs:
|
|
62
|
+
pair = pairs[pairIndex]
|
|
63
|
+
key = pair.from_ + "/" + pair.to
|
|
64
|
+
pair = pair.__dict__
|
|
65
|
+
|
|
66
|
+
pair["asset_open_interest_limit"] = oi_limits.limits[key]
|
|
67
|
+
pair["asset_open_interest"] = {"long": oi.long[key], "short": oi.short[key]}
|
|
68
|
+
pair["asset_utilization"] = utilization.utilization[key]
|
|
69
|
+
pair["asset_skew"] = skew.skew[key]
|
|
70
|
+
|
|
71
|
+
pair["blended_utilization"] = (
|
|
72
|
+
utilization.utilization[key] * 0.25
|
|
73
|
+
+ group_utilization.utilization[str(pair["group_index"])] * 0.75
|
|
74
|
+
)
|
|
75
|
+
pair["blended_skew"] = (
|
|
76
|
+
skew.skew[key] * 0.25 + group_skew.skew[str(pair["group_index"])] * 0.75
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
pair["margin_fee"] = {
|
|
80
|
+
"hourly_base_fee_parameter": margin_fee.hourly_base_fee_parameter[key],
|
|
81
|
+
"hourly_margin_fee_long_bps": margin_fee.hourly_margin_fee_long_bps[
|
|
82
|
+
key
|
|
83
|
+
],
|
|
84
|
+
"hourly_margin_fee_short_bps": margin_fee.hourly_margin_fee_short_bps[
|
|
85
|
+
key
|
|
86
|
+
],
|
|
87
|
+
}
|
|
88
|
+
pair["one_percent_depth"] = {
|
|
89
|
+
"above": depth.above[key],
|
|
90
|
+
"below": depth.below[key],
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
pair["new_1k_long_opening_fee_bps"] = opening_fee.long[key]
|
|
94
|
+
pair["new_1k_short_opening_fee_bps"] = opening_fee.short[key]
|
|
95
|
+
|
|
96
|
+
pair["new_1k_long_opening_spread_bps"] = round(
|
|
97
|
+
pair["constant_spread_bps"]
|
|
98
|
+
+ price_impact_spread.long[key]
|
|
99
|
+
+ skew_impact_spread.long[key],
|
|
100
|
+
4,
|
|
101
|
+
)
|
|
102
|
+
pair["new_1k_short_opening_spread_bps"] = round(
|
|
103
|
+
pair["constant_spread_bps"]
|
|
104
|
+
+ price_impact_spread.short[key]
|
|
105
|
+
+ skew_impact_spread.short[key],
|
|
106
|
+
4,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
pair["price_impact_spread_long_bps"] = round(
|
|
110
|
+
price_impact_spread.long[key], 4
|
|
111
|
+
)
|
|
112
|
+
pair["price_impact_spread_short_bps"] = round(
|
|
113
|
+
price_impact_spread.short[key], 4
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
pair["skew_impact_spread_long_bps"] = round(skew_impact_spread.long[key], 4)
|
|
117
|
+
pair["skew_impact_spread_short_bps"] = round(
|
|
118
|
+
skew_impact_spread.short[key], 4
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
pair["priceImpactMultiplier"] = pair.pop("price_impact_parameter") * 10**10
|
|
122
|
+
pair["skewImpactMultiplier"] = pair.pop("skew_impact_parameter") * 10**10
|
|
123
|
+
pair["spreadP"] = pair.pop("constant_spread_bps") * 10**10 / 100
|
|
124
|
+
pairs[pairIndex] = PairInfoExtended(**pair)
|
|
125
|
+
|
|
126
|
+
for group_index in group_oi_limits.limits:
|
|
127
|
+
response[group_index] = {
|
|
128
|
+
"group_open_interest_limit": group_oi_limits.limits[group_index],
|
|
129
|
+
"group_open_interest": {
|
|
130
|
+
"long": group_oi.long[group_index],
|
|
131
|
+
"short": group_oi.short[group_index],
|
|
132
|
+
},
|
|
133
|
+
"group_utilization": group_utilization.utilization[group_index],
|
|
134
|
+
"group_skew": group_skew.skew[group_index],
|
|
135
|
+
"pairs": {
|
|
136
|
+
pair.from_ + "/" + pair.to: pair
|
|
137
|
+
for _, pair in pairs.items()
|
|
138
|
+
if pair.group_index == int(group_index)
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return Snapshot(groups=response)
|