bitunix-automated-crypto-trading 2.6.7__py3-none-any.whl → 2.6.8__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.
Files changed (31) hide show
  1. bitunix_automated_crypto_trading/AsyncThreadRunner.py +81 -81
  2. bitunix_automated_crypto_trading/BitunixApi.py +278 -278
  3. bitunix_automated_crypto_trading/BitunixSignal.py +1099 -1099
  4. bitunix_automated_crypto_trading/BitunixWebSocket.py +254 -254
  5. bitunix_automated_crypto_trading/DataFrameHtmlRenderer.py +74 -74
  6. bitunix_automated_crypto_trading/NotificationManager.py +23 -23
  7. bitunix_automated_crypto_trading/ThreadManager.py +68 -68
  8. bitunix_automated_crypto_trading/TickerManager.py +635 -635
  9. bitunix_automated_crypto_trading/bitunix.py +597 -594
  10. bitunix_automated_crypto_trading/config.py +90 -90
  11. bitunix_automated_crypto_trading/logger.py +84 -84
  12. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/METADATA +36 -36
  13. bitunix_automated_crypto_trading-2.6.8.dist-info/RECORD +17 -0
  14. bitunix_automated_crypto_trading/config.txt +0 -60
  15. bitunix_automated_crypto_trading/sampleenv.txt +0 -5
  16. bitunix_automated_crypto_trading/static/chart.css +0 -28
  17. bitunix_automated_crypto_trading/static/chart.js +0 -362
  18. bitunix_automated_crypto_trading/static/modal.css +0 -68
  19. bitunix_automated_crypto_trading/static/modal.js +0 -147
  20. bitunix_automated_crypto_trading/static/script.js +0 -166
  21. bitunix_automated_crypto_trading/static/styles.css +0 -118
  22. bitunix_automated_crypto_trading/templates/charts.html +0 -98
  23. bitunix_automated_crypto_trading/templates/login.html +0 -19
  24. bitunix_automated_crypto_trading/templates/main.html +0 -551
  25. bitunix_automated_crypto_trading/templates/modal-chart.html +0 -26
  26. bitunix_automated_crypto_trading/templates/modal-config.html +0 -34
  27. bitunix_automated_crypto_trading/templates/modal-logs.html +0 -15
  28. bitunix_automated_crypto_trading-2.6.7.dist-info/RECORD +0 -31
  29. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/WHEEL +0 -0
  30. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/entry_points.txt +0 -0
  31. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/top_level.txt +0 -0
