Comercio cuantitativo de acciones de Python (12) --- Utilice pyqt5 para crear una página de inicio de software de comercio de acciones

Datos de stock en tiempo real

Siguiendo el contenido del post anterior del blog, hoy realizaremos la adquisición y elaboración de datos bursátiles en tiempo real. Primero, necesitamos obtener datos de transacciones en tiempo real para un día determinado a través de la biblioteca de akshare. El código específico es el siguiente:

import akshare as ak
df = ak.stock_zh_a_tick_tx(code="sh600690", trade_date="20210203")
df.to_excel("sh600690.xlsx")

Después de obtenerlos, obtendremos los siguientes datos:
datos
Entre ellos, aquí podemos obtener los datos de los cambios de negociación de acciones en tiempo real cada 3 segundos, y al mismo tiempo obtener la transacción actual es una compra o venta, y cuántos lotes son comprado y vendido. Por supuesto, para los novatos en acciones, debe haber algo muy confuso, es decir, el mercado neutral. En el comercio de acciones, de acuerdo con la lógica convencional, o vendemos o compramos ¿Qué diablos es neutral?

De hecho, el pedido neutral significa que si actualmente realiza un pedido y vende 10 lotes, y también hay un pedido en la orden de compra, que resulta ser de 10 lotes, y los precios de los dos son iguales, entonces coincidir directamente con la transacción.Este tipo de transacción se denomina disco neutro, que puede entenderse como offset.

Datos detallados de cada transacción

Ahora que hemos obtenido los datos detallados de las transacciones diarias de stock, lo siguiente que debemos hacer es dibujar, el código específico es el siguiente:

df = pd.read_excel("sh600690.xlsx")
df['成交时间'] = pd.to_datetime(df['成交时间'])
df['成交时间'] = df['成交时间'].apply(lambda x: x.strftime('%H:%M'))
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
plt.rcParams['font.sans-serif'] = ['SimHei']
ax.plot(np.arange(0, len(df["成交时间"])), df["成交价格"])
ax.xaxis.set_major_locator(ticker.MaxNLocator(20))


def format_date(x, pos=None):
    if x < 0 or x > len(df['成交时间']) - 1:
        return ''
    return df['成交时间'][int(x)]


ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
ax.grid(True)
plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
plt.show()

Después de ejecutar, el efecto es como se muestra en la siguiente figura:
Datos de mercado en tiempo real

Dibujar gráfico de stock y datos de pedido

Aunque ya sabemos cómo dibujar un gráfico de tendencias y obtener los datos de las órdenes invertidas, luego de acuerdo con el código pyqt5 del artículo anterior, lo agregaremos a la página de inicio. El código específico es el siguiente:

# mian.py代码
def init_hometab(self):
	#第一篇代码
	self.mainThread = MainPlotThread()
    self.mainThread.setValue("sh600690")
    self.mainThread._signal.connect(self.mianThread_callbacklog)
    self.mainThread._orderList.connect(self.orderThread_callbacklog)
    self.mainThread.start()

def mianThread_callbacklog(self, df):
    mpl = StockMplCanvas(self, width=5, height=4, dpi=100)
    mpl.start_staict_plot(df)
    mpl_ntb = NavigationToolbar(mpl, self)
    mpl_ntb.setStyleSheet("background-color:white;color:black")

    self.grid.addWidget(mpl, 2, 0, 12, 12)
    self.grid.addWidget(mpl_ntb, 2, 0, 1, 5)

 # 指数显示模块
def tableWidget_connect(self, item):
    QMessageBox.information(self, "QTableWidget", "你选择了" + item.text())

