Приложение на Flet Python для отображения актуальных цен с биржи Bybit

GetCoder.ru
Изображение статьи

Создание пользовательского интерфейса для отображения актуальных цен криптовалютных торговых пар с биржи Bybit с использованием библиотеки Flet.

Представленный код реализует графический пользовательский интерфейс (GUI) с помощью библиотеки Flet для отображения актуальных цен торговых пар с криптовалютной биржи Bybit. Код состоит из двух основных частей: класса для взаимодействия с WebSocket API биржи Bybit и функции для создания интерфейса с элементами управления.

Настройка проекта

Прежде чем мы начнем, убедитесь, что у вас установлены необходимые библиотеки:

  • copy
pip install websocket-client requests flet

Код

  • copy
# -*- coding: utf-8 -*- import flet as ft import time, websocket, json, threading, requests, re from functools import partial sybolsList = {} class bybit(): def __init__(self): try: self.mTickers = {} self.ticker_socket = {} self.start() except Exception as e: print(e) # Данные от сокета def on_message(self, _wsa, wsData, prm): varData = json.loads(wsData) if 'op' in varData: if varData['op'] == 'subscribe' and varData['success'] == False: mPairs = re.findall(r'\[([^]]*)\]', varData['ret_msg']) for elem in mPairs: del(self.ticker_socket[prm['key']]['listPair'][elem]) if len(self.ticker_socket[prm['key']]['listPair']) == 0: self.ticker_socket[prm['key']]['exit'] = 'true' self.ticker_socket[prm['key']]['status'] = 'off' _wsa.close() else: self.mTickers[varData['data']['symbol']] = varData['data'] # Отлов ошибок/выключения сокета def on_close(self, _wsa, wsData, prm): _wsa.close() self.ticker_socket[prm['key']]['status'] = 'off' # Открытие соединения def on_open(self, _wsa, prm): try: args = list(self.ticker_socket[prm['key']]['listPair'].values()) _wsa.send(json.dumps({"op": "subscribe", "args": args})) except Exception as e: _wsa.close() # Запуск сокета def runWebSockPl(self, key): while True: try: wss = 'wss://stream.bybit.com/v5/public/spot' wsa = websocket.WebSocketApp(wss, on_open = partial(self.on_open, prm={'key': key}), on_message = partial(self.on_message, prm={'key': key}), on_error = partial(self.on_close, prm={'key': key}), on_close = partial(self.on_close, prm={'key': key})) self.ticker_socket[key]['connect'] = wsa self.ticker_socket[key]['status'] = 'on' print(u'Установлено соединение Web Socket ключ '+key) wsa.run_forever() if self.ticker_socket[key]['exit'] == 'true': break raise Exception('Exit') except Exception as e: print(u'Разрыв соединения Web Socket ключ '+key) self.ticker_socket[key]['status'] = 'off' time.sleep(10) def start(self): response = requests.get("https://api.bybit.com/v5/market/instruments-info?category=spot") data = response.json() i = 1 listPair = {} for elem in data['result']['list']: listPair['tickers.'+elem['symbol']] = 'tickers.'+elem['symbol'] if len(listPair) >= 10: key = str(i) self.ticker_socket[key] = {'connect': '', 'status': 'off', 'exit': 'false', 'listPair': listPair} listPair = {} ws = threading.Thread(target=self.runWebSockPl, kwargs={'key': key}) ws.setDaemon(True) ws.start() i = i + 1 if len(listPair) > 0: key = str(i) self.ticker_socket[key] = {'connect': '', 'status': 'off', 'exit': 'false', 'listPair': listPair} ws = threading.Thread(target=self.runWebSockPl, kwargs={'key': key}) ws.setDaemon(True) ws.start() def main(page: ft.Page): # Генерация списка торговых пар def add_pairs(): response = requests.get("https://api.bybit.com/v5/market/instruments-info?category=spot") data = response.json() lv = ft.ListView(expand = 1, spacing = 10, padding = 10) rr = ft.ResponsiveRow([]) lastPrice = 0.00000000 for elem in data['result']['list']: var_text = ft.Text(elem['symbol']+' '+str(lastPrice)) var_elem = ft.Container( var_text, padding=5, col={"sm": 6, "md": 4, "xl": 2}, border = ft.border.all(1, ft.colors.PRIMARY) ) sybolsList[elem['symbol']] = {'container': var_elem, 'text': var_text, 'lastPrice': lastPrice} rr.controls.append(var_elem) lv.controls.append(rr) page.add(lv) page.update() # Филтрация списка def filter_proccess(e): serchVar = search.value.upper() for keyElem, dataElem in sybolsList.items(): sybolsList[keyElem]['container'].visible = False if serchVar in keyElem: sybolsList[keyElem]['container'].visible = True page.update() # Отмена фильтрации def clear_filter(e): search.value = '' for keyElem, dataElem in sybolsList.items(): sybolsList[keyElem]['container'].visible = True page.update() # Обновление торговых пар def update_price(): while True: time.sleep(1) for keyElem, dataElem in sybolsList.items(): sybolsList[keyElem]['container'].bgcolor = None for keyElem, dataElem in bb.mTickers.items(): if keyElem in sybolsList: sybolsList[keyElem]['text'].value = keyElem+' '+str(dataElem['lastPrice']) if float(dataElem['lastPrice']) > float(sybolsList[keyElem]['lastPrice']): sybolsList[keyElem]['container'].bgcolor = ft.colors.GREEN_700 if float(dataElem['lastPrice']) < float(sybolsList[keyElem]['lastPrice']): sybolsList[keyElem]['container'].bgcolor = ft.colors.RED sybolsList[keyElem]['lastPrice'] = float(dataElem['lastPrice']) page.update() search = ft.TextField(label="Поиск",on_change=filter_proccess) page.appbar = ft.AppBar( title=ft.Text("Bybit - торговые пары"), center_title=False, bgcolor=ft.colors.SURFACE_VARIANT, actions=[ ft.Container(search,padding=10), ft.IconButton( ft.icons.FILTER_ALT_OFF, icon_size=30, tooltip = "Отмена фильтра", on_click = clear_filter ) ], ) page.add() # Генерация списка торговых пар ws = threading.Thread(target=add_pairs) ws.setDaemon(True) ws.start() # Запуск ws bb = bybit() # Запуск обновления торговых пар ws = threading.Thread(target = update_price) ws.setDaemon(True) ws.start() ft.app(target=main)
Исходный код

