trd-utils 0.0.34__tar.gz → 0.0.36__tar.gz

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.

Files changed (38) hide show
  1. {trd_utils-0.0.34 → trd_utils-0.0.36}/PKG-INFO +1 -1
  2. {trd_utils-0.0.34 → trd_utils-0.0.36}/pyproject.toml +1 -1
  3. trd_utils-0.0.36/trd_utils/__init__.py +3 -0
  4. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/README.md +4 -2
  5. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/base_types.py +5 -0
  6. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/blofin/blofin_client.py +7 -3
  7. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/blofin/blofin_types.py +7 -2
  8. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/bx_ultra/bx_ultra_client.py +10 -1
  9. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/exchange_base.py +3 -0
  10. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/hyperliquid/hyperliquid_client.py +6 -1
  11. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/okx/okx_client.py +2 -0
  12. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/price_fetcher.py +11 -1
  13. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/types_helper/base_model.py +0 -1
  14. trd_utils-0.0.34/trd_utils/__init__.py +0 -3
  15. {trd_utils-0.0.34 → trd_utils-0.0.36}/LICENSE +0 -0
  16. {trd_utils-0.0.34 → trd_utils-0.0.36}/README.md +0 -0
  17. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/cipher/__init__.py +0 -0
  18. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/common_utils/float_utils.py +0 -0
  19. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/common_utils/wallet_utils.py +0 -0
  20. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/date_utils/__init__.py +0 -0
  21. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/date_utils/datetime_helpers.py +0 -0
  22. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/__init__.py +0 -0
  23. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/blofin/__init__.py +0 -0
  24. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/bx_ultra/__init__.py +0 -0
  25. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/bx_ultra/bx_types.py +0 -0
  26. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/bx_ultra/bx_utils.py +0 -0
  27. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/errors.py +0 -0
  28. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/hyperliquid/README.md +0 -0
  29. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/hyperliquid/__init__.py +0 -0
  30. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/hyperliquid/hyperliquid_types.py +0 -0
  31. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/okx/__init__.py +0 -0
  32. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/exchanges/okx/okx_types.py +0 -0
  33. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/html_utils/__init__.py +0 -0
  34. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/html_utils/html_formats.py +0 -0
  35. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/tradingview/__init__.py +0 -0
  36. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/tradingview/tradingview_client.py +0 -0
  37. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/tradingview/tradingview_types.py +0 -0
  38. {trd_utils-0.0.34 → trd_utils-0.0.36}/trd_utils/types_helper/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: trd_utils
3
- Version: 0.0.34
3
+ Version: 0.0.36
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,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "trd_utils"
3
- version = "0.0.34"
3
+ version = "0.0.36"
4
4
  description = "Common Basic Utils for Python3. By ALiwoto."
5
5
  authors = ["ALiwoto <aminnimaj@gmail.com>"]
6
6
  packages = [
@@ -0,0 +1,3 @@
1
+
2
+ __version__ = "0.0.36"
3
+
@@ -48,11 +48,13 @@ class MyExchangeClient(ExchangeBase):
48
48
  fav_letter: str = "^",
49
49
  read_session_file: bool = True,
50
50
  sessions_dir: str = "sessions",
51
+ use_http1: bool = False,
52
+ use_http2: bool = True,
51
53
  ):
52
54
  self.httpx_client = httpx.AsyncClient(
53
55
  verify=http_verify,
54
- http2=True,
55
- http1=False,
56
+ http1=use_http1,
57
+ http2=use_http2,
56
58
  )
57
59
  self.account_name = account_name
58
60
  self._fav_letter = fav_letter
@@ -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
@@ -51,16 +51,19 @@ class BlofinClient(ExchangeBase):
51
51
  fav_letter: str = "^",
52
52
  read_session_file: bool = True,
53
53
  sessions_dir: str = "sessions",
54
+ use_http1: bool = False,
55
+ use_http2: bool = True,
54
56
  ):
55
57
  self.httpx_client = httpx.AsyncClient(
56
58
  verify=http_verify,
57
- http2=True,
58
- http1=False,
59
+ http1=use_http1,
60
+ http2=use_http2,
59
61
  )
60
62
  self.account_name = account_name
61
63
  self._fav_letter = fav_letter
62
64
  self.sessions_dir = sessions_dir
63
-
65
+ self.exchange_name = "blofin"
66
+
64
67
  super().__init__()
65
68
 
66
69
  if read_session_file:
@@ -339,6 +342,7 @@ class BlofinClient(ExchangeBase):
339
342
  unified_pos.open_time = dt_from_ts(position.open_time)
340
343
  unified_pos.open_price = position.avg_open_price
341
344
  unified_pos.open_price_unit = position.symbol.split("-")[-1]
345
+ unified_pos.initial_margin = position.get_initial_margin()
342
346
  unified_result.positions.append(unified_pos)
343
347
 
344
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
@@ -114,9 +114,13 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
114
114
  http_verify: bool = True,
115
115
  fav_letter: str = "^",
116
116
  sessions_dir: str = "sessions",
117
+ use_http1: bool = False,
118
+ use_http2: bool = True,
117
119
  ):
118
120
  self.httpx_client = httpx.AsyncClient(
119
- verify=http_verify, http2=True, http1=False
121
+ verify=http_verify,
122
+ http1=use_http1,
123
+ http2=use_http2,
120
124
  )