def orderThread_callbacklog(self, urlList):
    ft = QFont()
    ft.setPointSize(10)
    ft.setBold(True)
    m_color = None
    j = 0
    if not self.isListView:
        self.tableWidget.clear()
        self.tableWidget.setHorizontalHeaderLabels(['性质', '成交量(手)', '成交额(元)'])
        for qlist in urlList:
            for index, m_dict in enumerate(qlist):
                if index == 0:
                    if str(m_dict).strip() == "买盘":
                        m_color = QColor(255, 0, 0)
                    elif str(m_dict).strip() == "卖盘":
                        m_color = QColor(0, 255, 0)
                    else:
                        m_color = QColor(255, 255, 255)
                newItem = QTableWidgetItem(str(m_dict))
                newItem.setFont(ft)
                newItem.setForeground(QBrush(m_color))
                self.tableWidget.setItem(j, index, newItem)
            j += 1
    else:
        # 各个板块指数
        self.tableWidget = QTableWidget(len(urlList), 3)
        self.tableWidget.setHorizontalHeaderLabels(['性质', '成交量(手)', '成交额(元)'])
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 不可编辑
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)  # 禁止拖拽
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)  # 只能选中一行
        self.tableWidget.itemClicked.connect(self.tableWidget_connect)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.setShowGrid(False)  # 不显示子线条
        self.tableWidget.setColumnWidth(0, 70)  # 设置第一列宽
        self.tableWidget.setColumnWidth(1, 70)  # 设置第二列宽
        self.tableWidget.setColumnWidth(2, 70)  # 设置第三列宽
        for qlist in urlList:
            for index, m_dict in enumerate(qlist):
                if index == 0:
                    if str(m_dict).strip() == "买盘":
                        m_color = QColor(255, 0, 0)
                    elif str(m_dict).strip() == "卖盘":
                        m_color = QColor(0, 255, 0)
                    else:
                        m_color = QColor(255, 255, 255)
                newItem = QTableWidgetItem(str(m_dict))
                newItem.setFont(ft)
                newItem.setForeground(QBrush(m_color))
                self.tableWidget.setItem(j, index, newItem)
            j += 1
        self.grid.addWidget(self.tableWidget, 2, 12, 12, 4)
        self.isListView = False
    self.tableWidget.scrollToBottom()

Aquí usamos FigureCanvas para mostrar el gráfico dibujado por matplotlib en la interfaz, y usamos QTableWidget para mostrar los datos del pedido en la interfaz. Tenga en cuenta que los datos del pedido están siempre en la parte inferior, que es la hora más reciente, por lo que debemos movernos el extremo inferior a través de scrollToBottom.

A continuación, echemos un vistazo a la clase de dibujo StockMplCanvas:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np

from matplotlib import gridspec
class StockMplCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        plt.rcParams['font.sans-serif'] = ['SimHei']
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        FigureCanvas.__init__(self, self.fig)
        spec = gridspec.GridSpec(2, 1, height_ratios=[2, 1])
        self.ax1 = self.fig.add_subplot(spec[0])
        self.ax2 = self.fig.add_subplot(spec[1])
        self.setParent(parent)

        FigureCanvas.updateGeometry(self)


    def start_staict_plot(self, df):
        df['成交时间'] = pd.to_datetime(df['成交时间'])
        df['成交时间'] = df['成交时间'].apply(lambda x: x.strftime('%H:%M'))
        self.ax1.plot(np.arange(0, len(df["成交时间"])), df["成交价格"], color='black')
        df_buy = np.where(df["性质"] == "买盘", df["成交量(手)"], 0)
        df_sell = np.where(df["性质"] == "卖盘", df["成交量(手)"], 0)
        self.ax1.set(ylabel=u"股价走势图")
        self.ax2.bar(np.arange(0, len(df)), df_buy, color="red")
        self.ax2.bar(np.arange(0, len(df)), df_sell, color="blue")
        self.ax2.set_ylim([0, df["成交量(手)"].max()/3])
        self.ax2.set(ylabel=u"成交量分时图")
        self.ax1.xaxis.set_major_locator(ticker.MaxNLocator(3))

        def format_date(x, pos=None):
            if x < 0 or x > len(df['成交时间']) - 1:
                return ''
            return df['成交时间'][int(x)]

        self.ax1.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
        self.ax1.grid(True)
        plt.setp(self.ax2.get_xticklabels(), visible=False)
        plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')

Aquí, dibujamos dos gráficos, uno es el gráfico de negociación de acciones y el otro es el gráfico de tiempo compartido del volumen de negociación. El código es muy simple. Lo he introducido antes, así que no lo repetiré aquí.

A continuación, necesitamos obtener estos datos para facilitar su dibujo:

import akshare as ak
import pandas as pd
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
from pandas import DataFrame

class MainPlotThread(QtCore.QThread):
    _signal = pyqtSignal(DataFrame)
    _orderList = pyqtSignal(list)
    def setValue(self, shareNumber):
        self.share_num = shareNumber

    def run(self):
        self.list = []
        df = pd.read_excel("sh600690.xlsx")
        self._signal.emit(df)
        self.list.clear()
        for index, row in df.iterrows():
            self.list.append([row['性质'], row['成交量(手)'], row['成交额(元)']])
        self._orderList.emit(self.list)

Aquí, obtenemos los datos a través de archivos. También puede obtenerlos directamente a través de akshare. Sin embargo, el blogger recomienda obtener primero los datos de la red y luego obtener los datos del documento, ya que los datos no han cambiado después de las 15:00 del día de negociación. Estos datos gratuitos tienen una latencia muy alta y se almacenan localmente, lo que puede acelerar la velocidad de adquisición de datos durante las horas no transaccionales.

Después de ejecutar, el efecto mostrado es como se muestra en la siguiente figura:
Datos de la transacción

Supongo que te gusta

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