trd-utils 0.0.35__py3-none-any.whl → 0.0.37__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 CHANGED
@@ -1,3 +1,3 @@
1
1
 
2
- __version__ = "0.0.34"
2
+ __version__ = "0.0.37"
3
3
 
@@ -37,6 +37,11 @@ class UnifiedPositionInfo(BaseModel):
37
37
  # The base unit that the open-price is based on (e.g. USD, USDT, USDC)
38
38
  open_price_unit: str | None = None
39
39
 
40
+ # The initial amount of open_price_unit that the trader has put to open
41
+ # this position.
42
+ # Note that not all public APIs might provide this field.
43
+ initial_margin: Decimal | None = None
44
+
40
45
  # The last price of this pair on the target exchange.
41
46
  # not all exchanges support this yet, so use it with caution.
42
47
  last_price: Decimal | None = None
@@ -342,6 +342,7 @@ class BlofinClient(ExchangeBase):
342
342
  unified_pos.open_time = dt_from_ts(position.open_time)
343
343
  unified_pos.open_price = position.avg_open_price
344
344
  unified_pos.open_price_unit = position.symbol.split("-")[-1]
345
+ unified_pos.initial_margin = position.get_initial_margin()
345
346
  unified_result.positions.append(unified_pos)
346
347
 
347
348
  return unified_result
@@ -97,8 +97,8 @@ class CopyTraderSingleOrderInfo(BaseModel):
97
97
  symbol: str = None
98
98
  leverage: int = None
99
99
  order_side: str = None
100
- avg_open_price: str = None
101
- quantity: str = None
100
+ avg_open_price: Decimal = None
101
+ quantity: Decimal = None
102
102
  quantity_cont: Any = None
103
103
  open_time: int = None
104
104
  close_time: Any = None
@@ -146,6 +146,11 @@ class CopyTraderSingleOrderInfo(BaseModel):
146
146
  position_change_history: Any = None
147
147
  user_id: Any = None
148
148
 
149
+ def get_initial_margin(self) -> Decimal:
150
+ if not self.avg_open_price or not self.quantity or not self.leverage:
151
+ return None
152
+ return (self.avg_open_price * self.quantity) / self.leverage
153
+
149
154
 
150
155
  class CopyTraderOrderListResponse(BlofinApiResponse):
151
156
  data: list[CopyTraderSingleOrderInfo] = None
@@ -1217,6 +1217,75 @@ class ContractConfigResponse(BxApiResponse):
1217
1217
  data: ContractConfigData = None
1218
1218
 
1219
1219
 
1220
+ # endregion
1221
+
1222
+ ###########################################################
1223
+
1224
+ # region std futures types
1225
+
1226
+
1227
+ class CopyTraderStdFuturesPositionInfo(BaseModel):
1228
+ order_no: str = None
1229
+ quotation_coin_vo: QuotationCoinVOInfo = None
1230
+ margin: Decimal = None
1231
+ margin_coin_name: str = None
1232
+ lever_times: Decimal = None
1233
+ display_lever_times: Decimal = None
1234
+ amount: Decimal = None
1235
+ display_price: Decimal = None
1236
+ display_close_price: Decimal = None
1237
+ order_type: int = None
1238
+ close_type: int = None
1239
+ status: Any = None
1240
+ open_date: datetime = None
1241
+ fees: Decimal = None
1242
+ lever_fee: Decimal = None
1243
+ name: str = None
1244
+ order_create_type: int = None
1245
+ hide_price: bool = None
1246
+ fee_rate: Decimal = None
1247
+ hide: bool = None
1248
+ liquidation_desc: str = None
1249
+ contract_account_mode: Any = None
1250
+ current_price: Decimal = None
1251
+ sys_force_price: Decimal = None
1252
+ fund_type: int = None
1253
+ interest: Any = None
1254
+ order_open_trade: OrderOpenTradeInfo = None
1255
+ order_debit: OrderDebitInfo = None
1256
+ open_rate: Decimal = None
1257
+ close_rate: Decimal = None
1258
+ market_status: int = None
1259
+ create_time: datetime = None
1260
+ coupon_amount: Decimal = None
1261
+ stop_profit_rate: Decimal = None
1262
+ stop_loss_rate: Decimal = None
1263
+ stop_profit_modify_time: datetime = None
1264
+ stop_loss_modify_time: datetime = None
1265
+ show_adjust_margin: int = None
1266
+ trailing_stop: Decimal = None
1267
+ trailing_close_price: Decimal = None
1268
+ stop_rate: Decimal = None
1269
+ profit_loss_info: ProfitLossInfoContainer = None
1270
+ stop_offset_rate: None
1271
+
1272
+ def __str__(self):
1273
+ return super().__str__()
1274
+
1275
+ def __repr__(self):
1276
+ return self.__str__()
1277
+
1278
+
1279
+ class CopyTraderStdFuturesPositionsResult(BaseModel):
1280
+ page_id: int = None
1281
+ total_str: str = None
1282
+ positions: list[CopyTraderStdFuturesPositionInfo] = None
1283
+
1284
+
1285
+ class CopyTraderStdFuturesPositionsResponse(BxApiResponse):
1286
+ data: CopyTraderStdFuturesPositionsResult = None
1287
+
1288
+
1220
1289
  # endregion
