Closed nikolayromenskiy closed 2 months ago
Fixed in the commit 75d1f36. When loading the trading history in the file api/bybit/agent.py in the trading_history() function, the sign of correct exit from the thread has been changed, explicitly specified as “success” at the exit point from get_in_thread(). Thus, if the get_in_thread() function does not complete due to a Bybit API error, the thread completion flag will remain by default as None, which will be regarded by the program as an unsuccessful attempt to load the trading history, and therefore will be a signal to completely reload the data from Bybit.
See comments in the code below:
def trading_history(self, histCount: int, time=None) -> list:
if time:
trade_history = []
utc = datetime.now(timezone.utc)
if utc - time > timedelta(days=729):
self.logger.info(
"Bybit only allows you to query trading history for the last 2 years. Check the History.ini file."
)
time = utc - timedelta(days=729)
self.logger.info("Time changed to " + str(time))
startTime = service.time_converter(time)
limit = min(100, histCount)
def get_in_thread(category, startTime, limit, success, num):
nonlocal trade_history
cursor = "no"
while cursor:
self.logger.info(
"Sending get_executions() - category - "
+ category
+ " - startTime - "
+ str(service.time_converter(startTime / 1000))
)
result = self.session.get_executions(
category=category,
startTime=startTime,
limit=limit,
cursor=cursor,
)
cursor = result["result"]["nextPageCursor"]
res = result["result"]["list"]
if isinstance(result["result"]["list"], list):
for row in res:
row["symbol"] = (row["symbol"], category, self.name)
row["execID"] = row["execId"]
row["orderID"] = row["orderId"]
row["category"] = category
row["lastPx"] = float(row["execPrice"])
row["leavesQty"] = float(row["leavesQty"])
row["transactTime"] = service.time_converter(
time=int(row["execTime"]) / 1000, usec=True
)
row["commission"] = float(row["feeRate"])
if row["orderLinkId"]:
row["clOrdID"] = row["orderLinkId"]
row["price"] = float(row["execPrice"])
if category == "spot":
row["settlCurrency"] = (row["feeCurrency"], self.name)
else:
row["settlCurrency"] = self.Instrument[
row["symbol"]
].settlCurrency
row["lastQty"] = float(row["execQty"])
row["market"] = self.name
if row["execType"] == "Funding":
if row["side"] == "Sell":
row["lastQty"] = -row["lastQty"]
row["execFee"] = float(row["execFee"])
trade_history += res
####################################################
# success[num] is explicitly specified as “success”
####################################################
success[num] = "success"
else:
return
while startTime < service.time_converter(datetime.now(tz=timezone.utc)):
threads, success = [], []
for category in self.categories:
####################################################
# success[num] defaults to None
####################################################
success.append(None)
t = threading.Thread(
target=get_in_thread,
args=(category, startTime, limit, success, len(success) - 1),
)
threads.append(t)
t.start()
[thread.join() for thread in threads]
####################################################
# All threads must succeed, otherwise None is returned
####################################################
for s in success:
if not s:
return
message = (
"Bybit - loading trading history, startTime="
+ str(service.time_converter(startTime / 1000))
+ ", received: "
+ str(len(trade_history))
+ " records."
)
self.logger.info(message)
if len(trade_history) > histCount:
break
startTime += 604800000 # +7 days
trade_history.sort(key=lambda x: x["transactTime"])
return trade_history
2024-06-08 15:03:20,856 - api.bybit.ws - INFO - Bybit - Websocket closed 2024-06-08 15:03:20,857 - api.bybit.agent - INFO - Sending get_instruments_info() - category - spot 2024-06-08 15:03:20,859 - api.bybit.agent - INFO - Sending get_instruments_info() - category - inverse 2024-06-08 15:03:20,860 - api.bybit.agent - INFO - Sending get_instruments_info() - category - option 2024-06-08 15:03:20,862 - api.bybit.agent - INFO - Sending get_instruments_info() - category - linear 2024-06-08 15:03:21,383 - api.bybit.agent - INFO - Sending open_orders() - parameters - {'openOnly': 0, 'limit': 50, 'category': 'spot', 'cursor': 'no'} 2024-06-08 15:03:21,384 - api.bybit.agent - INFO - Sending open_orders() - parameters - {'openOnly': 0, 'limit': 50, 'category': 'linear', 'settleCoin': 'USDT', 'cursor': 'no'} 2024-06-08 15:03:22,040 - api.bybit.agent - INFO - Sending open_orders() - parameters - {'openOnly': 0, 'limit': 50, 'category': 'linear', 'settleCoin': 'USDT', 'cursor': 'ce655e2e-02da-45ed-a3fd-13861dd5f4ae%3A1717858200151%2Caa2205dd-6474-4199-9540-67c7e709a1d7%3A1716477047327'} 2024-06-08 15:03:22,261 - api.bybit.ws - INFO - Connecting to websocket 2024-06-08 15:03:22,262 - api.bybit.agent - INFO - Sending get_uid_wallet_type() 2024-06-08 15:03:22,262 - api.bybit.agent - INFO - Sending get_wallet_balance() - accountType - UNIFIED 2024-06-08 15:03:22,265 - api.bybit.pybit._websocket_stream - INFO - WebSocket Unified V5 attempting connection... 2024-06-08 15:03:22,266 - api.bybit.agent - INFO - Sending get_positions() - category - linear - settlCurrency - USDT 2024-06-08 15:03:22,266 - api.bybit.pybit._websocket_stream - INFO - WebSocket Unified V5 (Auth) attempting connection... 2024-06-08 15:03:22,971 - api.bybit.agent - INFO - Sending get_wallet_balance() - accountType - CONTRACT 2024-06-08 15:03:23,712 - websocket - INFO - Websocket connected 2024-06-08 15:03:23,712 - api.bybit.pybit._websocket_stream - INFO - WebSocket Unified V5 (Auth) connected 2024-06-08 15:03:23,740 - websocket - INFO - Websocket connected 2024-06-08 15:03:23,742 - api.bybit.pybit._websocket_stream - INFO - WebSocket Unified V5 connected 2024-06-08 15:03:23,742 - api.bybit.ws - INFO - ws subscription - orderbook_stream - category - linear - symbol - ('BTCUSDT', 'linear', 'Bybit') 2024-06-08 15:03:23,742 - api.bybit.ws - INFO - ws subscription - ticker_stream - category - linear - symbol - ('BTCUSDT', 'linear', 'Bybit') 2024-06-08 15:03:23,751 - api.bybit.agent - INFO - Sending get_executions() - category - spot - startTime - 2024-06-05 08:04:40+00:00 2024-06-08 15:03:23,751 - api.bybit.agent - INFO - Sending get_executions() - category - inverse - startTime - 2024-06-05 08:04:40+00:00 2024-06-08 15:03:23,753 - api.bybit.agent - INFO - Sending get_executions() - category - option - startTime - 2024-06-05 08:04:40+00:00 2024-06-08 15:03:23,753 - api.bybit.agent - INFO - Sending get_executions() - category - linear - startTime - 2024-06-05 08:04:40+00:00 ___Unexpected Bybit error: Exception Traceback (most recent call last): File "/home/rmn/tmatic_240608/api/bybit/errors.py", line 16, in decorator return method(*args, **kwargs) File "/home/rmn/tmatic_240608/api/bybit/ws.py", line 416, in _on_message self.callback(message) File "/home/rmn/tmatic_240608/api/bybit/pybit/_websocket_stream.py", line 458, in _handle_incoming_message self._process_auth_message(message) File "/home/rmn/tmatic_240608/api/bybit/pybit/_websocket_stream.py", line 402, in _process_auth_message raise Exception( Exception: Authorization for Unified V5 (Auth) failed. Please check your API keys and resync your system time. Raw error: {'success': False, 'ret_msg': 'Params Error', 'op': 'auth', 'conn_id': 'cno3fi5daugt7mgdqvtg-2yz96'} 2024-06-08 15:03:23,955 - api.bybit.errors - ERROR - Exception - Authorization for Unified V5 (Auth) failed. Please check your API keys and resync your system time. Raw error: {'success': False, 'ret_msg': 'Params Error', 'op': 'auth', 'conn_id': 'cno3fi5daugt7mgdqvtg-2yz96'} 2024-06-08 15:03:23,956 - websocket - ERROR - error from callback <function _WebSocketManager._connect.. at 0x782840198dc0>: 'WebSocket' object has no attribute 'name'
2024-06-08 15:03:23,989 - api.bybit.agent - INFO - Sending get_executions() - category - linear - startTime - 2024-06-05 08:04:40+00:00
2024-06-08 15:03:24,171 - websocket - ERROR - error from callback <function _WebSocketManager._connect.. at 0x782840198d30>: 'WebSocket' object has no attribute 'name'
2024-06-08 15:03:24,171 - websocket - INFO - tearing down on exception 'WebSocket' object has no attribute 'name'
2024-06-08 15:03:24,402 - api.bybit.agent - INFO - Bybit - loading trading history, startTime=2024-06-05 08:04:40+00:00, received: 1 records.
2024-06-08 15:03:24,602 - common.init - INFO - Robot EMI=Btc1. Adding to 'robots' with STATUS='NOT DEFINED'
2024-06-08 15:03:24,602 - common.init - INFO - Robot EMI=Btc5. Adding to 'robots' with STATUS='NOT DEFINED'
__Tmatic: Bybit API is still pinging, but the websocket is already closed
__Tmatic: Bybit API is still pinging, but the websocket is already closed