@@ -1,278 +1,278 @@
1
- import secrets
2
- import base64
3
- import time
4
- import json
5
- import hashlib
6
- import asyncio
7
- import requests
8
- from urllib.parse import urlencode
9
- from typing import Dict, Any
10
- import traceback
11
- from .logger import Logger
12
- logger = Logger(__name__).get_logger()
13
-
14
-
15
- class BitunixApi:
16
-
17
- def __init__(self, api_key, secret_key, settings):
18
- self.api_key = api_key
19
- self.secret_key = secret_key
20
-
21
- self.session = requests.Session()
22
- self.session.headers.update({
23
- 'Content-Type': 'application/json',
24
- 'User-Agent': 'BitunixAPI/1.0'
25
- })
26
-
27
- self.pending_positions_URL="https://fapi.bitunix.com/api/v1/futures/position/get_pending_positions"
28
- self.account_Url="https://fapi.bitunix.com/api/v1/futures/account"
29
- self.ticker_Url='https://fapi.bitunix.com/api/v1/futures/market/tickers'
30
- self.ticker_pair_Url='https://fapi.bitunix.com/api/v1/futures/market/trading_pairs'
31
- self.kline_Url='https://fapi.bitunix.com/api/v1/futures/market/kline'
32
- self.depth_Url='https://fapi.bitunix.com/api/v1/futures/market/depth'
33
- self.placeOrder_Url="https://fapi.bitunix.com/api/v1/futures/trade/place_order"
34
- self.flashClose_Url="https://fapi.bitunix.com/api/v1/futures/trade/flash_close_position"
35
- self.pending_order_url="https://fapi.bitunix.com/api/v1/futures/trade/get_pending_orders"
36
- self.cancelOrder_Url="https://fapi.bitunix.com/api/v1/futures/trade/cancel_orders"
37
- self.Trade_history_Url="https://fapi.bitunix.com/api/v1/futures/trade/get_history_trades"
38
- self.position_history_Url="https://fapi.bitunix.com/api/v1/futures/position/get_history_positions"
39
-
40
- async def update_settings(self, settings):
41
- self.settings = settings
42
-
43
- async def create_timestamp(self):
44
- return str(int(time.time()*1000))
45
-
46
- async def is_near_high_of_day(self, current_value, high_of_day, threshold_percentage=5):
47
- # Calculate the difference as a percentage of the high of the day
48
- difference_percentage = ((high_of_day - current_value) / high_of_day) * 100
49
- # Check if the difference is within the threshold
50
- return difference_percentage <= threshold_percentage
51
-
52
- async def is_near_low_of_day(self, current_value, low_of_day, threshold_percentage=5):
53
- # Calculate the difference as a percentage of the low of the day
54
- difference_percentage = ((current_value - low_of_day) / low_of_day) * 100
55
- # Check if the difference is within the threshold
56
- return difference_percentage <= threshold_percentage
57
-
58
-
59
- async def _generate_nonce(self) -> str:
60
- random_bytes = secrets.token_bytes(32)
61
- return base64.b64encode(random_bytes).decode('utf-8')
62
-
63
-
64
- async def sign_request(self, nonce: str, timestamp: str,
65
- query_params: str = None,
66
- body: str = None) -> str:
67
- query_string = query_params if query_params else ""
68
- body_string = body if body else ""
69
- message = f"{nonce}{timestamp}{self.api_key}{query_string}{body_string}"
70
-
71
- # First SHA256 encryption
72
- digest = hashlib.sha256(message.encode()).hexdigest()
73
-
74
- # Second SHA256 encryption
75
- sign = hashlib.sha256((digest + self.secret_key).encode()).hexdigest()
76
-
77
- return sign
78
-
79
- async def _get(self, endpoint: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
80
- response = self.session.get(endpoint, params=params)
81
- response.raise_for_status()
82
- return response.json()
83
-
84
- async def _get_authenticated(self, endpoint: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
85
- timestamp = await self.create_timestamp()
86
- nonce = await self._generate_nonce()
87
-
88
- headers = {
89
- "api-key": self.api_key,
90
- "timestamp": timestamp,
91
- "nonce": nonce,
92
- }
93
-
94
- query_string = urlencode(sorted(params.items())).replace('=','') if params else ""
95
- signature = await self.sign_request(nonce, timestamp, query_params=query_string)
96
- headers["sign"] = signature
97
-
98
- response = self.session.get(endpoint, params=params, headers=headers)
99
- response.raise_for_status()
100
- return response.json()
101
-
102
- async def _post_authenticated(self, endpoint: str, data: Dict[str, Any]) -> Dict[str, Any]:
103
- timestamp = await self.create_timestamp()
104
- nonce = await self._generate_nonce()
105
-
106
- headers = {
107
- "api-key": self.api_key,
108
- "timestamp": timestamp,
109
- "nonce": nonce,
110
- "Content-Type": "application/json"
111
- }
112
-
113
- body_string = json.dumps(data, separators=(',', ':'))
114
- signature = await self.sign_request(nonce, timestamp, body=body_string)
115
- headers["sign"] = signature
116
-
117
- response = self.session.post(endpoint, data=body_string, headers=headers)
118
- logger.info(f"Response: {body_string} {response.json()}")
119
- response.raise_for_status()
120
- return response.json()
121
-
122
- async def PlaceOrder(self, ticker, qty, price, side, positionId=0, tradeSide="OPEN",reduceOnly=False):
123
- data = {
124
- "side": side,
125
- "orderType":"LIMIT",
126
- "qty": qty,
127
- "price": price,
128
- "symbol": ticker,
129
- "tradeSide":tradeSide,
130
- "reduceOnly":reduceOnly,
131
- "positionId":positionId
132
- }
133
- datajs = await self._post_authenticated(self.placeOrder_Url,data)
134
- return datajs
135
-
136
- async def FlashClose(self, positionId):
137
- data = {
138
- "positionId": positionId
139
- }
140
- datajs = await self._post_authenticated(self.flashClose_Url,data)
141
- return datajs
142
-
143
- async def CancelOrder(self, symbol, orderId):
144
- data = {
145
- "symbol": symbol,
146
- "orderList":[{"orderId": orderId}]
147
- }
148
- datajs = await self._post_authenticated(self.cancelOrder_Url,data)
149
- return datajs
150
-
151
- async def GetTradeHistoryData(self):
152
- tradeHistory=await self._get_authenticated(self.Trade_history_Url)
153
- if tradeHistory['code']==0:
154
- return tradeHistory['data']
155
- else:
156
- logger.info(tradeHistory['msg'])
157
-
158
- async def GetPendingOrderData(self,dictparm={}):
159
- orders=await self._get_authenticated(self.pending_order_url, dictparm)
160
- if orders['code']==0:
161
- return orders['data']
162
- else:
163
- logger.info(orders['msg'])
164
-
165
- async def GetPendingPositionData(self, dictparm={}):
166
- positions=await self._get_authenticated(self.pending_positions_URL, dictparm)
167
- if positions['code']==0:
168
- return positions['data']
169
- else:
170
- logger.info(positions['msg'])
171
-
172
- async def GetPositionHistoryData(self, dictparm={}):
173
- tradeHistory=await self._get_authenticated(self.position_history_Url, dictparm)
174
- if tradeHistory['code']==0:
175
- return tradeHistory['data']
176
- else:
177
- logger.info(tradeHistory['msg'])
178
-
179
-
180
- async def GetportfolioData(self):
181
- portfolio=await self._get_authenticated(self.account_Url, params={"marginCoin":"USDT"})
182
- if portfolio['code']==0:
183
- return portfolio['data']
184
- else:
185
- logger.info(portfolio['msg'])
186
-
187
-
188
- async def GetTickerslastPrice(self, tickersStr):
189
- try:
190
- resp = self.session.get(self.ticker_Url+'?symbols='+tickersStr)
191
- datajs = resp.json()
192
- if datajs['code']==0:
193
- return datajs['data']
194
- except Exception as e:
195
- stack = traceback.extract_stack()
196
- function_name = stack[-2].name
197
- logger.error(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
198
-
199
- async def GetTickersPair(self, tickersStr):
200
- try:
201
- resp = self.session.get(self.ticker_pair_Url+'?symbols='+tickersStr)
202
- datajs = resp.json()
203
- if datajs['code']==0:
204
- return datajs['data']
205
- except Exception as e:
206
- stack = traceback.extract_stack()
207
- function_name = stack[-2].name
208
- logger.error(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
209
-
210
- async def GetTickerList(self, threshold, volume):
211
- symbols=[]
212
- try:
213
- resp = self.session.get(self.ticker_Url)
214
- datajs = resp.json()
215
- for item in datajs["data"]:
216
- if await self.is_near_high_of_day(float(item['last']), float(item['high']) ,threshold) and float(item['baseVol']) > volume:
217
- symbols.append(item['symbol'])
218
- if await self.is_near_low_of_day(float(item['last']), float(item['low']) ,threshold) and float(item['baseVol']) > volume:
219
- symbols.append(item['symbol'])
220
- #if float(item['baseVol']) > volume:
221
- # symbols.append(item['symbol'])
222
- return symbols
223
- except Exception as e:
224
- stack = traceback.extract_stack()
225
- function_name = stack[-2].name
226
- logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
227
-
228
- async def GetTickerData(self):
229
- try:
230
- url = f'{self.ticker_Url}'
231
- resp = self.session.get(url)
232
- datajs = resp.json()
233
- if datajs['code']==0:
234
- return datajs['data']
235
- except Exception as e:
236
- stack = traceback.extract_stack()
237
- function_name = stack[-2].name
238
- logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
239
-
240
- async def GetDepthData(self,symbol,limit):
241
- try:
242
- url = f'{self.depth_Url}?symbol={symbol}&limit={limit}'
243
- resp = self.session.get(url)
244
- datajs = resp.json()
245
- if datajs['code']==0:
246
- return datajs['data']
247
- except Exception as e:
248
- stack = traceback.extract_stack()
249
- function_name = stack[-2].name
250
- logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
251
-
252
- async def GetKlineHistory(self, ticker, interval, limit):
253
- data = []
254
- lm=limit
255
- current_unix_timestamp = int(time.time())
256
- try:
257
- while True:
258
- url = f'{self.kline_Url}?symbol={ticker}&startTime={current_unix_timestamp}&interval={interval}&limit={lm}'
259
- resp = self.session.get(url)
260
- datajs = resp.json()
261
- if len(datajs['data']) > 0:
262
- current_unix_timestamp = str(int(datajs['data'][-1]['time']) + 1) # Adjust 'time' to match the appropriate key in your data
263
- data.extend(datajs['data'])
264
- lm=limit-len(data)
265
- if len(data) >= limit:
266
- break
267
- else:
268
- break
269
- return data
270
- except Exception as e:
271
- stack = traceback.extract_stack()
272
- function_name = stack[-2].name
273
- logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
274
-
275
- def __del__(self):
276
- """Cleanup method to close the session"""
277
- if hasattr(self, 'session'):
278
- self.session.close()
1
+ import secrets
2
+ import base64
3
+ import time
4
+ import json
5
+ import hashlib
6
+ import asyncio
7
+ import requests
8
+ from urllib.parse import urlencode
9
+ from typing import Dict, Any
10
+ import traceback
11
+ from logger import Logger
12
+ logger = Logger(__name__).get_logger()
13
+
14
+
15
+ class BitunixApi:
16
+
17
+ def __init__(self, api_key, secret_key, settings):
18
+ self.api_key = api_key
19
+ self.secret_key = secret_key
20
+
21
+ self.session = requests.Session()
22
+ self.session.headers.update({
23
+ 'Content-Type': 'application/json',
24
+ 'User-Agent': 'BitunixAPI/1.0'
25
+ })
26
+
27
+ self.pending_positions_URL="https://fapi.bitunix.com/api/v1/futures/position/get_pending_positions"
28
+ self.account_Url="https://fapi.bitunix.com/api/v1/futures/account"
29
+ self.ticker_Url='https://fapi.bitunix.com/api/v1/futures/market/tickers'
30
+ self.ticker_pair_Url='https://fapi.bitunix.com/api/v1/futures/market/trading_pairs'
31
+ self.kline_Url='https://fapi.bitunix.com/api/v1/futures/market/kline'
32
+ self.depth_Url='https://fapi.bitunix.com/api/v1/futures/market/depth'
33
+ self.placeOrder_Url="https://fapi.bitunix.com/api/v1/futures/trade/place_order"
34
+ self.flashClose_Url="https://fapi.bitunix.com/api/v1/futures/trade/flash_close_position"
35
+ self.pending_order_url="https://fapi.bitunix.com/api/v1/futures/trade/get_pending_orders"
36
+ self.cancelOrder_Url="https://fapi.bitunix.com/api/v1/futures/trade/cancel_orders"
37
+ self.Trade_history_Url="https://fapi.bitunix.com/api/v1/futures/trade/get_history_trades"
38
+ self.position_history_Url="https://fapi.bitunix.com/api/v1/futures/position/get_history_positions"
39
+
40
+ async def update_settings(self, settings):
41
+ self.settings = settings
42
+
43
+ async def create_timestamp(self):
44
+ return str(int(time.time()*1000))
45
+
46
+ async def is_near_high_of_day(self, current_value, high_of_day, threshold_percentage=5):
47
+ # Calculate the difference as a percentage of the high of the day
48
+ difference_percentage = ((high_of_day - current_value) / high_of_day) * 100
49
+ # Check if the difference is within the threshold
50
+ return difference_percentage <= threshold_percentage
51
+
52
+ async def is_near_low_of_day(self, current_value, low_of_day, threshold_percentage=5):
53
+ # Calculate the difference as a percentage of the low of the day
54
+ difference_percentage = ((current_value - low_of_day) / low_of_day) * 100
55
+ # Check if the difference is within the threshold
56
+ return difference_percentage <= threshold_percentage
57
+
58
+
59
+ async def _generate_nonce(self) -> str:
60
+ random_bytes = secrets.token_bytes(32)
61
+ return base64.b64encode(random_bytes).decode('utf-8')
62
+
63
+
64
+ async def sign_request(self, nonce: str, timestamp: str,
65
+ query_params: str = None,
66
+ body: str = None) -> str:
67
+ query_string = query_params if query_params else ""
68
+ body_string = body if body else ""
69
+ message = f"{nonce}{timestamp}{self.api_key}{query_string}{body_string}"
70
+
71
+ # First SHA256 encryption
72
+ digest = hashlib.sha256(message.encode()).hexdigest()
73
+
74
+ # Second SHA256 encryption
75
+ sign = hashlib.sha256((digest + self.secret_key).encode()).hexdigest()
76
+
77
+ return sign
78
+
79
+ async def _get(self, endpoint: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
80
+ response = self.session.get(endpoint, params=params)
81
+ response.raise_for_status()
82
+ return response.json()
83
+
84
+ async def _get_authenticated(self, endpoint: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
85
+ timestamp = await self.create_timestamp()
86
+ nonce = await self._generate_nonce()
87
+
88
+ headers = {
89
+ "api-key": self.api_key,
90
+ "timestamp": timestamp,
91
+ "nonce": nonce,
92
+ }
93
+
94
+ query_string = urlencode(sorted(params.items())).replace('=','') if params else ""
95
+ signature = await self.sign_request(nonce, timestamp, query_params=query_string)
96
+ headers["sign"] = signature
97
+
98
+ response = self.session.get(endpoint, params=params, headers=headers)
99
+ response.raise_for_status()
100
+ return response.json()
101
+
102
+ async def _post_authenticated(self, endpoint: str, data: Dict[str, Any]) -> Dict[str, Any]:
103
+ timestamp = await self.create_timestamp()
104
+ nonce = await self._generate_nonce()
105
+
106
+ headers = {
107
+ "api-key": self.api_key,
108
+ "timestamp": timestamp,
109
+ "nonce": nonce,
110
+ "Content-Type": "application/json"
111
+ }
112
+
113
+ body_string = json.dumps(data, separators=(',', ':'))
114
+ signature = await self.sign_request(nonce, timestamp, body=body_string)
115
+ headers["sign"] = signature
116
+
117
+ response = self.session.post(endpoint, data=body_string, headers=headers)
118
+ logger.info(f"Response: {body_string} {response.json()}")
119
+ response.raise_for_status()
120
+ return response.json()
121
+
122
+ async def PlaceOrder(self, ticker, qty, price, side, positionId=0, tradeSide="OPEN",reduceOnly=False):
123
+ data = {
124
+ "side": side,
125
+ "orderType":"LIMIT",
126
+ "qty": qty,
127
+ "price": price,
128
+ "symbol": ticker,
129
+ "tradeSide":tradeSide,
130
+ "reduceOnly":reduceOnly,
131
+ "positionId":positionId
132
+ }
133
+ datajs = await self._post_authenticated(self.placeOrder_Url,data)
134
+ return datajs
135
+
136
+ async def FlashClose(self, positionId):
137
+ data = {
138
+ "positionId": positionId
139
+ }
140
+ datajs = await self._post_authenticated(self.flashClose_Url,data)
141
+ return datajs
142
+
143
+ async def CancelOrder(self, symbol, orderId):
144
+ data = {
145
+ "symbol": symbol,
146
+ "orderList":[{"orderId": orderId}]
147
+ }
148
+ datajs = await self._post_authenticated(self.cancelOrder_Url,data)
149
+ return datajs
150
+
151
+ async def GetTradeHistoryData(self):
152
+ tradeHistory=await self._get_authenticated(self.Trade_history_Url)
153
+ if tradeHistory['code']==0:
154
+ return tradeHistory['data']
155
+ else:
156
+ logger.info(tradeHistory['msg'])
157
+
158
+ async def GetPendingOrderData(self,dictparm={}):
159
+ orders=await self._get_authenticated(self.pending_order_url, dictparm)
160
+ if orders['code']==0:
161
+ return orders['data']
162
+ else:
163
+ logger.info(orders['msg'])
164
+
165
+ async def GetPendingPositionData(self, dictparm={}):
166
+ positions=await self._get_authenticated(self.pending_positions_URL, dictparm)
167
+ if positions['code']==0:
168
+ return positions['data']
169
+ else:
170
+ logger.info(positions['msg'])
171
+
172
+ async def GetPositionHistoryData(self, dictparm={}):
173
+ tradeHistory=await self._get_authenticated(self.position_history_Url, dictparm)
174
+ if tradeHistory['code']==0:
175
+ return tradeHistory['data']
176
+ else:
177
+ logger.info(tradeHistory['msg'])
178
+
179
+
180
+ async def GetportfolioData(self):
181
+ portfolio=await self._get_authenticated(self.account_Url, params={"marginCoin":"USDT"})
182
+ if portfolio['code']==0:
183
+ return portfolio['data']
184
+ else:
185
+ logger.info(portfolio['msg'])
186
+
187
+
188
+ async def GetTickerslastPrice(self, tickersStr):
189
+ try:
190
+ resp = self.session.get(self.ticker_Url+'?symbols='+tickersStr)
191
+ datajs = resp.json()
192
+ if datajs['code']==0:
193
+ return datajs['data']
194
+ except Exception as e:
195
+ stack = traceback.extract_stack()
196
+ function_name = stack[-2].name
197
+ logger.error(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
198
+
199
+ async def GetTickersPair(self, tickersStr):
200
+ try:
201
+ resp = self.session.get(self.ticker_pair_Url+'?symbols='+tickersStr)
202
+ datajs = resp.json()
203
+ if datajs['code']==0:
204
+ return datajs['data']
205
+ except Exception as e:
206
+ stack = traceback.extract_stack()
207
+ function_name = stack[-2].name
208
+ logger.error(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
209
+
210
+ async def GetTickerList(self, threshold, volume):
211
+ symbols=[]
212
+ try:
213
+ resp = self.session.get(self.ticker_Url)
214
+ datajs = resp.json()
215
+ for item in datajs["data"]:
216
+ if await self.is_near_high_of_day(float(item['last']), float(item['high']) ,threshold) and float(item['baseVol']) > volume:
217
+ symbols.append(item['symbol'])
218
+ if await self.is_near_low_of_day(float(item['last']), float(item['low']) ,threshold) and float(item['baseVol']) > volume:
219
+ symbols.append(item['symbol'])
220
+ #if float(item['baseVol']) > volume:
221
+ # symbols.append(item['symbol'])
222
+ return symbols
223
+ except Exception as e:
224
+ stack = traceback.extract_stack()
225
+ function_name = stack[-2].name
226
+ logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
227
+
228
+ async def GetTickerData(self):
229
+ try:
230
+ url = f'{self.ticker_Url}'
231
+ resp = self.session.get(url)
232
+ datajs = resp.json()
233
+ if datajs['code']==0:
234
+ return datajs['data']
235
+ except Exception as e:
236
+ stack = traceback.extract_stack()
237
+ function_name = stack[-2].name
238
+ logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
239
+
240
+ async def GetDepthData(self,symbol,limit):
241
+ try:
242
+ url = f'{self.depth_Url}?symbol={symbol}&limit={limit}'
243
+ resp = self.session.get(url)
244
+ datajs = resp.json()
245
+ if datajs['code']==0:
246
+ return datajs['data']
247
+ except Exception as e:
248
+ stack = traceback.extract_stack()
249
+ function_name = stack[-2].name
250
+ logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
251
+
252
+ async def GetKlineHistory(self, ticker, interval, limit):
253
+ data = []
254
+ lm=limit
255
+ current_unix_timestamp = int(time.time())
256
+ try:
257
+ while True:
258
+ url = f'{self.kline_Url}?symbol={ticker}&startTime={current_unix_timestamp}&interval={interval}&limit={lm}'
259
+ resp = self.session.get(url)
260
+ datajs = resp.json()
261
+ if len(datajs['data']) > 0:
262
+ current_unix_timestamp = str(int(datajs['data'][-1]['time']) + 1) # Adjust 'time' to match the appropriate key in your data
263
+ data.extend(datajs['data'])
264
+ lm=limit-len(data)
265
+ if len(data) >= limit:
266
+ break
267
+ else:
268
+ break
269
+ return data
270
+ except Exception as e:
271
+ stack = traceback.extract_stack()
272
+ function_name = stack[-2].name
273
+ logger.info(f"Function: {function_name}, {e}, {e.args}, {type(e).__name__}")
274
+
275
+ def __del__(self):
276
+ """Cleanup method to close the session"""
277
+ if hasattr(self, 'session'):
278
+ self.session.close()