bitunix-automated-crypto-trading 1.3.0__tar.gz → 1.4.0__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 (26) hide show
  1. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/PKG-INFO +1 -1
  2. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/bitunix_automated_crypto_trading.egg-info/PKG-INFO +1 -1
  3. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/bitunix_automated_crypto_trading.egg-info/SOURCES.txt +15 -0
  4. bitunix_automated_crypto_trading-1.4.0/bitunix_automated_crypto_trading.egg-info/entry_points.txt +2 -0
  5. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/setup.py +12 -10
  6. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/bitunix.py +74 -71
  7. bitunix_automated_crypto_trading-1.3.0/bitunix_automated_crypto_trading.egg-info/entry_points.txt +0 -2
  8. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/README.md +0 -0
  9. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/bitunix_automated_crypto_trading.egg-info/dependency_links.txt +0 -0
  10. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/bitunix_automated_crypto_trading.egg-info/requires.txt +0 -0
  11. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/bitunix_automated_crypto_trading.egg-info/top_level.txt +0 -0
  12. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/setup.cfg +0 -0
  13. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/AsyncThreadRunner.py +0 -0
  14. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/BitunixApi.py +0 -0
  15. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/BitunixSignal.py +0 -0
  16. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/BitunixWebSocket.py +0 -0
  17. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/DataFrameHtmlRenderer.py +0 -0
  18. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/NotificationManager.py +0 -0
  19. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/ResourceManager.py +0 -0
  20. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/ThreadManager.py +0 -0
  21. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/TickerManager.py +0 -0
  22. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/__init__.py +0 -0
  23. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/clearenv.py +0 -0
  24. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/config.py +0 -0
  25. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/logger.py +0 -0
  26. {bitunix_automated_crypto_trading-1.3.0 → bitunix_automated_crypto_trading-1.4.0}/src/sampleenv.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitunix_automated_crypto_trading
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Bitunix Futures Auto Trading Platform
5
5
  Home-page: https://github.com/tcj2001/bitunix-automated-crypto-trading
6
6
  Author: tcj2001
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitunix_automated_crypto_trading
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Bitunix Futures Auto Trading Platform
5
5
  Home-page: https://github.com/tcj2001/bitunix-automated-crypto-trading
6
6
  Author: tcj2001
@@ -1,5 +1,20 @@
1
1
  README.md
2
2
  setup.py
3
+ ./src/AsyncThreadRunner.py
4
+ ./src/BitunixApi.py
5
+ ./src/BitunixSignal.py
6
+ ./src/BitunixWebSocket.py
7
+ ./src/DataFrameHtmlRenderer.py
8
+ ./src/NotificationManager.py
9
+ ./src/ResourceManager.py
10
+ ./src/ThreadManager.py
11
+ ./src/TickerManager.py
12
+ ./src/__init__.py
13
+ ./src/bitunix.py
14
+ ./src/clearenv.py
15
+ ./src/config.py
16
+ ./src/logger.py
17
+ ./src/sampleenv.txt
3
18
  bitunix_automated_crypto_trading.egg-info/PKG-INFO
4
19
  bitunix_automated_crypto_trading.egg-info/SOURCES.txt
5
20
  bitunix_automated_crypto_trading.egg-info/dependency_links.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ bitunixautotrade = src.bitunix:main
@@ -1,7 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
  from setuptools.command.install import install
3
3
  import sys
4
- import os
5
4
  import urllib.request
6
5
  import subprocess
7
6
 
@@ -12,26 +11,28 @@ class CustomInstall(install):
12
11
  """Custom install class to download and install platform-specific wheels."""
13
12
  def run(self):
14
13
  # Detect the operating system
15
- if sys.platform.startswith('linux'):
14
+ platform = sys.platform
15
+ if platform.startswith('linux'):
16
16
  print("Linux detected. Downloading TA-Lib .deb package...")
17
17
  url = "https://github.com/ta-lib/ta-lib/releases/download/v0.6.4/ta-lib_0.6.4_amd64.deb"
18
18
  file_name = "ta-lib_0.6.4_amd64.deb"
19
19
  urllib.request.urlretrieve(url, file_name)
