exchanges-wrapper 2.1.29__tar.gz → 2.1.31__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.
Files changed (20) hide show
  1. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/PKG-INFO +6 -8
  2. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/__init__.py +1 -1
  3. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/client.py +3 -1
  4. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/exch_srv.py +1 -1
  5. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/http_client.py +1 -1
  6. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/parsers/huobi.py +36 -22
  7. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/pyproject.toml +3 -6
  8. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/LICENSE.md +0 -0
  9. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/README.md +0 -0
  10. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/definitions.py +0 -0
  11. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/errors.py +0 -0
  12. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/events.py +0 -0
  13. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/exch_srv_cfg.toml.template +0 -0
  14. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/lib.py +0 -0
  15. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/martin/__init__.py +0 -0
  16. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/parsers/bitfinex.py +0 -0
  17. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/parsers/bybit.py +0 -0
  18. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/parsers/okx.py +0 -0
  19. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/proto/martin.proto +0 -0
  20. {exchanges_wrapper-2.1.29 → exchanges_wrapper-2.1.31}/exchanges_wrapper/web_sockets.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: exchanges-wrapper
3
- Version: 2.1.29
3
+ Version: 2.1.31
4
4
  Summary: REST API and WebSocket asyncio wrapper with grpc powered multiplexer server
5
5
  Author-email: Thomas Marchand <thomas.marchand@tuta.io>, Jerry Fedorenko <jerry.fedorenko@yahoo.com>
6
6
  Requires-Python: >=3.9
@@ -11,14 +11,12 @@ Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Operating System :: Unix
12
12
  Classifier: Operating System :: Microsoft :: Windows
13
13
  Classifier: Operating System :: MacOS
14
- Requires-Dist: crypto-ws-api==2.0.16
14
+ License-File: LICENSE.md
15
+ Requires-Dist: crypto-ws-api==2.0.18
15
16
  Requires-Dist: pyotp==2.9.0
16
- Requires-Dist: simplejson==3.19.3
17
- Requires-Dist: toml~=0.10.2
18
- Requires-Dist: aiohttp~=3.11.11
19
- Requires-Dist: websockets==14.2
17
+ Requires-Dist: simplejson==3.20.1
18
+ Requires-Dist: aiohttp~=3.11.12
20
19
  Requires-Dist: expiringdict~=1.2.2
21
- Requires-Dist: ujson~=5.10.0
22
20
  Requires-Dist: betterproto==2.0.0b7
23
21
  Requires-Dist: grpclib~=0.4.7
24
22
  Project-URL: Source, https://github.com/DogsTailFarmer/exchanges-wrapper
@@ -12,7 +12,7 @@ __maintainer__ = "Jerry Fedorenko"
12
12
  __contact__ = "https://github.com/DogsTailFarmer"
13
13
  __email__ = "jerry.fedorenko@yahoo.com"
14
14
  __credits__ = ["https://github.com/DanyaSWorlD"]
15
- __version__ = "2.1.29"
15
+ __version__ = "2.1.31"
16
16
 
17
17
  from pathlib import Path
18
18
  import shutil
@@ -1515,11 +1515,13 @@ class Client:
1515
1515
  params = {}
1516
1516
  binance_res = {}
1517
1517
  if self.exchange == 'binance':
1518
+ params["omitZeroBalances"] = "true"
1518
1519
  if receive_window:
1519
1520
  params["recvWindow"] = receive_window
1520
1521
  binance_res = await self.user_session.handle_request(
1521
1522
  trade_id,
1522
1523
  "account.status",
1524
+ _params=params,
1523
1525
  send_api_key=True,
1524
1526
  _signed=True
1525
1527
  )
@@ -1548,7 +1550,7 @@ class Client:
1548
1550
  params = {'accountType': 'UNIFIED'}
1549
1551
  res, ts = await self.http.send_api_call("/v5/account/wallet-balance", signed=True, **params)
1550
1552
  binance_res = bbt.account_information(res["list"][0]["coin"], ts)
1551
- # print(f"fetch_account_information.binance_res: {binance_res}")
1553
+ # logger.info(f"fetch_account_information.binance_res: {trade_id}: {binance_res}")
1552
1554
  return binance_res
1553
1555
 
1554
1556
  # https://binance-docs.github.io/apidocs/spot/en/#funding-wallet-user_data
@@ -32,7 +32,7 @@ from exchanges_wrapper.martin import StreamResponse, SimpleResponse, OnKlinesUpd
32
32
  #
33
33
  HEARTBEAT = 1 # sec
34
34
  MAX_QUEUE_SIZE = 100
35
- WSS_TICKER_TIMEOUT = 300 # sec
35
+ WSS_TICKER_TIMEOUT = 600 # sec
36
36
  #
37
37
  logger = logging.getLogger(__name__)
38
38
  formatter = logging.Formatter(fmt="[%(asctime)s: %(levelname)s] %(message)s")
