diff --git a/CHANGELOG.md b/CHANGELOG.md index db2feb0..0ed00b3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.1.5 2024-03-25 +### Fix +* Bybit: `on_balance_update`: duplication during transfer from web-interface +* Some exception handling + +### Update +* Dependency: Up requirements for crypto-ws-api==2.0.7 + ## 2.1.4 2024-03-22 ### Update * Refine HTTP handle errors diff --git a/exchanges_wrapper/__init__.py b/exchanges_wrapper/__init__.py index 1440a34..461c880 100755 --- a/exchanges_wrapper/__init__.py +++ b/exchanges_wrapper/__init__.py @@ -12,7 +12,7 @@ __contact__ = "https://github.com/DogsTailFarmer" __email__ = "jerry.fedorenko@yahoo.com" __credits__ = ["https://github.com/DanyaSWorlD"] -__version__ = "2.1.4" +__version__ = "2.1.5" from pathlib import Path import shutil diff --git a/exchanges_wrapper/bybit_parser.py b/exchanges_wrapper/bybit_parser.py index 8266654..7223214 100644 --- a/exchanges_wrapper/bybit_parser.py +++ b/exchanges_wrapper/bybit_parser.py @@ -450,7 +450,9 @@ def on_balance_update(data_in: list, ts: str, symbol: str, mode: str, uid=None) elif mode == 'universal': for i in data_in: - if i['coin'] in symbol and 'UNIFIED' in (i['fromAccountType'], i['toAccountType']): + if i['coin'] in symbol and \ + ((i['fromAccountType'] == 'UNIFIED' and i['fromMemberId'] == uid) + or (i['toAccountType'] == 'UNIFIED' and i['toMemberId'] == uid)): data_out.append( { i['transferId']: { diff --git a/exchanges_wrapper/client.py b/exchanges_wrapper/client.py index 952cda0..27bb766 100644 --- a/exchanges_wrapper/client.py +++ b/exchanges_wrapper/client.py @@ -1095,7 +1095,6 @@ async def cancel_order( # lgtm [py/similar-function] binance_res = bfx.order(res[4], response_type=True, cancelled=True) break await asyncio.sleep(0.1) - logger.debug(f"cancel_order.bitfinex {order_id}: timeout: {timeout}") else: logger.warning(f"cancel_order.bitfinex {order_id}: res: {res}") elif self.exchange == 'huobi': diff --git a/exchanges_wrapper/exch_srv.py b/exchanges_wrapper/exch_srv.py index 1487e8f..d50da14 100755 --- a/exchanges_wrapper/exch_srv.py +++ b/exchanges_wrapper/exch_srv.py @@ -1,7 +1,9 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +import grpclib.exceptions -from exchanges_wrapper import __version__ +from exchanges_wrapper import __version__ as ver_ew +from crypto_ws_api import __version__ as ver_cw import time import weakref import gc @@ -129,9 +131,9 @@ def get_id(cls, _account_name): ) @classmethod - def get_client(cls, _id, raise_ex=True): + def get_client(cls, _id): res = next((client for client in cls.open_clients if id(client) == _id), None) - if res is None and raise_ex: + if res is None: logger.warning(f"No client exist: {_id}") raise GRPCError(status=Status.UNAVAILABLE, message="No client exist") return res @@ -196,7 +198,7 @@ async def open_client_connection(self, request: mr.OpenClientConnectionRequest) Martin.rate_limiter = max(Martin.rate_limiter or 0, request.rate_limiter) return mr.OpenClientConnectionId( client_id=client_id, - srv_version=__version__, + srv_version=f"{ver_cw}:{ver_ew}", exchange=open_client.client.exchange, real_market=open_client.real_market ) @@ -229,7 +231,7 @@ async def send_request(self, client_method_name, request, rate_limit=False, **kw await self.rate_limit_control(open_client) try: res = await getattr(client, client_method_name)(**kwargs) - except asyncio.CancelledError: + except (asyncio.CancelledError, asyncio.exceptions.CancelledError): pass # Task cancellation should not be logged as an error except (errors.RateLimitReached, errors.QueryCanceled) as ex: Martin.rate_limit_reached_time = time.time() @@ -700,7 +702,7 @@ async def on_order_update(self, request: mr.MarketRequest) -> mr.SimpleResponse: else: event = vars(_event) event.pop('handlers', None) - # logger.debug(f"OnOrderUpdate: {open_client.name}: {event}") + # logger.info(f"OnOrderUpdate: {open_client.name}: {event}") response.success = True response.result = json.dumps(event) yield response @@ -800,11 +802,11 @@ async def stop_stream(self, request: mr.MarketRequest) -> mr.SimpleResponse: async def check_stream(self, request: mr.MarketRequest) -> mr.SimpleResponse: response = mr.SimpleResponse() - if open_client := OpenClient.get_client(request.client_id, raise_ex=False): + response.success = False + if open_client := OpenClient.get_client(request.client_id): client = open_client.client response.success = bool(client.data_streams.get(request.trade_id)) else: - response.success = False logger.warning(f"CheckStream request failed for {request.symbol}") return response @@ -841,7 +843,7 @@ async def amain(host: str = '127.0.0.1', port: int = 50051): server = Server([Martin()]) with graceful_exit([server]): await server.start(host, port) - logger.info(f"Starting server v:{__version__} on {host}:{port}") + logger.info(f"Starting server v:{ver_cw}:{ver_ew} on {host}:{port}") await server.wait_closed() for oc in OpenClient.open_clients: @@ -853,7 +855,7 @@ async def amain(host: str = '127.0.0.1', port: int = 50051): def main(): try: asyncio.run(amain()) - except asyncio.exceptions.CancelledError: + except (asyncio.exceptions.CancelledError, grpclib.exceptions.StreamTerminatedError): pass # # Task cancellation should not be logged as an error except Exception as ex: print(f"Exception: {ex}") diff --git a/exchanges_wrapper/http_client.py b/exchanges_wrapper/http_client.py index 9bf8b36..ac65cea 100644 --- a/exchanges_wrapper/http_client.py +++ b/exchanges_wrapper/http_client.py @@ -64,9 +64,9 @@ async def handle_errors(self, response): ): raise ExchangeError(ERR_TIMESTAMP_OUTSIDE_RECV_WINDOW) else: - raise ExchangeError(f"ExchangeError: {payload}:{response.reason}:{response.text}") + raise ExchangeError(f"ExchangeError: {payload}") elif response.reason != "Bad Request": - raise ExchangeError(f"ExchangeError: {payload}:{response.reason}:{response.text}") + raise ExchangeError(f"ExchangeError: {response.reason}:{response.text}") elif ( response.status == STATUS_UNAUTHORIZED diff --git a/pyproject.toml b/pyproject.toml index 3fa02d2..d17eef1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ dynamic = ["version", "description"] requires-python = ">=3.9" dependencies = [ - "crypto-ws-api==2.0.6", + "crypto-ws-api==2.0.7", "grpcio==1.62.0", "pyotp~=2.9.0", "simplejson==3.19.2", diff --git a/requirements.txt b/requirements.txt index 9f94134..d398ad7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -crypto-ws-api==2.0.6 +crypto-ws-api==2.0.7 pyotp==2.9.0 simplejson==3.19.2 toml~=0.10.2