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


Создание пользовательского интерфейса для отображения актуальных цен криптовалютных торговых пар с биржи Bybit с использованием библиотеки Flet.
Представленный код реализует графический пользовательский интерфейс (GUI) с помощью библиотеки Flet для отображения актуальных цен торговых пар с криптовалютной биржи Bybit. Код состоит из двух основных частей: класса для взаимодействия с WebSocket API биржи Bybit и функции для создания интерфейса с элементами управления.
Настройка проекта
Прежде чем мы начнем, убедитесь, что у вас установлены необходимые библиотеки:
pip install websocket-client requests flet
Код
# -*- 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 и функции для создания интерфейса с элементами управления.
Настройка проекта
Прежде чем мы начнем, убедитесь, что у вас установлены необходимые библиотеки:
pip install websocket-client requests flet
Код
# -*- 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 для обновлений цен позволяет создать интерактивное и отзывчивое приложение.