Negociação quantitativa de ações Python (11) --- Use pyqt5 para construir uma página inicial de software de negociação de ações

Prefácio

Nos 10 posts anteriores do blog, apresentamos em detalhes o desenho de vários gráficos de ações e algoritmos de previsão de ações, mas há um ponto que é muito inconveniente, ou seja, toda vez que visualizamos os dados de um determinado estoque, também precisamos substitua ou altere o código. Isso inevitavelmente causará perda de tempo extra, então o que devemos fazer?

A resposta é simples, nós desenvolvemos diretamente um software de bolsa de valores por nós mesmos, obtemos nós mesmos os dados e os verificamos nós mesmos. Desta forma, desde que o código de estoque seja alterado todas as vezes, os dados podem ser atualizados e exibidos de maneira uniforme, o que é muito conveniente e conveniente. E blogueiros de interface de construção recomendam usar pyqt5. Afinal, a tecnologia Qt é usada na camada inferior. Atualmente, o desempenho do desenvolvimento de desktop ainda é o melhor em Qt.

Construir a estrutura geral da interface

Primeiro, precisamos construir a estrutura geral do software de negociação de ações, o código é o seguinte:

import sys
import qdarkstyle
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MyFrom(QMainWindow):
    def __init__(self, parent=None):
        super(MyFrom, self).__init__(parent=parent)
        self.setWindowTitle('星辰股票行情软件')
        self.resize(1100, 100)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    myUI = MyFrom()
    myUI.setWindowFlag(Qt.WindowMinimizeButtonHint)  # 禁止放大界面
    myUI.setFixedSize(myUI.width(), myUI.height())  # 静止拖拽放大界面
    myUI.show()
    sys.exit(app.exec_())

Aqui, definimos o nome e o tema do software de estoque e o tamanho da interface do software. , Mas todos nós sabemos que, de acordo com o gráfico de ações anterior, uma única interface certamente não pode acomodar tantos gráficos, então o que devo fazer?

Na verdade, pyqt5 nos fornece uma página de guia. Ao alternar as guias acima, podemos alternar a interface completamente sem pular para a interface. Vamos implementar a guia geral.

class MyFrom(QMainWindow):
    def __init__(self, parent=None):
        //...代码在上面
        self.init()

    def init(self):
        self.qTableWidget = QTabWidget()
        self.homeTab = QWidget()
        self.kTab2 = QWidget()
        self.otherTab = QWidget()
        self.qTableWidget.addTab(self.homeTab, "主页")
        self.qTableWidget.addTab(self.kTab2, "K线图")
        self.qTableWidget.addTab(self.otherTab, "龙虎榜")
        self.setCentralWidget(self.qTableWidget)

Aqui, criamos a guia QTabWidget, definimos o nome da subguia e configuramos a guia para a interface principal. Após a execução, o efeito exibido é conforme mostrado na figura abaixo:

Insira a descrição da imagem aqui

Topo da página inicial

O protótipo da estrutura geral é basicamente concluído com o código acima. Em seguida, precisamos preencher as páginas dessas subguias, por sua vez.

Primeiro, precisamos implementar nossa homepage. Para o software de ações em geral, existem vários índices de grande capitalização, como a exibição do índice da Bolsa de Valores de Xangai, das Bolsas de Valores de Xangai e Shenzhen e do Mercado de Empresas em Crescimento, bem como o gráfico de tendência de uma única ação. como os detalhes comerciais do estoque e assim por diante. Então, aqui chegamos primeiro ao modelo de layout, aqui usamos QGridView para dividir a interface em grades para o layout.

class MyFrom(QMainWindow):
    def init(self):
    	//...上面的代码
        self.init_hometab()

    def init_hometab(self):
        self.grid = QGridLayout()
        self.grid.setSpacing(5)
        ft = QFont()
        ft.setPointSize(26)
        ft.setBold(True)
        self.share_params = [QLabel() for x in range(10)]
        self.grid.addWidget(self.share_params[0], 0, 0, 2, 3)
        self.share_params[0].setFont(ft)
        self.share_params[0].setStyleSheet("color:yellow")
        self.grid.addWidget(self.share_params[1], 0, 3, 1, 2)
        self.share_params[1].setFont(ft)
        self.grid.addWidget(self.share_params[2], 0, 5)
        self.grid.addWidget(self.share_params[3], 0, 6)
        self.grid.addWidget(self.share_params[4], 0, 7)
        self.grid.addWidget(self.share_params[5], 1, 3)
        self.grid.addWidget(self.share_params[6], 1, 4)
        self.grid.addWidget(self.share_params[7], 1, 5)
        self.grid.addWidget(self.share_params[8], 1, 6)
        self.grid.addWidget(self.share_params[9], 1, 7)
        self.shareThread = ShareThread()
        self.shareThread.setValue("sh600690")
        self.shareThread._signal.connect(self.shareThread_callbacklog)
        self.shareThread.start()

        self.qListOne = ['上证指数', '深证成指', '创业板指', '科创50', '上证50', '中证500', '沪深300']  # 添加的数组数据
        self.plateThread = plateThread()
        self.plateThread._signal.connect(self.plateThread_callbacklog)
        self.plateThread.start()
        self.homeTab.setLayout(self.grid)

    def shareThread_callbacklog(self, shareList):
        isloss = float(shareList[5])
        i = 0
        for share_label, qlist in zip(self.share_params, shareList):
            if i == 1:
                share_label.setText(str(qlist))
                if isloss >= 0:
                    share_label.setStyleSheet("color:red")
                else:zh
                    share_label.setStyleSheet("color:rgb(0, 255, 0)")
            else:
                share_label.setText(str(qlist))
            i += 1

    def plateThread_callbacklog(self, urlList):
        i = 0
        one_QLabel = [QLabel() for x in range(7)]
        two_QLabel = [QLabel() for x in range(7)]
        for o_label, t_label, qlist, m_name in zip(one_QLabel, two_QLabel, urlList, self.qListOne):
            temp = qlist.split('"')[1].split(',')
            isloss = float(str(round(float(temp[2]), 2)))
            if isloss >= 0:
                o_label.setStyleSheet("color:red;font-size:14px")
                t_label.setStyleSheet("color:red;font-size:14px")
            else:
                o_label.setStyleSheet("color:rgb(0, 255, 0);font-size:14px")
                t_label.setStyleSheet("color:rgb(0, 255, 0);font-size:14px")
            o_label.setText(m_name)
            self.grid.addWidget(o_label, 0, 8 + i, 1, 1)
            t_label.setText(str(round(float(temp[1]), 2)))
            self.grid.addWidget(t_label, 1, 8 + i, 1, 1)
            i += 1