1221
1290
 
1222
1291
  ###########################################################
@@ -16,10 +16,8 @@ import httpx
16
16
  import time
17
17
  from pathlib import Path
18
18
 
19
+ import pytz
19
20
  import websockets
20
- import websockets.asyncio
21
- import websockets.asyncio.client
22
- import websockets.asyncio.connection
23
21
 
24
22
  from trd_utils.exchanges.base_types import (
25
23
  UnifiedPositionInfo,
@@ -34,6 +32,7 @@ from trd_utils.exchanges.bx_ultra.bx_types import (
34
32
  ContractsListResponse,
35
33
  CopyTraderFuturesStatsResponse,
36
34
  CopyTraderResumeResponse,
35
+ CopyTraderStdFuturesPositionsResponse,
37
36
  CopyTraderTradePositionsResponse,
38
37
  CreateOrderDelegationResponse,
39
38
  HintListResponse,
@@ -67,7 +66,7 @@ WEB_APP_VERSION = "4.78.12"
67
66
  TG_APP_VERSION = "5.0.15"
68
67
 
69
68
  ACCEPT_ENCODING_HEADER = "gzip, deflate, br, zstd"
70
- BASE_PROFILE_URL = "https://bingx.com/en/CopyTrading/"
69
+ BASE_PROFILE_URL = "https://\u0062ing\u0078.co\u006d/en/CopyTr\u0061ding/"
71
70
 
72
71
  logger = logging.getLogger(__name__)
73
72
 
@@ -102,6 +101,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
102
101
  # a dict that maps "BTC/USDT" to it single candle info.
103
102
  __last_candle_storage: dict = None
104
103
  __last_candle_lock: asyncio.Lock = None
104
+
105
105
  # endregion
106
106
  ###########################################################
107
107
  # region client constructor
@@ -323,11 +323,15 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
323
323
  self.price_ws_connection = ws
324
324
  self._internal_lock.release()
325
325
 
326
- await ws.send(json.dumps({
327
- "dataType": "swap.market.v2.contracts",
328
- "id": uuid.uuid4().hex,
329
- "reqType": "sub",
330
- }))
326
+ await ws.send(
327
+ json.dumps(
328
+ {
329
+ "dataType": "swap.market.v2.contracts",
330
+ "id": uuid.uuid4().hex,
331
+ "reqType": "sub",
332
+ }
333
+ )
334
+ )
331
335
  async for msg in ws:
332
336
  try:
333
337
  decompressed_message = gzip.decompress(msg)
@@ -336,7 +340,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
336
340
  str_msg=str_msg,
337
341
  )
338
342
  except Exception as ex:
339
- logger.info(f"failed to handle ws message from exchange: {msg}; {ex}")
343
+ logger.info(
344
+ f"failed to handle ws message from exchange: {msg}; {ex}"
345
+ )
340
346
 
341
347
  async def _handle_price_ws_msg(self, str_msg: str):
342
348
  if str_msg.lower() == "ping":
@@ -356,14 +362,18 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
356
362
  target_id = data["ping"]
357
363
  target_time = data.get(
358
364
  "time",
359
- datetime.now(
360
- timezone(timedelta(hours=8))
361
- ).isoformat(timespec="seconds")
365
+ datetime.now(timezone(timedelta(hours=8))).isoformat(
366
+ timespec="seconds"
367
+ ),
368
+ )
369
+ await self.price_ws_connection.send(
370
+ json.dumps(
371
+ {
372
+ "pong": target_id,
373
+ "time": target_time,
374
+ }
375
+ )
362
376
  )
363
- await self.price_ws_connection.send(json.dumps({
364
- "pong": target_id,
365
- "time": target_time,
366
- }))
367
377
  return
368
378
 
369
379
  inner_data = data.get("data", None)
@@ -379,7 +389,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
379
389
  return
380
390
 
381
391
  logger.info(f"we got some unknown data: {data}")
382
-
392
+
383
393
  async def get_last_candle(self, pair: str) -> SingleCandleInfo:
384
394
  """
385
395
  Returns the last candle's info in this exchange.
@@ -390,16 +400,16 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
390
400
  info = self.__last_candle_storage.get(pair.lower())
391
401
  self.__last_candle_lock.release()
392
402
  return info
393
-
403
+
394
404
  # endregion
395
405
  ###########################################################
396
406
  # region contract
397
407
  async def get_contract_config(
398
408
  self,
399
- fund_type: int, # e.g. 1
400
- coin_name: str, # e.g. "SOL"
401
- valuation_name: str, # e.g. "USDT"
402
- margin_coin_name: str, # e.g. "USDT"
409
+ fund_type: int, # e.g. 1
410
+ coin_name: str, # e.g. "SOL"
411
+ valuation_name: str, # e.g. "USDT"
412
+ margin_coin_name: str, # e.g. "USDT"
403
413
  ) -> ContractConfigResponse:
404
414
  params = {
405
415
  "fundType": f"{fund_type}",
@@ -417,7 +427,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
417
427
  params=params,
418
428
  model_type=CopyTraderTradePositionsResponse,
419
429
  )
420
-
430
+
421
431
  async def get_contract_list(
422
432
  self,
423
433
  quotation_coin_id: int = -1,
@@ -605,7 +615,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
605
615
  "marginCoinName": margin_coin_name or "USDT",
606
616
  "marketFactor": market_factor or 1,
607
617
  "orderType": f"{order_type or 0}",
608
- "price": float(price), # e.g. 107161.27
618
+ "price": float(price), # e.g. 107161.27
609
619
  "profitLossRateDto": {
610
620
  "stopProfitRate": stop_profit_rate or -1,
611
621
  "stopLossRate": stop_loss_rate or -1,
@@ -626,6 +636,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
626
636
  content=payload,
627
637
  model_type=CreateOrderDelegationResponse,
628
638
  )
639
+
629
640
  # endregion
630
641
  ###########################################################
631
642
  # region copy-trade-facade
@@ -652,6 +663,27 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
652
663
  model_type=CopyTraderTradePositionsResponse,
653
664
  )
654
665
 
666
+ async def get_copy_trader_std_futures_positions(
667
+ self,
668
+ uid: int | str,
669
+ page_size: int = 20,
670
+ page_id: int = 0,
671
+ ) -> CopyTraderStdFuturesPositionsResponse:
672
+ params = {
673
+ "trader": f"{uid}",
674
+ # it seems like this method doesn't really need api identity param...
675
+ # "apiIdentity": f"{api_identity}",
676
+ "pageSize": f"{page_size}",
677
+ "pageId": f"{page_id}",
678
+ }
679
+ headers = self.get_headers(params)
680
+ return await self.invoke_get(
681
+ f"{self.we_api_base_url}/v1/copy-trade/traderContractHold",
682
+ headers=headers,
683
+ params=params,
684
+ model_type=CopyTraderStdFuturesPositionsResponse,
685
+ )
686
+
655
687
  async def search_copy_traders(
656
688
  self,
657
689
  exchange_id: int = 2,
@@ -740,7 +772,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
740
772
  api_identity = resume.data.api_identity
741
773
  if not api_identity:
742
774
  # second try: try to use one of the sub-accounts' identity
743
- api_identity = resume.data.get_account_identity_by_filter(sub_account_filter)
775
+ api_identity = resume.data.get_account_identity_by_filter(
776
+ filter_text=sub_account_filter,
777
+ )
744
778
 
745
779
  # maybe also try to fetch it in other ways later?
746
780
  # ...
@@ -881,6 +915,37 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
881
915
  # region unified methods
882
916
 
883
917
  async def get_unified_trader_positions(
918
+ self,
919
+ uid: int | str,
920
+ api_identity: int | str | None = None,
921
+ no_warn: bool = False,
922
+ ) -> UnifiedTraderPositions:
923
+ perp_positions = []
924
+ std_positions = []
925
+ try:
926
+ result = await self.get_unified_trader_positions_perp(
927
+ uid=uid,
928
+ api_identity=api_identity,
929
+ )
930
+ perp_positions = result.positions
931
+ except Exception as ex:
932
+ if not no_warn:
933
+ logger.warning(f"Failed to fetch perp positions of {uid}: {ex}")
934
+
935
+ try:
936
+ result = await self.get_unified_trader_positions_std(
937
+ uid=uid,
938
+ )
939
+ std_positions = result.positions
940
+ except Exception as ex:
941
+ if not no_warn:
942
+ logger.warning(f"Failed to fetch std positions of {uid}: {ex}")
943
+
944
+ unified_result = UnifiedTraderPositions()
945
+ unified_result.positions = perp_positions + std_positions
946
+ return unified_result
947
+
948
+ async def get_unified_trader_positions_perp(
884
949
  self,
885
950
  uid: int | str,
886
951
  api_identity: int | str | None = None,
@@ -891,7 +956,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
891
956
  uid=uid,
892
957
  sub_account_filter=sub_account_filter,
893
958
  )
894
-
959
+
895
960
  if not api_identity:
896
961
  raise ValueError(f"Failed to fetch api_identity for user {uid}")
897
962
 
@@ -920,8 +985,11 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
920
985
  unified_pos.margin_mode = "isolated" # TODO: fix this
921
986
  unified_pos.position_leverage = position.leverage
922
987
  unified_pos.position_pair = position.symbol.replace("-", "/")
923
- unified_pos.open_time = None # TODO: do something for this?
988
+ unified_pos.open_time = datetime.now(
989
+ pytz.UTC
990
+ ) # TODO: do something for this?
924
991
  unified_pos.open_price = position.avg_price
992
+ unified_pos.initial_margin = position.margin
925
993
  unified_pos.open_price_unit = (
926
994
  position.valuation_coin_name or position.symbol.split("-")[-1]
927
995
  ) # TODO
@@ -935,6 +1003,65 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
935
1003
 
936
1004
  return unified_result
937
1005
 
1006
+ async def get_unified_trader_positions_std(
1007
+ self,
1008
+ uid: int | str,
1009
+ page_offset: int = 0,
1010
+ page_size: int = 50,
1011
+ ) -> UnifiedTraderPositions:
1012
+ unified_result = UnifiedTraderPositions()
1013
+ unified_result.positions = []
1014
+ current_page_id = page_offset - 1
1015
+
1016
+ while True:
1017
+ current_page_id += 1
1018
+ try:
1019
+ result = await self.get_copy_trader_std_futures_positions(
1020
+ uid=uid,
1021
+ page_size=page_size,
1022
+ page_id=current_page_id,
1023
+ )
1024
+
1025
+ if result.code != 0 and not result.data:
1026
+ if result.msg:
1027
+ raise ExchangeError(f"got error from API: {result.msg}")
1028
+ raise ExchangeError(
1029
+ f"got unknown error from bx API while fetching std positions for {uid}"
1030
+ )
1031
+
1032
+ for position in result.data.positions:
1033
+ unified_pos = UnifiedPositionInfo()
1034
+ unified_pos.position_id = position.order_no
1035
+ unified_pos.position_pnl = (
1036
+ position.current_price - position.display_price
1037
+ ) * position.amount
1038
+ unified_pos.position_side = (
1039
+ "LONG" if position.amount > 0 else "SHORT"
1040
+ )
1041
+ unified_pos.margin_mode = "isolated" # TODO: fix this
1042
+ unified_pos.position_leverage = position.lever_times
1043
+ unified_pos.position_pair = f"{position.quotation_coin_vo.coin.name}/{position.margin_coin_name}"
1044
+ unified_pos.open_time = position.create_time
1045
+ unified_pos.open_price = position.display_price
1046
+ unified_pos.initial_margin = position.margin
1047
+ unified_pos.open_price_unit = position.margin_coin_name
1048
+
1049
+ last_candle = await self.get_last_candle(unified_pos.position_pair)
1050
+ if last_candle:
1051
+ unified_pos.last_price = last_candle.close_price
1052
+ unified_pos.last_volume = last_candle.quote_volume
1053
+
1054
+ unified_result.positions.append(unified_pos)
1055
+
1056
+ if int(result.data.total_str) <= len(unified_result.positions):
1057
+ # all is done
1058
+ return unified_result
1059
+ except Exception as ex:
1060
+ logger.warning(
1061
+ f"Failed to fetch std positions from exchange for {uid}: {ex}"
1062
+ )
1063
+ return unified_result
1064
+
938
1065
  async def get_unified_trader_info(
939
1066
  self,
940
1067
  uid: int | str,
@@ -944,8 +1071,8 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
944
1071
  )
945
1072
  if resume_resp.code != 0 and not resume_resp.data:
946
1073
  if resume_resp.msg:
947
- raise ValueError(f"got error from API: {resume_resp.msg}")
948
- raise ValueError(
1074
+ raise ExchangeError(f"got error from API: {resume_resp.msg}")
1075
+ raise ExchangeError(
949
1076
  f"got unknown error from bx API while fetching resume for {uid}"
950
1077
  )
951
1078
 
@@ -1,4 +1,5 @@
1
1
 
2
+ from datetime import datetime
2
3
  from decimal import Decimal
3
4
  import json
4
5
  import logging
@@ -6,6 +7,8 @@ import httpx
6
7
 
7
8
  from pathlib import Path
8
9
 
10
+ import pytz
11
+
9
12
  from trd_utils.cipher import AESCipher
10
13
  from trd_utils.common_utils.wallet_utils import shorten_wallet_address
11
14
  from trd_utils.exchanges.base_types import UnifiedPositionInfo, UnifiedTraderInfo, UnifiedTraderPositions
@@ -163,9 +166,10 @@ class HyperLiquidClient(ExchangeBase):
163
166
  unified_pos.margin_mode = position.leverage.type
164
167
  unified_pos.position_leverage = Decimal(position.leverage.value)
165
168
  unified_pos.position_pair = f"{position.coin}/USDT"
166
- unified_pos.open_time = None # hyperliquid doesn't provide this...
169
+ unified_pos.open_time = datetime.now(pytz.UTC) # hyperliquid doesn't provide this...
167
170
  unified_pos.open_price = position.entry_px
168
171
  unified_pos.open_price_unit = "USDT"
172
+ unified_pos.initial_margin = position.margin_used
169
173
  unified_result.positions.append(unified_pos)
170
174
 
171
175
  return unified_result
@@ -186,6 +186,7 @@ class OkxClient(ExchangeBase):
186
186
  unified_pos.open_time = position.c_time
187
187
  unified_pos.open_price = position.avg_px
188
188
  unified_pos.open_price_unit = position.quote_ccy
189
+ unified_pos.initial_margin = position.margin
189
190
  unified_result.positions.append(unified_pos)
190
191
 
191
192
  return unified_result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: trd_utils
3
- Version: 0.0.35
3
+ Version: 0.0.37
4
4
  Summary: Common Basic Utils for Python3. By ALiwoto.
5
5
  Keywords: utils,trd_utils,basic-utils,common-utils
6
6
  Author: ALiwoto
@@ -1,4 +1,4 @@
1
- trd_utils/__init__.py,sha256=GsuIE8NCRzLRhMGiCIknc3O6tjSWfykx6tLGfuEkYz4,25
1
+ trd_utils/__init__.py,sha256=uIAzhEc7N_HuxzS736TwDZ5XUDfBlKQGF3Xb-w1w9SY,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
@@ -6,22 +6,22 @@ trd_utils/date_utils/__init__.py,sha256=Erg_E1TfKWNpiuZFm_NXRjCwoRMfxpPS2-mJK6V4
6
6
  trd_utils/date_utils/datetime_helpers.py,sha256=euIJBr-6PfJzLScOC9xVXd8Re_Gw5CSBPwtHX9_Il4A,596
7
7
  trd_utils/exchanges/README.md,sha256=8egE4IPUQ3_UtiGP6GaCg50xq_dp43aGY_X1lKcO6ok,6812
8
8
  trd_utils/exchanges/__init__.py,sha256=sZRyp24q0KyMYASshAfsP-AfvsCADTYqqefxiRulPKE,484
9
- trd_utils/exchanges/base_types.py,sha256=NGykHGyY97mcc4gqxa0RLNElro0y3cQsdSCM1XAtIz8,3625
9
+ trd_utils/exchanges/base_types.py,sha256=Dh7obMq9EMhLNuH6c0WbX8sFJpqRfhBXkRCKiiAG49c,3827
10
10
  trd_utils/exchanges/blofin/__init__.py,sha256=X4r9o4Nyjla4UeOBG8lrgtnGYO2aErFMKaJ7yQrFasE,76
11
- trd_utils/exchanges/blofin/blofin_client.py,sha256=j3E9fdz06x3T4fA0SmS0PxopE4qNc1kSuj2UxGazodQ,13008
12
- trd_utils/exchanges/blofin/blofin_types.py,sha256=ZlHX1ClYTd2pDRTQIlZYyBu5ReGpMgxXxKASsPeBQug,4090
11
+ trd_utils/exchanges/blofin/blofin_client.py,sha256=LAAbwXbA7nDxJZFwbXtaNsIZCayEyX3SwfwYdRr3uQs,13079
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
- trd_utils/exchanges/bx_ultra/bx_types.py,sha256=hRe8DfF3sdXlMdk-knwWx4XpZUp1rITpXPnUDtiy93o,34715
15
- trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=MKL2nKMjWy_aIFQKtY62gwODISEfAsGnD58SElUx6Q8,34977
14
+ trd_utils/exchanges/bx_ultra/bx_types.py,sha256=7Ga6IYHQNRDbhWXmS1J0NxpcR9HUJ8ZwQGh-1EvNRqM,36687
15
+ trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=rKH04edvFxTpqo4XQMlCiWnNF1MQcoOLUonO_eG8uRs,39777
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
18
  trd_utils/exchanges/exchange_base.py,sha256=Zn5y4bymK53ENVLjYnQadS61SZKs8BGoZ4jfsY4GOcE,7835
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=-aBtgTjXJyI9n4kmDQIlm4Ip00SAwgURJ-ztZxuCRTM,6875
21
+ trd_utils/exchanges/hyperliquid/hyperliquid_client.py,sha256=JC9hp-INt7oSFshsa402dsFmzEOHjnrg6NlGTxIesp8,6998
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
- trd_utils/exchanges/okx/okx_client.py,sha256=zrWGs8H8oU_ZrP-nY5g5p3iaIZUJs_oozFa0HExS6EU,7181
24
+ trd_utils/exchanges/okx/okx_client.py,sha256=3gvpF0xAGNNpYGfMeOy81yo8O2Eo-CM1BUqMibKkga8,7238
25
25
  trd_utils/exchanges/okx/okx_types.py,sha256=IkFOfgivcvvIw950jyGHAVfFFGbGqfZcYGfZLWfNLvc,5013
26
26
  trd_utils/exchanges/price_fetcher.py,sha256=YHLkM6sCvHGFS_4t188Sl3DczqrarK-1ivGwZEVsom4,1320
27
27
  trd_utils/html_utils/__init__.py,sha256=1WWs8C7JszRjTkmzIRLHpxWECHur_DrulTPGIeX88oM,426
@@ -31,7 +31,7 @@ trd_utils/tradingview/tradingview_client.py,sha256=g_eWYaCRQAL8Kvd-r6AnAdbH7Jha6
31
31
  trd_utils/tradingview/tradingview_types.py,sha256=z21MXPVdWHAduEl3gSeMIRhxtBN9yK-jPYHfZSMIbSA,6144
32
32
  trd_utils/types_helper/__init__.py,sha256=lLbUiW1jUV1gjzTMFLthwkvF0hwauH-F_J2JZq--1U0,67
33
33
  trd_utils/types_helper/base_model.py,sha256=dknzoq6iAUOb0n_yhI5mU3So-F_8d5ykGk3EbrERLnM,11763
34
- trd_utils-0.0.35.dist-info/LICENSE,sha256=J1EP2xt87RjjmsTV1jTjHDQMLIM9FjdwEftTpw8hyv4,1067
35
- trd_utils-0.0.35.dist-info/METADATA,sha256=h6uD6uuSfYbor9unNO36-sxv4uxdpdhCKBIqJfNeygM,1179
36
- trd_utils-0.0.35.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
37
- trd_utils-0.0.35.dist-info/RECORD,,
34
+ trd_utils-0.0.37.dist-info/LICENSE,sha256=J1EP2xt87RjjmsTV1jTjHDQMLIM9FjdwEftTpw8hyv4,1067
35
+ trd_utils-0.0.37.dist-info/METADATA,sha256=60mZlvZDyd13XW1oSvHVj0U-5Ymqh1HGe05dtR8RRnk,1179
36
+ trd_utils-0.0.37.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
37
+ trd_utils-0.0.37.dist-info/RECORD,,