121
125
  self.account_name = account_name
122
126
  self.platform_id = platform_id
@@ -124,6 +128,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
124
128
  self.app_version = app_version
125
129
  self._fav_letter = fav_letter
126
130
  self.sessions_dir = sessions_dir
131
+ self.exchange_name = "\u0062ing\u0078"
127
132
 
128
133
  super().__init__()
129
134
  self.read_from_session_file(
@@ -301,6 +306,8 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
301
306
  await self._do_price_ws(
302
307
  url=url,
303
308
  )
309
+ except asyncio.CancelledError:
310
+ return
304
311
  except Exception as ex:
305
312
  err_str = f"{ex}"
306
313
  if err_str.find("Event loop is closed") != -1:
@@ -308,6 +315,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
308
315
  return
309
316
 
310
317
  logger.warning(f"error at _do_price_ws: {err_str}")
318
+ await asyncio.sleep(1)
311
319
 
312
320
  async def _do_price_ws(self, url: str):
313
321
  async with websockets.connect(url, ping_interval=None) as ws:
@@ -914,6 +922,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
914
922
  unified_pos.position_pair = position.symbol.replace("-", "/")
915
923
  unified_pos.open_time = None # TODO: do something for this?
916
924
  unified_pos.open_price = position.avg_price
925
+ unified_pos.initial_margin = position.margin
917
926
  unified_pos.open_price_unit = (
918
927
  position.valuation_coin_name or position.symbol.split("-")[-1]
919
928
  ) # TODO
@@ -52,6 +52,9 @@ class ExchangeBase(ABC):
52
52
  install_channel: str = "officialAPK"
53
53
  channel_header: str = "officialAPK"
54
54
 
55
+ # The name of the exchange.
56
+ exchange_name: str = None
57
+
55
58
  jwt_manager: JWTManager = None
56
59
 
57
60
  _fav_letter: str = "^"
@@ -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
@@ -46,6 +49,7 @@ class HyperLiquidClient(ExchangeBase):
46
49
  self.account_name = account_name
47
50
  self._fav_letter = fav_letter
48
51
  self.sessions_dir = sessions_dir
52
+ self.exchange_name = "hyperliquid"
49
53
 
50
54
  super().__init__()
51
55
 
@@ -162,9 +166,10 @@ class HyperLiquidClient(ExchangeBase):
162
166
  unified_pos.margin_mode = position.leverage.type
163
167
  unified_pos.position_leverage = Decimal(position.leverage.value)
164
168
  unified_pos.position_pair = f"{position.coin}/USDT"
165
- unified_pos.open_time = None # hyperliquid doesn't provide this...
169
+ unified_pos.open_time = datetime.now(pytz.UTC) # hyperliquid doesn't provide this...
166
170
  unified_pos.open_price = position.entry_px
167
171
  unified_pos.open_price_unit = "USDT"
172
+ unified_pos.initial_margin = position.margin_used
168
173
  unified_result.positions.append(unified_pos)
169
174
 
170
175
  return unified_result
@@ -54,6 +54,7 @@ class OkxClient(ExchangeBase):
54
54
  self.account_name = account_name
55
55
  self._fav_letter = fav_letter
56
56
  self.sessions_dir = sessions_dir
57
+ self.exchange_name = "okx"
57
58
 
58
59
  super().__init__()
59
60
 
@@ -185,6 +186,7 @@ class OkxClient(ExchangeBase):
185
186
  unified_pos.open_time = position.c_time
186
187
  unified_pos.open_price = position.avg_px
187
188
  unified_pos.open_price_unit = position.quote_ccy
189
+ unified_pos.initial_margin = position.margin
188
190
  unified_result.positions.append(unified_pos)
189
191
 
190
192
  return unified_result
@@ -1,6 +1,9 @@
1
1
 
2
2
 
3
+ from datetime import datetime
3
4
  from decimal import Decimal
5
+
6
+ import pytz
4
7
  from trd_utils.types_helper import BaseModel
5
8
 
6
9
 
@@ -20,6 +23,13 @@ class MinimalCandleInfo(BaseModel):
20
23
  # volume in the second part of the pair (e.g. USDT).
21
24
  quote_volume: Decimal = None
22
25
 
26
+ # The time this candle info was retrieved.
27
+ fetched_at: datetime = None
28
+
29
+ def __init__(self, **kwargs):
30
+ super().__init__(**kwargs)
31
+ self.fetched_at = datetime.now(tz=pytz.UTC)
32
+
23
33
 
24
34
  class IPriceFetcher:
25
35
  """
@@ -35,4 +45,4 @@ class IPriceFetcher:
35
45
  pass
36
46
 
37
47
  async def get_last_candle(self, pair: str) -> MinimalCandleInfo:
38
- pass
48
+ pass
@@ -212,7 +212,6 @@ def convert_to_ultra_list(value: Any) -> UltraList:
212
212
  class BaseModel:
213
213
  def __init__(self, **kwargs):
214
214
  annotations = get_my_field_types(self)
215
- # annotations = self.__annotations__
216
215
  for key, value in kwargs.items():
217
216
  corrected_key = key
218
217
  if key not in annotations:
@@ -1,3 +0,0 @@
1
-
2
- __version__ = "0.0.34"
3
-
File without changes
File without changes