@@ -63,7 +63,7 @@ class HttpClient:
63
63
  if response.status >= 500:
64
64
  raise ExchangeError(
65
65
  f"{'API request rejected' if self.exchange == 'bitfinex' else 'An issue occurred on exchange side'}:"
66
- f" {response.status}: {response.url}: {response.reason}"
66
+ f" {response.status}: {response.reason}"
67
67
  )
68
68
  if response.status == 429 or (self.exchange == 'bybit' and response.status == STATUS_FORBIDDEN):
69
69
  logger.error(f"API RateLimitReached: {response.url}")
@@ -170,6 +170,7 @@ def order(res: {}, response_type=None) -> {}:
170
170
  "side": side,
171
171
  }
172
172
 
173
+
173
174
  def order_cancelled(symbol, order_id=None, origin_client_order_id=None,) -> {}:
174
175
  return {
175
176
  "symbol": symbol,
@@ -188,27 +189,44 @@ def order_cancelled(symbol, order_id=None, origin_client_order_id=None,) -> {}:
188
189
  "side": '',
189
190
  }
190
191
 
192
+
191
193
  def account_information(res: {}) -> {}:
192
- balances = []
194
+ """
195
+ This function parses the Huobi API response for account information and
196
+ returns a dictionary with relevant details.
197
+
198
+ Args:
199
+ res (dict): The API response from the Huobi exchange.
200
+
201
+ Returns:
202
+ dict: A dictionary containing the user's account information.
203
+ """
204
+
205
+ # Filter out balances that have zero value
193
206
  res[:] = [i for i in res if i.get('balance') != '0']
207
+
194
208
  assets = {}
195
209
  for balance in res:
196
- asset = balance.get('currency')
197
- asset_i = assets.get(asset, {})
210
+ asset = balance['currency']
211
+ assets.setdefault(asset, {
212
+ 'available': Decimal(0),
213
+ 'frozen': Decimal(0)
214
+ })
215
+
216
+ # Update available and frozen balances
198
217
  if balance.get('available'):
199
- asset_i.setdefault('available', balance.get('available'))
218
+ assets[asset]['available'] += Decimal(balance['available'])
200
219
  else:
201
- asset_i.setdefault('frozen', balance.get('balance', '0'))
202
- assets[asset] = asset_i
203
- for asset in assets:
204
- free = assets.get(asset, {}).get('available', '0')
205
- locked = assets.get(asset, {}).get('frozen', '0')
206
- _binance_res = {
220
+ assets[asset]['frozen'] += Decimal(balance['balance'])
221
+
222
+ balances = [
223
+ {
207
224
  "asset": asset.upper(),
208
- "free": free,
209
- "locked": locked,
225
+ "free": str(assets[asset]["available"]),
226
+ "locked": str(assets[asset]["frozen"])
210
227
  }
211
- balances.append(_binance_res)
228
+ for asset in assets
229
+ ]
212
230
 
213
231
  return {
214
232
  "makerCommission": 0,
@@ -226,20 +244,16 @@ def account_information(res: {}) -> {}:
226
244
 
227
245
 
228
246
  def order_book(res: {}) -> {}:
229
- binance_order_book = {"lastUpdateId": res.get('ts')}
230
- binance_order_book.setdefault('bids', res.get('bids'))
231
- binance_order_book.setdefault('asks', res.get('asks'))
232
- return binance_order_book
247
+ res["lastUpdateId"] = res.pop("ts")
248
+ return res
233
249
 
234
250
 
235
251
  def order_book_ws(res: {}, symbol: str) -> {}:
236
- bids = res.get('tick').get('bids')[:5]
237
- asks = res.get('tick').get('asks')[:5]
238
252
  return {
239
253
  'stream': f"{symbol}@depth5",
240
- 'data': {'lastUpdateId': res.get('ts'),
241
- 'bids': bids,
242
- 'asks': asks,
254
+ 'data': {'lastUpdateId': res['ts'],
255
+ 'bids': res['tick']['bids'][:5],
256
+ 'asks': res['tick']['asks'][:5],
243
257
  }
244
258
  }
245
259
 
@@ -17,14 +17,11 @@ dynamic = ["version", "description"]
17
17
  requires-python = ">=3.9"
18
18
 
19
19
  dependencies = [
20
- "crypto-ws-api==2.0.16",
20
+ "crypto-ws-api==2.0.18",
21
21
  "pyotp==2.9.0",
22
- "simplejson==3.19.3",
23
- "toml~=0.10.2",
24
- "aiohttp~=3.11.11",
25
- "websockets==14.2",
22
+ "simplejson==3.20.1",
23
+ "aiohttp~=3.11.12",
26
24
  "expiringdict~=1.2.2",
27
- "ujson~=5.10.0",
28
25
  "betterproto==2.0.0b7",
29
26
  "grpclib~=0.4.7"
30
27
  ]