20
-
20
+
21
21
  # Install the .deb package
22
22
  subprocess.check_call(["sudo", "dpkg", "-i", file_name])
23
23
 
24
- elif sys.platform == "win32":
24
+ elif platform == "win32":
25
25
  print("Windows detected. Downloading TA-Lib .whl file...")
26
26
  url = "https://github.com/cgohlke/talib-build/releases/download/v0.6.3/ta_lib-0.6.3-cp313-cp313-win_amd64.whl"
27
27
  file_name = "ta_lib-0.6.3-cp313-cp313-win_amd64.whl"
28
28
  urllib.request.urlretrieve(url, file_name)
29
-
29
+
30
30
  # Install the .whl file
31
31
  subprocess.check_call([sys.executable, "-m", "pip", "install", file_name])
32
32
 
33
33
  else:
34
- print("Unsupported platform. Please manually install TA-Lib.")
34
+ # For macOS or other platforms
35
+ print(f"Unsupported platform: {platform}. Please manually install TA-Lib.")
35
36
 
36
37
  # Continue with the standard install process
37
38
  install.run(self)
@@ -40,21 +41,22 @@ class CustomInstall(install):
40
41
 
41
42
  setup(
42
43
  name="bitunix_automated_crypto_trading",
43
- version="1.3.0",
44
+ version="1.4.0",
44
45
  author="tcj2001",
45
46
  author_email="thomsonmathews@hotmail.com",
46
47
  description="Bitunix Futures Auto Trading Platform",
47
48
  long_description=long_description,
48
49
  long_description_content_type="text/markdown",
49
50
  url="https://github.com/tcj2001/bitunix-automated-crypto-trading",
50
- packages=find_packages(),
51
+ packages=find_packages(include=['src', 'src.*']),
52
+ package_dir={'': '.'},
51
53
  include_package_data=True,
52
54
  classifiers=[
53
55
  "Programming Language :: Python :: 3",
54
56
  "License :: OSI Approved :: MIT License",
55
57
  "Operating System :: OS Independent",
56
58
  ],
57
- python_requires=">=3.13",
59
+ python_requires=">=3.13", # Required for the TA-Lib wheel compatibility
58
60
  install_requires=[
59
61
  "fastapi",
60
62
  "uvicorn",
@@ -76,7 +78,7 @@ setup(
76
78
  ],
77
79
  entry_points={
78
80
  "console_scripts": [
79
- "bitunix-automated-crypto-trading=bitunix_automated_crypto_trading.bitunix:main",
81
+ "bitunixautotrade=src.bitunix:main",
80
82
  ],
81
83
  },
82
84
  cmdclass={
@@ -1,4 +1,4 @@
1
- import asyncio
1
+ import asyncio
2
2
  import os
3
3
  import uvicorn
4
4
  import numpy as np
@@ -48,29 +48,29 @@ settings = Settings()
48
48
  class bitunix():
49
49
  def __init__(self, password, api_key, secret_key, settings):
50
50
  self.screen_refresh_interval =settings.SCREEN_REFRESH_INTERVAL
51
-
51
+
52
52
  self.autoTrade=settings.AUTOTRADE
53
-
53
+
54
54
  self.threadManager = ThreadManager()
55
55
  self.notifications = NotificationManager()
56
56
  self.bitunixApi = BitunixApi(api_key, secret_key, settings)
57
57
  self.bitunixSignal = BitunixSignal(api_key, secret_key, settings, self.threadManager, self.notifications, self.bitunixApi)
58
-
58
+
59
59
  self.websocket_connections = set()
60
60
  self.DB = {"admin": {"password": password}}
61
-
61
+
62
62
  async def update_settings(self, settings):
63
63
  self.settings = settings
64
64
  await self.bitunixSignal.update_settings(settings)
65
65
  await self.bitunixApi.update_settings(settings)
66
66
 
67
- async def start(self):
67
+ async def start(self):
68
68
  await asyncio.create_task(self.bitunixSignal.load_tickers())
69
69
  await asyncio.create_task(self.bitunixSignal.start_jobs())
70
-
71
- async def restart(self):
70
+
71
+ async def restart(self):
72
72
  await asyncio.create_task(self.bitunixSignal.restart_jobs())
73
-
73
+
74
74
  async def send_message_to_websocket(self,message):
75
75
  async def send_to_all():
76
76
  for ws in self.bitunixSignal.websocket_connections:
@@ -80,7 +80,7 @@ class bitunix():
80
80
  async def send_async_message_to_websocket(self,message):
81
81
  for ws in self.bitunixSignal.websocket_connections:
82
82
  await ws.send_text(message)
83
-
83
+
84
84
  app = FastAPI()
85
85
  app.mount("/static", StaticFiles(directory="static"), name="static")
86
86
  app.add_middleware(
@@ -101,7 +101,7 @@ async def login(data: OAuth2PasswordRequestForm = Depends()):
101
101
  start=time.time()
102
102
  username = data.username
103
103
  password = data.password
104
-
104
+
105
105
  user = load_user(username, some_callable_object)
106
106
  if not user or password != user["password"]:
107
107
  raise InvalidCredentialsException
@@ -123,7 +123,7 @@ def load_user(username, some_callable=some_callable_object):
123
123
  async def get_private_endpoint(user=Depends(login_manager)):
124
124
  return "You are an authenticated user"
125
125
 
126
- @app.on_event("startup")
126
+ @app.on_event("startup")
127
127
  async def startup_event():
128
128
  await asyncio.create_task(get_server_states(app, settings))
129
129
  await bitunix.start()
@@ -156,18 +156,18 @@ async def set_server_states():
156
156
 
157
157
  if settings.AUTOTRADE:
158
158
  settings.OPTION_MOVING_AVERAGE = app.state.element_states['optionMovingAverage']
159
- settings.notifications.add_notification(f"optionMovingAverage: {settings.OPTION_MOVING_AVERAGE}")
159
+ settings.notifications.add_notification(f"optionMovingAverage: {settings.OPTION_MOVING_AVERAGE}")
160
160
 
161
161
  settings.PROFIT_AMOUNT = app.state.element_states['profitAmount']
162
- settings.notifications.add_notification(f"profitAmount: {settings.PROFIT_AMOUNT}")
162
+ settings.notifications.add_notification(f"profitAmount: {settings.PROFIT_AMOUNT}")
163
163
 
164
164
  settings.LOSS_AMOUNT = app.state.element_states['lossAmount']
165
- settings.notifications.add_notification(f"lossAmount: {settings.LOSS_AMOUNT}")
165
+ settings.notifications.add_notification(f"lossAmount: {settings.LOSS_AMOUNT}")
166
166
 
167
167
  settings.MAX_AUTO_TRADES = app.state.element_states['maxAutoTrades']
168
168
  settings.notifications.add_notification(f"maxAutoTrades: {settings.MAX_AUTO_TRADES}")
169
169
 
170
- settings.notifications.add_notification(" AutoTrade activated" if settings.AUTOTRADE else "AutoTrade de-activated")
170
+ settings.notifications.add_notification(" AutoTrade activated" if settings.AUTOTRADE else "AutoTrade de-activated")
171
171
 
172
172
 
173
173
  @app.post("/autotrade")
@@ -183,7 +183,7 @@ async def read_root(request: Request):
183
183
  @app.get("/main", response_class=HTMLResponse)
184
184
  async def main_page(request: Request, user=Depends(login_manager)):
185
185
  return templates.TemplateResponse({"request": request, "user": user}, "main.html")
186
-
186
+
187
187
  #when main page opened
188
188
  @app.websocket("/wsmain")
189
189
  async def websocket_endpoint(websocket: WebSocket):
@@ -191,33 +191,33 @@ async def websocket_endpoint(websocket: WebSocket):
191
191
 
192
192
  async def wsmain(websocket):
193
193
  query_params = websocket.query_params
194
-
194
+
195
195
  try:
196
196
  logger.info("local main page WebSocket connection opened")
197
-
197
+
198
198
  await websocket.accept()
199
199
  bitunix.websocket_connections.add(websocket)
200
200
 
201
201
  queue = asyncio.Queue()
202
- queueTask = asyncio.create_task(send_data_queue(websocket, queue))
202
+ queueTask = asyncio.create_task(send_data_queue(websocket, queue))
203
203
  while True:
204
204
  stime=time.time()
205
205
  data={}
206
206
  try:
207
-
207
+
208
208
  # Handle incoming ping messages
209
209
  await asyncio.create_task(send_pong(websocket,queue))
210
210
 
211
211
  #combined data
212
212
  dataframes={
213
- "portfolio" : bitunix.bitunixSignal.portfoliodfStyle,
214
- "positions" : bitunix.bitunixSignal.positiondfStyle,
213
+ "portfolio" : bitunix.bitunixSignal.portfoliodfStyle,
214
+ "positions" : bitunix.bitunixSignal.positiondfStyle,
215
215
  "orders" : bitunix.bitunixSignal.orderdfStyle,
216
216
  "signals" : bitunix.bitunixSignal.signaldfStyle,
217
217
  "study" : bitunix.bitunixSignal.allsignaldfStyle,
218
218
  "positionHistory" : bitunix.bitunixSignal.positionHistorydfStyle
219
219
  }
220
- notifications=bitunix.bitunixSignal.notifications.get_notifications()
220
+ notifications=bitunix.bitunixSignal.notifications.get_notifications()
221
221
 
222
222
  utc_time = datetime.fromtimestamp(bitunix.bitunixSignal.lastAutoTradeTime, tz=pytz.UTC)
223
223
  atctime = utc_time.astimezone(pytz.timezone('US/Central')).strftime('%Y-%m-%d %H:%M:%S')
@@ -239,19 +239,19 @@ async def wsmain(websocket):
239
239
  logger.info("local main page WebSocket connection closed")
240
240
  break
241
241
  except Exception as e:
242
- logger.info(f"local main page websocket unexpected error1: {e}")
243
- break
242
+ logger.info(f"local main page websocket unexpected error1: {e}")
243
+ break
244
244
 
245
245
  elapsed_time = time.time() - stime
246
-
246
+
247
247
  if settings.VERBOSE_LOGGING:
248
248
  logger.info(f"wsmain: elapsed time {elapsed_time}")
249
249
  time_to_wait = max(0.01, bitunix.screen_refresh_interval - elapsed_time)
250
-
250
+
251
251
  await asyncio.sleep(time_to_wait)
252
-
252
+
253
253
  except Exception as e:
254
- logger.info(f"local main page websocket unexpected error2: {e}")
254
+ logger.info(f"local main page websocket unexpected error2: {e}")
255
255
  finally:
256
256
  queueTask.cancel()
257
257
  try:
@@ -279,34 +279,34 @@ async def send_data_queue(websocket, queue):
279
279
  @app.get("/send-message/{msg}")
280
280
  async def send_message(msg: str):
281
281
  await asyncio.create_task(bitunix.send_message_to_websocket(msg))
282
- return {"message": f"Sent: {msg}"}
282
+ return {"message": f"Sent: {msg}"}
283
283
 
284
284
 
285
- @app.post("/handle_bitunix_click")
285
+ @app.post("/handle_bitunix_click")
286
286
  async def handle_bitunix_click(symbol: str = Form(...)):
287
- # Handle the row click event here
288
- message = f"https://www.bitunix.com/contract-trade/{symbol}"
289
- return {"message": message}
287
+ # Handle the row click event here
288
+ message = f"https://www.bitunix.com/contract-trade/{symbol}"
289
+ return {"message": message}
290
290
 
291
- @app.post("/handle_order_close_click")
291
+ @app.post("/handle_order_close_click")
292
292
  async def handle_order_close_click(symbol: str = Form(...), orderId: str = Form(...)):
293
293
  datajs = await bitunix.bitunixApi.CancelOrder(symbol, orderId)
294
294
  bitunix.bitunixSignal.notifications.add_notification(f'closing pending order for {symbol} {datajs["msg"]}')
295
295
 
296
- @app.post("/handle_close_click")
296
+ @app.post("/handle_close_click")
297
297
  async def handle_close_click(symbol: str = Form(...), positionId: str = Form(...), qty: str = Form(...), unrealizedPNL: str = Form(...), realizedPNL: str = Form(...)):
298
298
  datajs = await bitunix.bitunixApi.FlashClose(positionId)
299
299
  pnl=float(unrealizedPNL)+float(realizedPNL)
300
300
  bitunix.bitunixSignal.notifications.add_notification(f'closing {qty} {symbol} with a profit/loss of {pnl} ({datajs["code"]} {datajs["msg"]}')
301
301
 
302
- @app.post("/handle_buy_click")
302
+ @app.post("/handle_buy_click")
303
303
  async def handle_buy_click(symbol: str = Form(...), close: str = Form(...)):
304
304
  balance = bitunix.bitunixSignal.get_portfolio_tradable_balance()
305
305
  qty= str(balance * (float(settings.ORDER_AMOUNT_PERCENTAGE) / 100) / float(close) * int(settings.LEVERAGE))
306
306
  datajs = await bitunix.bitunixApi.PlaceOrder(symbol,qty,close,'BUY')
307
307
  bitunix.bitunixSignal.notifications.add_notification(f'Buying {qty} {symbol} @ {close} ({datajs["code"]} {datajs["msg"]})')
308
308
 
309
- @app.post("/handle_add_click")
309
+ @app.post("/handle_add_click")
310
310
  async def handle_add_click(symbol: str = Form(...), close: str = Form(...)):
311
311
  row = bitunix.bitunixSignal.positiondf.loc[bitunix.bitunixSignal.positiondf['symbol'] == symbol]
312
312
  if not row.empty:
@@ -315,14 +315,14 @@ async def handle_add_click(symbol: str = Form(...), close: str = Form(...)):
315
315
  datajs = await bitunix.bitunixApi.PlaceOrder(symbol,qty,close,row['side'].values[0])
316
316
  bitunix.bitunixSignal.notifications.add_notification(f'adding {row["side"].values[0]} {qty} {symbol} @ {close} ({datajs["code"]} {datajs["msg"]})')
317
317
 
318
- @app.post("/handle_sell_click")
318
+ @app.post("/handle_sell_click")
319
319
  async def handle_sell_click(symbol: str = Form(...), close: str = Form(...)):
320
320
  balance = bitunix.bitunixSignal.get_portfolio_tradable_balance()
321
321
  qty= str(balance * (float(settings.ORDER_AMOUNT_PERCENTAGE) / 100) / float(close) * int(settings.LEVERAGE))
322
322
  datajs = await bitunix.bitunixApi.PlaceOrder(symbol,qty,close,'SELL')
323
323
  bitunix.bitunixSignal.notifications.add_notification(f'Selling {qty} {symbol} @ {close} ({datajs["code"]} {datajs["msg"]})')
324
324
 
325
- @app.post("/handle_reduce_click")
325
+ @app.post("/handle_reduce_click")
326
326
  async def handle_reduce_click(symbol: str = Form(...), positionId: str = Form(...), qty: str = Form(...), close: str = Form(...)):
327
327
  row = bitunix.bitunixSignal.positiondf.loc[bitunix.bitunixSignal.positiondf['symbol'] == symbol]
328
328
  if not row.empty:
@@ -331,14 +331,14 @@ async def handle_reduce_click(symbol: str = Form(...), positionId: str = Form(..
331
331
  datajs = await bitunix.bitunixApi.PlaceOrder(symbol,qty,close,'BUY' if row['side'].values[0]=='SELL' else 'SELL',positionId=positionId, reduceOnly=True)
332
332
  bitunix.bitunixSignal.notifications.add_notification(f'reducing {row["side"]} {qty} {symbol} @ {close} ({datajs["code"]} {datajs["msg"]})')
333
333
 
334
- @app.post("/handle_charts_click")
334
+ @app.post("/handle_charts_click")
335
335
  async def handle_charts_click(symbol: str = Form(...)):
336
336
  chart_url = f"/charts?symbol={symbol}"
337
- return JSONResponse(content={"message": chart_url})
337
+ return JSONResponse(content={"message": chart_url})
338
338
 
339
339
  # when charts page requested (multiple period)
340
- @app.get("/charts", response_class=HTMLResponse)
341
- async def show_charts(request: Request, symbol: str):
340
+ @app.get("/charts", response_class=HTMLResponse)
341
+ async def show_charts(request: Request, symbol: str):
342
342
  return templates.TemplateResponse({"request": request, "data": symbol}, "charts.html")
343
343
 
344
344
  # when charts page opened (multiple period)
@@ -346,10 +346,10 @@ async def show_charts(request: Request, symbol: str):
346
346
  async def websocket_endpoint(websocket: WebSocket):
347
347
  await asyncio.create_task(wscharts(websocket))
348
348
 
349
- async def wscharts(websocket):
349
+ async def wscharts(websocket):
350
350
  query_params = websocket.query_params
351
351
  ticker = query_params.get("ticker")
352
-
352
+
353
353
  try:
354
354
  logger.info("local charts page WebSocket connection opened")
355
355
 
@@ -357,7 +357,7 @@ async def wscharts(websocket):
357
357
  bitunix.websocket_connections.add(websocket)
358
358
 
359
359
  queue = asyncio.Queue()
360
- queueTask = asyncio.create_task(send_data_queue(websocket, queue))
360
+ queueTask = asyncio.create_task(send_data_queue(websocket, queue))
361
361
 
362
362
  while True:
363
363
  stime=time.time()
@@ -365,7 +365,7 @@ async def wscharts(websocket):
365
365
 
366
366
  # Handle incoming ping messages
367
367
  await asyncio.create_task(send_pong(websocket,queue))
368
-
368
+
369
369
  if ticker in bitunix.bitunixSignal.tickerObjects.symbols():
370
370
  bars=settings.BARS
371
371
  chart1m=list(bitunix.bitunixSignal.tickerObjects.get(ticker).get_interval_ticks('1m').get_data()[-bars:])
@@ -391,10 +391,10 @@ async def wscharts(websocket):
391
391
  "macd_chart": settings.MACD_CHART,
392
392
  "bbm_study": settings.BBM_STUDY,
393
393
  "bbm_chart": settings.BBM_CHART,
394
- "rsi_study": settings.RSI_STUDY,
394
+ "rsi_study": settings.RSI_STUDY,
395
395
  "rsi_chart": settings.RSI_CHART,
396
396
  }
397
-
397
+
398
398
  await queue.put(json.dumps(data))
399
399
 
400
400
  except WebSocketDisconnect:
@@ -403,16 +403,16 @@ async def wscharts(websocket):
403
403
  break
404
404
  except Exception as e:
405
405
  logger.info(f"local charts page websocket unexpected error1: {e}")
406
- break
406
+ break
407
+
407
408
 
408
-
409
409
  elapsed_time = time.time() - stime
410
410
  if settings.VERBOSE_LOGGING:
411
411
  logger.info(f"wscharts: elapsed time {elapsed_time}")
412
412
  time_to_wait = max(0.01, bitunix.screen_refresh_interval - elapsed_time)
413
413
  await asyncio.sleep(time_to_wait)
414
414
  except Exception as e:
415
- logger.info(f"local charts page websocket unexpected error2: {e}")
415
+ logger.info(f"local charts page websocket unexpected error2: {e}")
416
416
  finally:
417
417
  queueTask.cancel()
418
418
  try:
@@ -421,19 +421,19 @@ async def wscharts(websocket):
421
421
  pass
422
422
 
423
423
  # when modal chart page requested (current period)
424
- @app.get("/chart", response_class=HTMLResponse)
424
+ @app.get("/chart", response_class=HTMLResponse)
425
425
  async def chart_page(request: Request):
426
426
  return templates.TemplateResponse("modal-chart.html", {"request": request})
427
-
427
+
428
428
  # when chart page opened (current period)
429
429
  @app.websocket("/wschart")
430
430
  async def websocket_endpoint(websocket: WebSocket):
431
431
  await asyncio.create_task(wschart(websocket))
432
432
 
433
- async def wschart(websocket):
433
+ async def wschart(websocket):
434
434
  query_params = websocket.query_params
435
435
  ticker = query_params.get("ticker")
436
-
436
+
437
437
  try:
438
438
  logger.info("local chart page WebSocket connection opened")
439
439
 
@@ -441,7 +441,7 @@ async def wschart(websocket):
441
441
  bitunix.websocket_connections.add(websocket)
442
442
 
443
443
  queue = asyncio.Queue()
444
- queueTask = asyncio.create_task(send_data_queue(websocket, queue))
444
+ queueTask = asyncio.create_task(send_data_queue(websocket, queue))
445
445
 
446
446
  while True:
447
447
  stime=time.time()
@@ -449,7 +449,7 @@ async def wschart(websocket):
449
449
 
450
450
  # Handle incoming ping messages
451
451
  await asyncio.create_task(send_pong(websocket,queue))
452
-
452
+
453
453
  if ticker in bitunix.bitunixSignal.tickerObjects.symbols():
454
454
  period=settings.OPTION_MOVING_AVERAGE
455
455
  bars=settings.BARS
@@ -468,10 +468,10 @@ async def wschart(websocket):
468
468
  "macd_chart": settings.MACD_CHART,
469
469
  "bbm_study": settings.BBM_STUDY,
470
470
  "bbm_chart": settings.BBM_CHART,
471
- "rsi_study": settings.RSI_STUDY,
471
+ "rsi_study": settings.RSI_STUDY,
472
472
  "rsi_chart": settings.RSI_CHART,
473
473
  }
474
-
474
+
475
475
  await queue.put(json.dumps(data))
476
476
 
477
477
  except WebSocketDisconnect:
@@ -480,16 +480,16 @@ async def wschart(websocket):
480
480
  break
481
481
  except Exception as e:
482
482
  logger.info(f"local chart page websocket unexpected error1: {e}")
483
- break
483
+ break
484
+
484
485
 
485
-
486
486
  elapsed_time = time.time() - stime
487
487
  if settings.VERBOSE_LOGGING:
488
488
  logger.info(f"wschart: elapsed time {elapsed_time}")
489
489
  time_to_wait = max(0.01, bitunix.screen_refresh_interval - elapsed_time)
490
490
  await asyncio.sleep(time_to_wait)
491
491
  except Exception as e:
492
- logger.info(f"local chart page websocket unexpected error2: {e}")
492
+ logger.info(f"local chart page websocket unexpected error2: {e}")
493
493
  finally:
494
494
  queueTask.cancel()
495
495
  try:
@@ -562,7 +562,7 @@ async def stream_log_file(websocket: WebSocket):
562
562
  # Determine starting point: offset_from_end
563
563
  start_index = max(len(lines) - 100, 0)
564
564
  for line in lines[start_index:]: # Yield existing lines from offset
565
- await websocket.send_text(line)
565
+ await websocket.send_text(line)
566
566
  # Stream new lines added to the file
567
567
  log_file.seek(0, 2) # Go to the end of the file
568
568
  while True:
@@ -570,21 +570,24 @@ async def stream_log_file(websocket: WebSocket):
570
570
  if not line:
571
571
  await asyncio.sleep(0.1) # Wait briefly if no new line is added
572
572
  continue
573
- await websocket.send_text(line)
573
+ await websocket.send_text(line)
574
574
  except WebSocketDisconnect:
575
575
  print("log Client disconnected. Stopping the log stream.")
576
576
 
577
-
578
- if __name__ == '__main__':
579
-
577
+
578
+ def main():
579
+ global bitunix
580
580
  bitunix = bitunix(PASSWORD, API_KEY, SECRET_KEY, settings)
581
581
  bitunix.bitunixSignal.notifications.add_notification(f"Starting....................")
582
582
  import uvicorn
583
583
  if settings.VERBOSE_LOGGING:
584
584
  llevel = "debug"
585
585
  else:
586
- llevel = "error"
586
+ llevel = "error"
587
587
  config1 = uvicorn.Config(app, host=HOST, port=8000, log_level=llevel, reload=False)
588
588
  server = uvicorn.Server(config1)
589
589
  server.run()
590
590
 
591
+ if __name__ == '__main__':
592
+ main()
593
+
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- bitunix-automated-crypto-trading = bitunix_automated_crypto_trading.bitunix:main