Quanto aos elementos da interface, o blogueiro não dirá muito. Existem 2 threads aqui, um usuário obtém os dados básicos do estoque, o outro usuário obtém o índice do setor, a classe de thread para obter os dados do estoque é a seguinte:

import time

from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
import requests

from utils import LYJutils

#股票详细数据获取线程
class ShareThread(QtCore.QThread):
    _signal = pyqtSignal(list)

    def __init__(self):
        super(ShareThread, self).__init__()

    def setValue(self, shareNumber):
        self.share_num = shareNumber

    def run(self):
        list = []
        while True:
            list.clear()
            baseUrl = 'http://hq.sinajs.cn/list=' + self.share_num
            temp = requests.get(baseUrl).text.split('"')[1].split(',')
            list.append(temp[0])# 股票的名称
            list.append(round(float(temp[3]), 2))# 当前股票价格
            list.append("高 " + str(round(float(temp[4]), 2)))# 当前股票最高价格
            list.append("开 " + str(round(float(temp[1]), 2)))# 股票开盘价格
            list.append("量比 " + LYJutils.str_of_num(float(temp[8])))# 当前股票量比
            list.append(str(round(float(temp[3]) - float(temp[2]), 2))) # 当前股票涨跌幅
            m_flo = (float(temp[3]) - float(temp[2])) / float(temp[2]) * 100.0
            list.append(str(round(m_flo, 2)) + "%") # 当前股票涨跌幅百分比
            list.append("低 " + str(round(float(temp[5]), 2)))# 当前股票最低价格
            list.append(temp[30])#交易日期
            list.append("金额 " + LYJutils.str_of_num(float(temp[9]))) # 股票成交金额
            self._signal.emit(list)
            time.sleep(10)

Isso retorna a lista da lista de dados detalhados do estoque e, em seguida, atribui o valor ao texto QLabel por meio da função de retorno de chamada shareThread_callbacklog. Ao mesmo tempo, aqui está um thread de loop perpétuo, com o objetivo de obter dados de transações em tempo real a cada 10 segundos.

A seguir, está nossa classe de rosca de placa:

import time

from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
import requests

#板块指数详细数据线程
class plateThread(QtCore.QThread):
    _signal = pyqtSignal(list)

    def __init__(self):
        super(plateThread, self).__init__()

    def run(self):
        list = []
        qListName = ['s_sh000001', 's_sz399001', 's_sz399006', 's_sh000688', 's_sh000016', 's_sh000905',
                     's_sh000300', ]  # 添加的数组数据
        while True:
            list.clear()
            baseUrl = 'http://hq.sinajs.cn/list='
            for index in qListName:
                url = baseUrl + index
                temp = requests.get(url).text
                list.append(temp)
            self._signal.emit(list)
            time.sleep(10)

A classe de segmento de seção é muito simples, e também é um loop sem fio para obter o índice de seção. Afinal, os dados de transação de estoque em tempo real que queremos colocar na página inicial, se você quiser atualizar mais rápido, você pode alterar o número de segundos sozinho.

Preste atenção especial à interface para obtenção do índice do setor: "http://hq.sinajs.cn/list={block code}". A interface de aquisição de ações é: "http://hq.sinajs.cn/list={stock code}". Como na postagem anterior do blog, você precisa adicionar sz ou sh antes do código de ações. No entanto, o código de seção é independente, você pode verificar as regras de código de seção acima por si mesmo.

Após a execução, o efeito é mostrado na figura abaixo:
Insira a descrição da imagem aqui

Esqueci de mencionar que toda aquisição em tempo real de dados de estoque de rede requer a criação de thread.Os programadores com experiência em desenvolvimento devem saber que tarefas demoradas não podem ser realizadas no thread principal (ou seja, a interface), caso contrário, ele irá congelar.

Acho que você gosta

Origin blog.csdn.net/liyuanjinglyj/article/details/113569709
Recomendado
Clasificación