Заключение

Данный код обеспечивает эффективный способ получения и отображения актуальных цен торговых пар с биржи Bybit в реальном времени с помощью библиотеки Flet. Комбинация REST API для первоначального получения списка торговых пар и WebSocket API для обновлений цен позволяет создать интерактивное и отзывчивое приложение.

  • 05.08.2024
  • 66
  • 0

Приложение на Flet Python для отображения актуальных цен с биржи Bybit

Представленный код реализует графический пользовательский интерфейс (GUI) с помощью библиотеки Flet для отображения актуальных цен торговых пар с криптовалютной биржи Bybit. Код состоит из двух основных частей: класса для взаимодействия с WebSocket API биржи Bybit и функции для создания интерфейса с элементами управления.

Настройка проекта

Прежде чем мы начнем, убедитесь, что у вас установлены необходимые библиотеки:

  • copy
pip install websocket-client requests flet

Код

  • copy
# -*- coding: utf-8 -*- import flet as ft import time, websocket, json, threading, requests, re from functools import partial sybolsList = {} class bybit(): def __init__(self): try: self.mTickers = {} self.ticker_socket = {} self.start() except Exception as e: print(e) # Данные от сокета def on_message(self, _wsa, wsData, prm): varData = json.loads(wsData) if 'op' in varData: if varData['op'] == 'subscribe' and varData['success'] == False: mPairs = re.findall(r'\[([^]]*)\]', varData['ret_msg']) for elem in mPairs: del(self.ticker_socket[prm['key']]['listPair'][elem]) if len(self.ticker_socket[prm['key']]['listPair']) == 0: self.ticker_socket[prm['key']]['exit'] = 'true' self.ticker_socket[prm['key']]['status'] = 'off' _wsa.close() else: self.mTickers[varData['data']['symbol']] = varData['data'] # Отлов ошибок/выключения сокета def on_close(self, _wsa, wsData, prm): _wsa.close() self.ticker_socket[prm['key']]['status'] = 'off' # Открытие соединения def on_open(self, _wsa, prm): try: args = list(self.ticker_socket[prm['key']]['listPair'].values()) _wsa.send(json.dumps({"op": "subscribe", "args": args})) except Exception as e: _wsa.close() # Запуск сокета def runWebSockPl(self, key): while True: try: wss = 'wss://stream.bybit.com/v5/public/spot' wsa = websocket.WebSocketApp(wss, on_open = partial(self.on_open, prm={'key': key}), on_message = partial(self.on_message, prm={'key': key}), on_error = partial(self.on_close, prm={'key': key}), on_close = partial(self.on_close, prm={'key': key})) self.ticker_socket[key]['connect'] = wsa self.ticker_socket[key]['status'] = 'on' print(u'Установлено соединение Web Socket ключ '+key) wsa.run_forever() if self.ticker_socket[key]['exit'] == 'true': break raise Exception('Exit') except Exception as e: print(u'Разрыв соединения Web Socket ключ '+key) self.ticker_socket[key]['status'] = 'off' time.sleep(10) def start(self): response = requests.get("https://api.bybit.com/v5/market/instruments-info?category=spot") data = response.json() i = 1 listPair = {} for elem in data['result']['list']: listPair['tickers.'+elem['symbol']] = 'tickers.'+elem['symbol'] if len(listPair) >= 10: key = str(i) self.ticker_socket[key] = {'connect': '', 'status': 'off', 'exit': 'false', 'listPair': listPair} listPair = {} ws = threading.Thread(target=self.runWebSockPl, kwargs={'key': key}) ws.setDaemon(True) ws.start() i = i + 1 if len(listPair) > 0: key = str(i) self.ticker_socket[key] = {'connect': '', 'status': 'off', 'exit': 'false', 'listPair': listPair} ws = threading.Thread(target=self.runWebSockPl, kwargs={'key': key}) ws.setDaemon(True) ws.start() def main(page: ft.Page): # Генерация списка торговых пар def add_pairs(): response = requests.get("https://api.bybit.com/v5/market/instruments-info?category=spot") data = response.json() lv = ft.ListView(expand = 1, spacing = 10, padding = 10) rr = ft.ResponsiveRow([]) lastPrice = 0.00000000 for elem in data['result']['list']: var_text = ft.Text(elem['symbol']+' '+str(lastPrice)) var_elem = ft.Container( var_text, padding=5, col={"sm": 6, "md": 4, "xl": 2}, border = ft.border.all(1, ft.colors.PRIMARY) ) sybolsList[elem['symbol']] = {'container': var_elem, 'text': var_text, 'lastPrice': lastPrice} rr.controls.append(var_elem) lv.controls.append(rr) page.add(lv) page.update() # Филтрация списка def filter_proccess(e): serchVar = search.value.upper() for keyElem, dataElem in sybolsList.items(): sybolsList[keyElem]['container'].visible = False if serchVar in keyElem: sybolsList[keyElem]['container'].visible = True page.update() # Отмена фильтрации def clear_filter(e): search.value = '' for keyElem, dataElem in sybolsList.items(): sybolsList[keyElem]['container'].visible = True page.update() # Обновление торговых пар def update_price(): while True: time.sleep(1) for keyElem, dataElem in sybolsList.items(): sybolsList[keyElem]['container'].bgcolor = None for keyElem, dataElem in bb.mTickers.items(): if keyElem in sybolsList: sybolsList[keyElem]['text'].value = keyElem+' '+str(dataElem['lastPrice']) if float(dataElem['lastPrice']) > float(sybolsList[keyElem]['lastPrice']): sybolsList[keyElem]['container'].bgcolor = ft.colors.GREEN_700 if float(dataElem['lastPrice']) < float(sybolsList[keyElem]['lastPrice']): sybolsList[keyElem]['container'].bgcolor = ft.colors.RED sybolsList[keyElem]['lastPrice'] = float(dataElem['lastPrice']) page.update() search = ft.TextField(label="Поиск",on_change=filter_proccess) page.appbar = ft.AppBar( title=ft.Text("Bybit - торговые пары"), center_title=False, bgcolor=ft.colors.SURFACE_VARIANT, actions=[ ft.Container(search,padding=10), ft.IconButton( ft.icons.FILTER_ALT_OFF, icon_size=30, tooltip = "Отмена фильтра", on_click = clear_filter ) ], ) page.add() # Генерация списка торговых пар ws = threading.Thread(target=add_pairs) ws.setDaemon(True) ws.start() # Запуск ws bb = bybit() # Запуск обновления торговых пар ws = threading.Thread(target = update_price) ws.setDaemon(True) ws.start() ft.app(target=main)
Исходный код

Заключение

Данный код обеспечивает эффективный способ получения и отображения актуальных цен торговых пар с биржи Bybit в реальном времени с помощью библиотеки Flet. Комбинация REST API для первоначального получения списка торговых пар и WebSocket API для обновлений цен позволяет создать интерактивное и отзывчивое приложение.