trd-utils 0.0.41__py3-none-any.whl → 0.0.42__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.
Potentially problematic release.
This version of trd-utils might be problematic. Click here for more details.
- trd_utils/__init__.py +1 -1
- trd_utils/exchanges/blofin/blofin_client.py +8 -0
- trd_utils/exchanges/bx_ultra/bx_ultra_client.py +27 -6
- trd_utils/exchanges/exchange_base.py +8 -4
- trd_utils/exchanges/hyperliquid/hyperliquid_client.py +19 -5
- trd_utils/types_helper/__init__.py +5 -0
- trd_utils/types_helper/base_model.py +26 -56
- trd_utils/types_helper/decorators.py +20 -0
- trd_utils/types_helper/model_config.py +6 -0
- trd_utils/types_helper/ultra_list.py +40 -0
- trd_utils/types_helper/utils.py +28 -0
- {trd_utils-0.0.41.dist-info → trd_utils-0.0.42.dist-info}/METADATA +1 -1
- {trd_utils-0.0.41.dist-info → trd_utils-0.0.42.dist-info}/RECORD +15 -11
- {trd_utils-0.0.41.dist-info → trd_utils-0.0.42.dist-info}/LICENSE +0 -0
- {trd_utils-0.0.41.dist-info → trd_utils-0.0.42.dist-info}/WHEEL +0 -0
trd_utils/__init__.py
CHANGED
|
@@ -323,6 +323,8 @@ class BlofinClient(ExchangeBase):
|
|
|
323
323
|
async def get_unified_trader_positions(
|
|
324
324
|
self,
|
|
325
325
|
uid: int | str,
|
|
326
|
+
no_warn: bool = False,
|
|
327
|
+
min_margin: Decimal = 0,
|
|
326
328
|
) -> UnifiedTraderPositions:
|
|
327
329
|
result = await self.get_copy_trader_all_order_list(
|
|
328
330
|
uid=uid,
|
|
@@ -343,6 +345,12 @@ class BlofinClient(ExchangeBase):
|
|
|
343
345
|
unified_pos.open_price = position.avg_open_price
|
|
344
346
|
unified_pos.open_price_unit = position.symbol.split("-")[-1]
|
|
345
347
|
unified_pos.initial_margin = position.get_initial_margin()
|
|
348
|
+
if min_margin and (
|
|
349
|
+
not unified_pos.initial_margin
|
|
350
|
+
or unified_pos.initial_margin < min_margin
|
|
351
|
+
):
|
|
352
|
+
continue
|
|
353
|
+
|
|
346
354
|
unified_result.positions.append(unified_pos)
|
|
347
355
|
|
|
348
356
|
return unified_result
|
|
@@ -920,6 +920,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
920
920
|
uid: int | str,
|
|
921
921
|
api_identity: int | str | None = None,
|
|
922
922
|
no_warn: bool = False,
|
|
923
|
+
min_margin: Decimal = 0,
|
|
923
924
|
) -> UnifiedTraderPositions:
|
|
924
925
|
perp_positions = []
|
|
925
926
|
std_positions = []
|
|
@@ -930,26 +931,38 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
930
931
|
result = await self.get_unified_trader_positions_perp(
|
|
931
932
|
uid=uid,
|
|
932
933
|
api_identity=api_identity,
|
|
934
|
+
min_margin=min_margin,
|
|
933
935
|
)
|
|
934
936
|
perp_positions = result.positions
|
|
935
937
|
except Exception as ex:
|
|
938
|
+
err_str = f"{ex}"
|
|
939
|
+
if err_str.find("as the client has been closed") != -1:
|
|
940
|
+
raise ex
|
|
941
|
+
|
|
936
942
|
if not no_warn:
|
|
937
|
-
|
|
943
|
+
logger.warning(f"Failed to fetch perp positions of {uid}: {ex}")
|
|
944
|
+
perp_ex = ex
|
|
938
945
|
|
|
939
946
|
try:
|
|
940
947
|
result = await self.get_unified_trader_positions_std(
|
|
941
948
|
uid=uid,
|
|
949
|
+
min_margin=min_margin,
|
|
942
950
|
)
|
|
943
951
|
std_positions = result.positions
|
|
944
952
|
except Exception as ex:
|
|
953
|
+
err_str = f"{ex}"
|
|
954
|
+
if err_str.find("as the client has been closed") != -1:
|
|
955
|
+
raise ex
|
|
956
|
+
|
|
945
957
|
if not no_warn:
|
|
946
|
-
|
|
958
|
+
logger.warning(f"Failed to fetch std positions of {uid}: {ex}")
|
|
959
|
+
std_ex = ex
|
|
947
960
|
|
|
948
961
|
if not perp_positions and not std_positions:
|
|
949
|
-
if perp_ex:
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
962
|
+
if perp_ex or std_ex:
|
|
963
|
+
raise RuntimeError(
|
|
964
|
+
f"Failed to fetch both std and perp positions: perp: {perp_ex}; std: {std_ex}"
|
|
965
|
+
)
|
|
953
966
|
|
|
954
967
|
unified_result = UnifiedTraderPositions()
|
|
955
968
|
unified_result.positions = perp_positions + std_positions
|
|
@@ -960,6 +973,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
960
973
|
uid: int | str,
|
|
961
974
|
api_identity: int | str | None = None,
|
|
962
975
|
sub_account_filter: str = "futures",
|
|
976
|
+
min_margin: Decimal = 0,
|
|
963
977
|
) -> UnifiedTraderPositions:
|
|
964
978
|
if not api_identity:
|
|
965
979
|
api_identity = await self.get_trader_api_identity(
|
|
@@ -988,6 +1002,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
988
1002
|
unified_result = UnifiedTraderPositions()
|
|
989
1003
|
unified_result.positions = []
|
|
990
1004
|
for position in result.data.positions:
|
|
1005
|
+
if min_margin and (not position.margin or position.margin < min_margin):
|
|
1006
|
+
continue
|
|
1007
|
+
|
|
991
1008
|
unified_pos = UnifiedPositionInfo()
|
|
992
1009
|
unified_pos.position_id = position.position_no
|
|
993
1010
|
unified_pos.position_pnl = position.unrealized_pnl
|
|
@@ -1019,6 +1036,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
1019
1036
|
page_offset: int = 0,
|
|
1020
1037
|
page_size: int = 50,
|
|
1021
1038
|
delay_amount: float = 1,
|
|
1039
|
+
min_margin: Decimal = 0,
|
|
1022
1040
|
) -> UnifiedTraderPositions:
|
|
1023
1041
|
unified_result = UnifiedTraderPositions()
|
|
1024
1042
|
unified_result.positions = []
|
|
@@ -1041,6 +1059,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
1041
1059
|
)
|
|
1042
1060
|
|
|
1043
1061
|
for position in result.data.positions:
|
|
1062
|
+
if min_margin and (not position.margin or position.margin < min_margin):
|
|
1063
|
+
continue
|
|
1064
|
+
|
|
1044
1065
|
unified_pos = UnifiedPositionInfo()
|
|
1045
1066
|
unified_pos.position_id = position.order_no
|
|
1046
1067
|
unified_pos.position_pnl = (
|
|
@@ -16,14 +16,15 @@ from trd_utils.types_helper.base_model import BaseModel
|
|
|
16
16
|
|
|
17
17
|
logger = logging.getLogger(__name__)
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
class JWTManager:
|
|
20
21
|
_jwt_string: str = None
|
|
21
22
|
|
|
22
23
|
def __init__(self, jwt_string: str):
|
|
23
24
|
self._jwt_string = jwt_string
|
|
24
25
|
try:
|
|
25
|
-
payload_b64 = self._jwt_string.split(
|
|
26
|
-
payload_bytes = base64.urlsafe_b64decode(payload_b64 +
|
|
26
|
+
payload_b64 = self._jwt_string.split(".")[1]
|
|
27
|
+
payload_bytes = base64.urlsafe_b64decode(payload_b64 + "==")
|
|
27
28
|
self.payload = json.loads(payload_bytes)
|
|
28
29
|
except Exception:
|
|
29
30
|
self.payload = {}
|
|
@@ -31,9 +32,10 @@ class JWTManager():
|
|
|
31
32
|
def is_expired(self):
|
|
32
33
|
if "exp" not in self.payload:
|
|
33
34
|
return False
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
return time.time() > self.payload["exp"]
|
|
36
37
|
|
|
38
|
+
|
|
37
39
|
class ExchangeBase(ABC):
|
|
38
40
|
###########################################################
|
|
39
41
|
# region client parameters
|
|
@@ -82,6 +84,8 @@ class ExchangeBase(ABC):
|
|
|
82
84
|
async def get_unified_trader_positions(
|
|
83
85
|
self,
|
|
84
86
|
uid: int | str,
|
|
87
|
+
no_warn: bool = False,
|
|
88
|
+
min_margin: Decimal = 0,
|
|
85
89
|
) -> UnifiedTraderPositions:
|
|
86
90
|
"""
|
|
87
91
|
Returns the unified version of all currently open positions of the specific
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
from datetime import datetime
|
|
3
2
|
from decimal import Decimal
|
|
4
3
|
import json
|
|
@@ -11,9 +10,15 @@ import pytz
|
|
|
11
10
|
|
|
12
11
|
from trd_utils.cipher import AESCipher
|
|
13
12
|
from trd_utils.common_utils.wallet_utils import shorten_wallet_address
|
|
14
|
-
from trd_utils.exchanges.base_types import
|
|
13
|
+
from trd_utils.exchanges.base_types import (
|
|
14
|
+
UnifiedPositionInfo,
|
|
15
|
+
UnifiedTraderInfo,
|
|
16
|
+
UnifiedTraderPositions,
|
|
17
|
+
)
|
|
15
18
|
from trd_utils.exchanges.exchange_base import ExchangeBase
|
|
16
|
-
from trd_utils.exchanges.hyperliquid.hyperliquid_types import
|
|
19
|
+
from trd_utils.exchanges.hyperliquid.hyperliquid_types import (
|
|
20
|
+
TraderPositionsInfoResponse,
|
|
21
|
+
)
|
|
17
22
|
|
|
18
23
|
logger = logging.getLogger(__name__)
|
|
19
24
|
|
|
@@ -75,7 +80,7 @@ class HyperLiquidClient(ExchangeBase):
|
|
|
75
80
|
model_type=TraderPositionsInfoResponse,
|
|
76
81
|
)
|
|
77
82
|
|
|
78
|
-
#endregion
|
|
83
|
+
# endregion
|
|
79
84
|
###########################################################
|
|
80
85
|
# region another-thing
|
|
81
86
|
# async def get_another_thing_info(self, uid: int) -> AnotherThingInfoResponse:
|
|
@@ -151,6 +156,8 @@ class HyperLiquidClient(ExchangeBase):
|
|
|
151
156
|
async def get_unified_trader_positions(
|
|
152
157
|
self,
|
|
153
158
|
uid: int | str,
|
|
159
|
+
no_warn: bool = False,
|
|
160
|
+
min_margin: Decimal = 0,
|
|
154
161
|
) -> UnifiedTraderPositions:
|
|
155
162
|
result = await self.get_trader_positions_info(
|
|
156
163
|
uid=uid,
|
|
@@ -159,6 +166,11 @@ class HyperLiquidClient(ExchangeBase):
|
|
|
159
166
|
unified_result.positions = []
|
|
160
167
|
for position_container in result.asset_positions:
|
|
161
168
|
position = position_container.position
|
|
169
|
+
if min_margin and (
|
|
170
|
+
not position.margin_used or position.margin_used < min_margin
|
|
171
|
+
):
|
|
172
|
+
continue
|
|
173
|
+
|
|
162
174
|
unified_pos = UnifiedPositionInfo()
|
|
163
175
|
unified_pos.position_id = position.get_position_id()
|
|
164
176
|
unified_pos.position_pnl = round(position.unrealized_pnl, 3)
|
|
@@ -166,7 +178,9 @@ class HyperLiquidClient(ExchangeBase):
|
|
|
166
178
|
unified_pos.margin_mode = position.leverage.type
|
|
167
179
|
unified_pos.position_leverage = Decimal(position.leverage.value)
|
|
168
180
|
unified_pos.position_pair = f"{position.coin}/USDT"
|
|
169
|
-
unified_pos.open_time = datetime.now(
|
|
181
|
+
unified_pos.open_time = datetime.now(
|
|
182
|
+
pytz.UTC
|
|
183
|
+
) # hyperliquid doesn't provide this...
|
|
170
184
|
unified_pos.open_price = position.entry_px
|
|
171
185
|
unified_pos.open_price_unit = "USDT"
|
|
172
186
|
unified_pos.initial_margin = position.margin_used
|
|
@@ -3,7 +3,6 @@ from decimal import Decimal
|
|
|
3
3
|
import json
|
|
4
4
|
from typing import (
|
|
5
5
|
Union,
|
|
6
|
-
get_type_hints,
|
|
7
6
|
Any,
|
|
8
7
|
get_args as get_type_args,
|
|
9
8
|
)
|
|
@@ -12,6 +11,9 @@ import dateutil.parser
|
|
|
12
11
|
|
|
13
12
|
from trd_utils.date_utils.datetime_helpers import dt_from_ts, dt_to_ts
|
|
14
13
|
from trd_utils.html_utils.html_formats import camel_to_snake
|
|
14
|
+
from trd_utils.types_helper.model_config import ModelConfig
|
|
15
|
+
from trd_utils.types_helper.ultra_list import convert_to_ultra_list
|
|
16
|
+
from trd_utils.types_helper.utils import AbstractModel, get_my_field_types
|
|
15
17
|
|
|
16
18
|
# Whether to use ultra-list instead of normal python list or not.
|
|
17
19
|
# This might be convenient in some cases, but it is not recommended
|
|
@@ -24,27 +26,11 @@ ULTRA_LIST_ENABLED: bool = False
|
|
|
24
26
|
# attribute names are converted to snake_case.
|
|
25
27
|
SET_CAMEL_ATTR_NAMES = False
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
break
|
|
33
|
-
type_hints.update(get_type_hints(current_cls))
|
|
34
|
-
return type_hints
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def get_real_attr(cls, attr_name):
|
|
38
|
-
if cls is None:
|
|
39
|
-
return None
|
|
40
|
-
|
|
41
|
-
if isinstance(cls, dict):
|
|
42
|
-
return cls.get(attr_name, None)
|
|
43
|
-
|
|
44
|
-
if hasattr(cls, attr_name):
|
|
45
|
-
return getattr(cls, attr_name)
|
|
46
|
-
|
|
47
|
-
return None
|
|
29
|
+
# The _model_config is a special field which cannot get serialized
|
|
30
|
+
# nor can it get deserialized.
|
|
31
|
+
SPECIAL_FIELDS = [
|
|
32
|
+
"_model_config",
|
|
33
|
+
]
|
|
48
34
|
|
|
49
35
|
|
|
50
36
|
def is_base_model_type(expected_type: type) -> bool:
|
|
@@ -176,41 +162,13 @@ def generic_obj_to_value(
|
|
|
176
162
|
raise TypeError(f"unsupported type: {type(value)}")
|
|
177
163
|
|
|
178
164
|
|
|
179
|
-
class
|
|
180
|
-
|
|
181
|
-
if len(self) == 0:
|
|
182
|
-
return None
|
|
183
|
-
return UltraList([get_real_attr(item, attr) for item in self])
|
|
165
|
+
class BaseModel(AbstractModel):
|
|
166
|
+
_model_config: ModelConfig = None
|
|
184
167
|
|
|
185
|
-
|
|
186
|
-
def convert_to_ultra_list(value: Any) -> UltraList:
|
|
187
|
-
if not value:
|
|
188
|
-
return UltraList()
|
|
189
|
-
|
|
190
|
-
# Go through all fields of the value and convert them to
|
|
191
|
-
# UltraList if they are lists
|
|
192
|
-
|
|
193
|
-
try:
|
|
194
|
-
if isinstance(value, list):
|
|
195
|
-
return UltraList([convert_to_ultra_list(item) for item in value])
|
|
196
|
-
elif isinstance(value, dict):
|
|
197
|
-
return {k: convert_to_ultra_list(v) for k, v in value.items()}
|
|
198
|
-
elif isinstance(value, tuple):
|
|
199
|
-
return tuple(convert_to_ultra_list(v) for v in value)
|
|
200
|
-
elif isinstance(value, set):
|
|
201
|
-
return {convert_to_ultra_list(v) for v in value}
|
|
202
|
-
|
|
203
|
-
for attr, attr_value in get_my_field_types(value).items():
|
|
204
|
-
if isinstance(attr_value, list):
|
|
205
|
-
setattr(value, attr, convert_to_ultra_list(getattr(value, attr)))
|
|
206
|
-
|
|
207
|
-
return value
|
|
208
|
-
except Exception:
|
|
209
|
-
return value
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
class BaseModel:
|
|
213
168
|
def __init__(self, **kwargs):
|
|
169
|
+
if not self._model_config:
|
|
170
|
+
self._model_config = ModelConfig()
|
|
171
|
+
|
|
214
172
|
annotations = get_my_field_types(self)
|
|
215
173
|
for key, value in kwargs.items():
|
|
216
174
|
corrected_key = key
|
|
@@ -222,6 +180,12 @@ class BaseModel:
|
|
|
222
180
|
annotations[key] = Any
|
|
223
181
|
annotations[corrected_key] = Any
|
|
224
182
|
|
|
183
|
+
if corrected_key in SPECIAL_FIELDS or (
|
|
184
|
+
self._model_config.ignored_fields
|
|
185
|
+
and corrected_key in self._model_config.ignored_fields
|
|
186
|
+
):
|
|
187
|
+
continue
|
|
188
|
+
|
|
225
189
|
expected_type = annotations[corrected_key]
|
|
226
190
|
if hasattr(self, "_get_" + corrected_key + "_type"):
|
|
227
191
|
try:
|
|
@@ -344,13 +308,19 @@ class BaseModel:
|
|
|
344
308
|
annotations = get_my_field_types(self)
|
|
345
309
|
result_dict = {}
|
|
346
310
|
for key, _ in annotations.items():
|
|
347
|
-
if not isinstance(key, str):
|
|
311
|
+
if not isinstance(key, str) or key in SPECIAL_FIELDS:
|
|
348
312
|
continue
|
|
349
313
|
|
|
350
314
|
if key.startswith("__") or key.startswith(f"_{self.__class__.__name__}__"):
|
|
351
315
|
# ignore private attributes
|
|
352
316
|
continue
|
|
353
317
|
|
|
318
|
+
if (
|
|
319
|
+
self._model_config.ignored_fields
|
|
320
|
+
and key in self._model_config.ignored_fields
|
|
321
|
+
):
|
|
322
|
+
continue
|
|
323
|
+
|
|
354
324
|
normalized_value = value_to_normal_obj(
|
|
355
325
|
value=getattr(self, key),
|
|
356
326
|
omit_none=omit_none,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
from typing import Type, TypeVar
|
|
3
|
+
|
|
4
|
+
from trd_utils.types_helper.model_config import ModelConfig
|
|
5
|
+
from trd_utils.types_helper.utils import AbstractModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
T = TypeVar('T', bound=AbstractModel)
|
|
9
|
+
|
|
10
|
+
def ignore_json_fields(fields: list[str]):
|
|
11
|
+
def wrapper(cls: Type[T]) -> Type[T]:
|
|
12
|
+
config = getattr(cls, "_model_config", None)
|
|
13
|
+
if not config:
|
|
14
|
+
config = ModelConfig()
|
|
15
|
+
|
|
16
|
+
config.ignored_fields = fields.copy()
|
|
17
|
+
setattr(cls, "_model_config", config)
|
|
18
|
+
return cls
|
|
19
|
+
return wrapper
|
|
20
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from trd_utils.types_helper.utils import get_my_field_types, get_real_attr
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UltraList(list):
|
|
8
|
+
def __getattr__(self, attr):
|
|
9
|
+
if len(self) == 0:
|
|
10
|
+
return None
|
|
11
|
+
return UltraList([get_real_attr(item, attr) for item in self])
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def convert_to_ultra_list(value: Any) -> UltraList:
|
|
15
|
+
if not value:
|
|
16
|
+
return UltraList()
|
|
17
|
+
|
|
18
|
+
# Go through all fields of the value and convert them to
|
|
19
|
+
# UltraList if they are lists
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
if isinstance(value, list):
|
|
23
|
+
return UltraList([convert_to_ultra_list(item) for item in value])
|
|
24
|
+
elif isinstance(value, dict):
|
|
25
|
+
return {k: convert_to_ultra_list(v) for k, v in value.items()}
|
|
26
|
+
elif isinstance(value, tuple):
|
|
27
|
+
return tuple(convert_to_ultra_list(v) for v in value)
|
|
28
|
+
elif isinstance(value, set):
|
|
29
|
+
return {convert_to_ultra_list(v) for v in value}
|
|
30
|
+
|
|
31
|
+
for attr, attr_value in get_my_field_types(value).items():
|
|
32
|
+
if isinstance(attr_value, list):
|
|
33
|
+
setattr(value, attr, convert_to_ultra_list(getattr(value, attr)))
|
|
34
|
+
|
|
35
|
+
return value
|
|
36
|
+
except Exception:
|
|
37
|
+
return value
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
get_type_hints,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
class AbstractModel:
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
def get_real_attr(cls, attr_name):
|
|
9
|
+
if cls is None:
|
|
10
|
+
return None
|
|
11
|
+
|
|
12
|
+
if isinstance(cls, dict):
|
|
13
|
+
return cls.get(attr_name, None)
|
|
14
|
+
|
|
15
|
+
if hasattr(cls, attr_name):
|
|
16
|
+
return getattr(cls, attr_name)
|
|
17
|
+
|
|
18
|
+
return None
|
|
19
|
+
|
|
20
|
+
def get_my_field_types(cls):
|
|
21
|
+
type_hints = {}
|
|
22
|
+
for current_cls in cls.__class__.__mro__:
|
|
23
|
+
if current_cls is object or current_cls is AbstractModel:
|
|
24
|
+
break
|
|
25
|
+
type_hints.update(get_type_hints(current_cls))
|
|
26
|
+
return type_hints
|
|
27
|
+
|
|
28
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
trd_utils/__init__.py,sha256=
|
|
1
|
+
trd_utils/__init__.py,sha256=FTqI9urUdadYKumV6MlrQz3u1hDU-E2PPZzSEvKr-Wg,25
|
|
2
2
|
trd_utils/cipher/__init__.py,sha256=V05KNuzQwCic-ihMVHlC8sENaJGc3I8MCb4pg4849X8,1765
|
|
3
3
|
trd_utils/common_utils/float_utils.py,sha256=aYPwJ005LmrRhXAngojwvdDdtRgeb1FfR6hKeQ5ndMU,470
|
|
4
4
|
trd_utils/common_utils/wallet_utils.py,sha256=OX9q2fymP0VfIWTRIRBP8W33cfyjLXimxMgPOsZe-3g,727
|
|
@@ -8,17 +8,17 @@ trd_utils/exchanges/README.md,sha256=8egE4IPUQ3_UtiGP6GaCg50xq_dp43aGY_X1lKcO6ok
|
|
|
8
8
|
trd_utils/exchanges/__init__.py,sha256=sZRyp24q0KyMYASshAfsP-AfvsCADTYqqefxiRulPKE,484
|
|
9
9
|
trd_utils/exchanges/base_types.py,sha256=MVZvmxmYWgYh4URGVYaalNgY57l0VJX1GC8U18tB0rE,4964
|
|
10
10
|
trd_utils/exchanges/blofin/__init__.py,sha256=X4r9o4Nyjla4UeOBG8lrgtnGYO2aErFMKaJ7yQrFasE,76
|
|
11
|
-
trd_utils/exchanges/blofin/blofin_client.py,sha256=
|
|
11
|
+
trd_utils/exchanges/blofin/blofin_client.py,sha256=JVimaxGHRVviQHZbPY1gek8ICPl8-yS2AM-PRMa4_RA,13322
|
|
12
12
|
trd_utils/exchanges/blofin/blofin_types.py,sha256=bQx0opCgHwcuC-5TxiVA4VQr17A1x7u7QIMdcIrROAg,4315
|
|
13
13
|
trd_utils/exchanges/bx_ultra/__init__.py,sha256=8Ssy-eOemQR32Nv1-FoPHm87nRqRO4Fm2PU5GHEFKfQ,80
|
|
14
14
|
trd_utils/exchanges/bx_ultra/bx_types.py,sha256=7Ga6IYHQNRDbhWXmS1J0NxpcR9HUJ8ZwQGh-1EvNRqM,36687
|
|
15
|
-
trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=
|
|
15
|
+
trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=TVTdgebRLjbqo_FEz-id35ModqRRaoQvsed_52Z3ou8,40972
|
|
16
16
|
trd_utils/exchanges/bx_ultra/bx_utils.py,sha256=PwapomwDW33arVmKIDj6cL-aP0ptu4BYy_lOCqSAPOo,1392
|
|
17
17
|
trd_utils/exchanges/errors.py,sha256=P_NTuc389XL7rFegomP59BydWmHv8ckiGyNU-_l5qNQ,167
|
|
18
|
-
trd_utils/exchanges/exchange_base.py,sha256=
|
|
18
|
+
trd_utils/exchanges/exchange_base.py,sha256=eAORzCci78b2-IrslkQnMIbzVJGb6YYzNzniCUHG-jg,7891
|
|
19
19
|
trd_utils/exchanges/hyperliquid/README.md,sha256=-qaxmDt_9NTus2xRuzyFGkKgYDWgWk7ufHVTSkyn3t4,105
|
|
20
20
|
trd_utils/exchanges/hyperliquid/__init__.py,sha256=QhwGRcneGFHREM-MMdYpbcx-aWdsWsu2WznHzx7LaUM,92
|
|
21
|
-
trd_utils/exchanges/hyperliquid/hyperliquid_client.py,sha256=
|
|
21
|
+
trd_utils/exchanges/hyperliquid/hyperliquid_client.py,sha256=J1NjslRkyuAiqg9xvD8Mn7n0qxHtzDWibYU-mYgeG2s,7270
|
|
22
22
|
trd_utils/exchanges/hyperliquid/hyperliquid_types.py,sha256=MiGG5fRU7wHqOMtCzQXD1fwwbeUK1HEcQwW5rl-9D4c,2678
|
|
23
23
|
trd_utils/exchanges/okx/__init__.py,sha256=OjVpvcwB9mrCTofLt14JRHV2-fMAzGz9-YkJAMwl6dM,67
|
|
24
24
|
trd_utils/exchanges/okx/okx_client.py,sha256=3gvpF0xAGNNpYGfMeOy81yo8O2Eo-CM1BUqMibKkga8,7238
|
|
@@ -29,9 +29,13 @@ trd_utils/html_utils/html_formats.py,sha256=unKsvOiiDmYTTaM0DYZEUNLEUzWQKKrqASJX
|
|
|
29
29
|
trd_utils/tradingview/__init__.py,sha256=H0QYb-O5qvy7qC3yswtlcSWLmeBnaS6oJ3JtjvmaV_Y,154
|
|
30
30
|
trd_utils/tradingview/tradingview_client.py,sha256=g_eWYaCRQAL8Kvd-r6AnAdbH7Jha6C_GAyCuxh-RQUU,3917
|
|
31
31
|
trd_utils/tradingview/tradingview_types.py,sha256=z21MXPVdWHAduEl3gSeMIRhxtBN9yK-jPYHfZSMIbSA,6144
|
|
32
|
-
trd_utils/types_helper/__init__.py,sha256=
|
|
33
|
-
trd_utils/types_helper/base_model.py,sha256=
|
|
34
|
-
trd_utils
|
|
35
|
-
trd_utils
|
|
36
|
-
trd_utils
|
|
37
|
-
trd_utils
|
|
32
|
+
trd_utils/types_helper/__init__.py,sha256=cVm7Pbvuow4zS9vvH4cI9TQjRjPf_d1JE15zXb6dG40,188
|
|
33
|
+
trd_utils/types_helper/base_model.py,sha256=5y_QHYiNu57IxYtyFpPUNA3HI9Jywryl8cyxbM5jQcI,11066
|
|
34
|
+
trd_utils/types_helper/decorators.py,sha256=ziQGDKV0RnhMG6gBPAz244Ug3j6ayr0iKXeucAdnXB8,527
|
|
35
|
+
trd_utils/types_helper/model_config.py,sha256=uvyhdGHQZ1A_I5RUbCgzlDk6MxWL6RLV8r0cdVi6nBk,60
|
|
36
|
+
trd_utils/types_helper/ultra_list.py,sha256=01WQSkx0G7lD9O9XcXccexniNwyuQ9LwVOeixxr4tWQ,1178
|
|
37
|
+
trd_utils/types_helper/utils.py,sha256=Xq4SZG4NkkGzJyOBs9huAvzl2YcCZ7ZRjfOHol3o-Kc,569
|
|
38
|
+
trd_utils-0.0.42.dist-info/LICENSE,sha256=J1EP2xt87RjjmsTV1jTjHDQMLIM9FjdwEftTpw8hyv4,1067
|
|
39
|
+
trd_utils-0.0.42.dist-info/METADATA,sha256=MdFK7xoEWa1ft1BpEwzRkyGrJNiyb-6Aw4lvYkiRzoQ,1179
|
|
40
|
+
trd_utils-0.0.42.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
41
|
+
trd_utils-0.0.42.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|