实时股票数据
接着上篇博文的内容,今天我们来实现获取与绘制实时的股票行情数据。首先,我们需要通过akshare库获取某一天的实时交易数据,具体代码如下所示:
import akshare as ak df = ak.stock_zh_a_tick_tx(code="sh600690", trade_date="20210203") df.to_excel("sh600690.xlsx")
获取之后,我们会得到如下数据:
其中,这里我们可以获取每3秒的股票实时交易变化的数据,同时获取当前交易是买盘还是卖盘,分别买卖多少手。当然,对于炒股新手来说,肯定有个东西很困惑,就是中性盘。在股票交易当中,按常规的逻辑我们不是卖,就是买,中性是个什么鬼?
其实,中性盘的意思是假如当前你挂委托单,卖出10手,而买盘当中,也有委托单,刚好也是10手,且两者价格一致,那么你们直接会匹配成交,这种交易叫做中性盘,可以理解为抵消掉了。
每笔交易详情数据
既然我们已经获取到了每日的股票交易详情数据,接下来要做的就是绘图,具体代码如下:
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()
运行之后,效果如下图所示:
绘制股票走势图与买卖盘数据
尽然我们已经知道了如何绘制走势图以及获取倒了买卖盘数据,那么根据上篇pyqt5的代码,我们将其加入到首页当中。具体代码如下所示:
# 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()
这里我们使用FigureCanvas将matplotlib绘制的图显示到界面之上,同时使用QTableWidget将买卖盘数据显示到界面上,注意买卖盘数据永远在底部,也就是最近的时间,所以需要通过scrollToBottom移动的低端。
下面,我们来看看绘图类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')
这里,我们绘制2个图,一个是股票交易图,一个是成交量分时图。代码很简单前面有介绍,这里就不在赘述。
接下来,我们需要获取这些数据方便其绘制:
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)
这里,我们是通过文件获取的数据,你也可以直接通过akshare获取,不过博主建议先获取网络数据,再获取文档数据,因为交易日15点以后,数据是没有变化的。这些免费的数据本来就延迟非常的高,保存在本地,在非交易时间段能加快获取数据的速度。
运行之后,显示的效果如下图所示:
软件资源代码下载地址:点击下载