我有一个使用PyQt5库制作的简单GUI窗口。
`
import sys, csv, time
from datetime import datetime
from time import strftime,localtime
import threading
import pandas as pd
import numpy as np
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QTextEdit, QInputDialog, QLineEdit
from PyQt5 import QtCore
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5 import uic
from trade import trade
from pyqtgraph import PlotWidget
import pyqtgraph as pg
from itertools import islice
class UpdateThread(QThread):
signal = pyqtSignal()
def __init__(self, gui):
QThread.__init__(self)
self.gui = gui
def run(self):
try:
# timer = pg.QtCore.QTimer()
# timer.timeout.connect(UI.update_plot(self))
# timer.start(50)
while(True):
self.signal.emit()
time.sleep(5)
except Exception as e:
print(e)
class UI(QMainWindow):
gui = None
p_l = 0.0
display_trades = ''
def __init__(self):
super(UI, self).__init__()
global gui
gui = uic.loadUi('rightside.ui', self)
self.initUI()
self.timer_thread = UpdateThread(gui)
self.timer_thread.signal.connect(self.update_plot)
self.timer_thread.start()
def initUI(self):
self.prices = self.read_prices()
trades = self.get_trades()
list_trade_prices = trades[0].values.tolist()
list_trade_sizes = trades[1].values.tolist()
list_trade_ids = trades[4].drop_duplicates().values.tolist()
as_floats = np.array(list_trade_prices).astype(np.float)
self.set_fields(self.prices)
gui.update_button.clicked.connect(self.on_click)
gui.cancel_button.clicked.connect(self.on_exit)
self.show()
def get_trades(self):
df = pd.DataFrame()
# Get 50 most recent trades
trades = islice(trade.get_product_trades(), 192)
for x in reversed(list(trades)):
# if x['trade_id'] > last_id:
if x['side'] == 'buy':
#more trades that hit the bid force price down
new_row = {0:x['price'], 1:x['size'], 2:1, 3:time.mktime(datetime.timetuple(datetime.now())), 4:x['trade_id']}
df = df.append(new_row, ignore_index=True)
bid_side = True
else:
#more trades that hit the offer force force price up
new_row = {0:x['price'], 1:x['size'], 2:0, 3:time.mktime(datetime.timetuple(datetime.now())), 4:x['trade_id']}
df = df.append(new_row, ignore_index=True)
df = df.drop_duplicates([4], keep='last')
return df
def update_plot(self):
global gui
#set results_chart
trades = UI.get_trades(self)
list_trade_prices = trades[0].values.tolist()
last_price = list_trade_prices[-1]
as_floats = np.array(list_trade_prices).astype(np.float)
gui.results.setText("{0:,.2f}".format(float(last_price)))
gui.results_chart.clear()
gui.results_chart.plot(as_floats)
gui.statusBar().showMessage('Connected')
self.monitor_prices(last_price)
prices = self.read_prices()
self.set_fields(prices)
def get_open_trades(self, btc):
sum_buys = 0.0
open_trades = []
if float(btc) != 0:
for i in trade.get_last_fills():
if i['side'] == 'buy':
sum_buys += float(i['size'])
open_trades.append([i['price'], i['size']])
if sum_buys >= float(btc):
break
return open_trades
def monitor_prices(self, last_price):
global gui
date_local = strftime("%A, %d %b %Y %H:%M:%S", localtime())
stop_enter_price = float(gui.enter_box.toPlainText())
usd = gui.usd_display.text().replace(',', '')
btc = gui.btc_display.text()
trade_amount = ''
if float(last_price) > stop_enter_price and stop_enter_price != 0.0:
if float(usd) > 10.00:
trade_amount = "{0:.2f}".format((float(usd)+(float(btc)*float(last_price)))*0.02718)
result = trade.buy_market(trade_amount)
gui.statusBar().showMessage(str(result))
gui.enter_box.setText('')
with open('stop_enter.txt', 'w') as enter:
enter.write('0.0')
with open('../trades/buys.csv','a') as buys:
writer = csv.writer(buys)
writer.writerow([date_local, last_price, trade_amount, result])
open_trades = self.get_open_trades(btc)
display_trades = ''
trade_amount = 0.0
total_amount = 0.0
STOP_RATE = 0.02
if len(open_trades) != 0:
highest_entry_price = float(open_trades[0][0])
lowest_entry_price = float(open_trades[0][0])
#find lowest price and set stop-loss 2% below that and increment it up
for i,j in enumerate(open_trades):
difference = (float(last_price) - float(open_trades[i][0]))*float(open_trades[i][1])
total_amount += difference
per_diff = str((float(last_price) - float(open_trades[i][0])) / float(open_trades[i][0]))
display_trades += f'{"{0:.3f}".format(float(per_diff)*100)}%\t'
gui.statusBar().showMessage(display_trades)
if highest_entry_price < float(open_trades[i][0]):
highest_entry_price = float(open_trades[i][0])
if lowest_entry_price > float(open_trades[i][0]):
lowest_entry_price = float(open_trades[i][0])
#1R
if float(per_diff) < -STOP_RATE:
if float(btc) > 0.001:
trade_amount = "{0:.8f}".format(float(j[1]))
response = trade.sell_market(trade_amount)
with open('stop_loss.txt', 'w') as enter:
enter.write('0.0')
gui.statusBar().showMessage(str(response))
if float(last_price) < float(gui.stop_box.toPlainText()):
if float(btc) > 0.001:
trade_amount = "{0:.8f}".format(float(btc))
response = trade.sell_market(trade_amount)
gui.statusBar().showMessage(str(response))
def on_click(self):
global gui
enter_price = gui.enter_box.toPlainText()
stop_price = gui.stop_box.toPlainText()
self.write_prices('stop_enter.txt', enter_price)
self.write_prices('stop_loss.txt', stop_price)
gui.statusBar().showMessage('Updated Successfully!')
time.sleep(1.618)
gui.statusBar().showMessage('')
def on_exit(self):
sys.exit(0)
def write_disk(self, date_local, current_price, trade_amount, note, response):
with open('../trades/sells.csv','a') as sells:
writer = csv.writer(sells)
writer.writerow([date_local, current_price, trade_amount, note, response])
def take_it(self, risk_reward, btc):
if float(btc) > 0.001:
response = trade.sell_market(btc)
# playsound(path+'/sounds/sellit.mp3')
write_disk(date_local, current_price, trade_amount, risk_reward, response)
def write_prices(self, file_name, price):
with open(file_name, 'w') as file:
file.write(price)
def set_fields(self, prices):
global gui, p_l
last_price_data = trade.get_last_price()
last_price = last_price_data['price']
last_fill_data = None
while(True):
last_fill_data = trade.get_last_fill()
if 'trade_id' in last_fill_data:
break
last_fill = '0.0'
if last_fill_data['side'] != 'sell':
last_fill = last_fill_data['price']
p_l = float(last_price) - float(last_fill)
gui.enter_box.setText(prices[0])
gui.stop_box.setText(prices[1])
gui.results.setText("{0:,.2f}".format(p_l))
gui.in_price.setText("{0:,.2f}".format(float(last_fill)))
gui.usd_display.setText("{0:,.2f}".format(float(trade.get_usd())))
gui.btc_display.setText("{0:,.8f}".format(float(trade.get_btc())))
def read_prices(self):
content = []
with open('stop_enter.txt', 'r') as enter:
stop_enter = enter.readlines()
content.append(stop_enter[0].rstrip())
with open('stop_loss.txt', 'r') as stop:
stop_loss = stop.readlines()
content.append(stop_loss[0].rstrip())
return content
app = QApplication(sys.argv)
ex = UI()
app.exec_()
`我不太了解qthreads以及如何使它们工作。并且建议将不胜感激。我只想Updatethread每2秒钟左右调用一次update_plot。以为这很简单,但是这让我头疼。感谢您对我的程序员朋友的帮助。
对于某些定时更新,最好使用QTimer
及其信号QTimer
:
timeout