股票历史查看工具

使用工具:

  • 使用PySide6制作界面UI
  • 使用Matplotlib下关于量化数据可视化Mplfinance库绘制K线图等信息
  • 使用Tushare、AKShare库获取实时交易数据以及历史数据
  • 使用tensorflow库,基于历史数据对未来走势进行预测
  • tuchare官方文档:https://tushare.pro/
  • akshare官方文档:https://akshare.akfamily.xyz/introduction.html
  • k线图绘制:https://blog.youkuaiyun.com/Shepherdppz/article/details/108205721

界面UI:

在这里插入图片描述

k线图UI:在这里插入图片描述

k线图绘制:

import numpy as np
import mplfinance as mpf
from stockData import get_realtime_quotes
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

class KLineChart:
    def __init__(self):
        pass

    def draw_chart(self, data, code, start_date, end_date):
        # 设置mplfinance的蜡烛颜色,up为阳线颜色,down为阴线颜色
        my_color = mpf.make_marketcolors(up='r',
                                         down='g',
                                         edge='inherit',
                                         wick='inherit',
                                         volume='inherit')
        # 设置图表的背景色
        my_style = mpf.make_mpf_style(marketcolors=my_color,
                                      figcolor='(0.82, 0.83, 0.85)',
                                      gridcolor='(0.82, 0.83, 0.85)')
        # 标题格式,字体为中文字体,颜色为黑色,粗体,水平中心对齐
        title_font = {'fontname': 'SimHei', 'size': '14', 'color': 'black', 'weight': 'bold', 'va': 'bottom',
                      'ha': 'center'}
        # 红色数字格式(显示开盘收盘价)粗体红色10号字
        large_red_font = {'fontname': 'Arial', 'size': '18', 'color': 'red', 'weight': 'bold', 'va': 'bottom'}
        # 绿色数字格式(显示开盘收盘价)粗体绿色18号字
        large_green_font = {'fontname': 'Arial', 'size': '18', 'color': 'green', 'weight': 'bold', 'va': 'bottom'}
        # 小数字格式(显示其他价格信息)粗体红色10号字
        small_red_font = {'fontname': 'Arial', 'size': '10', 'color': 'red', 'weight': 'bold', 'va': 'bottom'}
        # 小数字格式(显示其他价格信息)粗体绿色10号字
        small_green_font = {'fontname': 'Arial', 'size': '10', 'color': 'green', 'weight': 'bold', 'va': 'bottom'}
        # 标签格式,可以显示中文,普通黑色10号字
        normal_label_font = {'fontname': 'SimHei', 'size': '10', 'color': 'black', 'va': 'bottom', 'ha': 'right'}
        # 普通文本格式,普通黑色10号字
        normal_font = {'fontname': 'Arial', 'size': '10', 'color': 'black', 'va': 'bottom', 'ha': 'left'}

        last_data = get_realtime_quotes(code, start_date, end_date)
        fig = mpf.figure(
            style=my_style,
            figsize=(12, 8),  # 图表大小
            facecolor=(0.82, 0.83, 0.85),  # 图表背景色
        )
        ax1 = fig.add_axes([0.11, 0.25, 0.8, 0.60])
        ax2 = fig.add_axes([0.11, 0.15, 0.8, 0.10], sharex=ax1)
        ax1.set_ylabel('Price, MA:[5,10,20]', fontsize=8)
        ax2.set_ylabel('Volume', fontsize=8)

        # 在figure对象上添加文本对象,用于显示各种价格和标题
        fig.text(0.50, 0.94, f'{code} - 纳指ETF:', **title_font)
        fig.text(0.08, 0.90, '开/收:', **normal_label_font)
        fig.text(0.08, 0.89, f'{np.round(last_data["open"], 3)} / {np.round(last_data["close"], 3)}', **large_red_font)
        fig.text(0.14, 0.86, f'{last_data["change"]}', **small_red_font)
        fig.text(0.22, 0.86, f'[{np.round(last_data["pct_chg"], 2)}%]', **small_red_font)
        fig.text(0.1, 0.86, f'{last_data.name.date()}', **normal_label_font)
        fig.text(0.42, 0.90, '高:', **normal_label_font)
        fig.text(0.42, 0.90, f'{last_data["high"]}', **small_red_font)
        fig.text(0.42, 0.86, '低:', **normal_label_font)
        fig.text(0.42, 0.86, f'{last_data["low"]}', **small_green_font)
        fig.text(0.6, 0.90, '量(手):', **normal_label_font)
        fig.text(0.6, 0.90, f'{np.round(last_data["vol"] / 10000, 3)}', **normal_font)
        fig.text(0.6, 0.86, '额(千元):', **normal_label_font)
        fig.text(0.6, 0.86, f'{last_data["amount"]}', **normal_font)
        fig.text(0.80, 0.86, '昨收:', **normal_label_font)
        fig.text(0.80, 0.86, f'{last_data["pre_close"]}', **normal_font)

        try:
            mpf.plot(data,
                     ax=ax1,  # 显示K线图
                     volume=ax2,  # 显示成交量
                     type='candle',
                     style=my_style,
                     mav=(5, 10, 20),  # 显示均线
                     )
        except Exception as e:
            print(e)
        canvas = FigureCanvas(fig)
        return canvas  # 返回画布对象

错误信息窗口:

# 显示错误信息窗口(请填写完整信息)
from PySide6.QtWidgets import QMessageBox

# 显示错误信息窗口(填写正确信息)
def errorWindow_info():
    msgBox = QMessageBox()
    msgBox.setIcon(QMessageBox.Warning)
    msgBox.setText("请填写正确信息!")
    msgBox.setWindowTitle("提示")
    msgBox.setStandardButtons(QMessageBox.Ok)
    msgBox.exec_()

# 显示错误信息窗口(日期顺序错误)
def errorWindow_date():
    msgBox = QMessageBox()
    msgBox.setIcon(QMessageBox.Warning)
    msgBox.setText("请填写正确日期顺序!")
    msgBox.setWindowTitle("提示")
    msgBox.setStandardButtons(QMessageBox.Ok)
    msgBox.exec_()

数据获取

# 获取指定股票指定时间段的日线数据
def get_day_data(code, start_date, end_date):
    """
    获取指定股票指定时间段的日线数据
    """
    data = pro.daily(ts_code=code, start_date=start_date, end_date=end_date)
    if data.empty:
        data = pro.index_daily(ts_code=code, start_date=start_date, end_date=end_date)
    data.index = data.trade_date
    data = data.rename(index=pd.Timestamp)
    data.drop(columns=['ts_code', 'trade_date', 'pre_close', 'change', 'pct_chg', 'amount'], inplace=True)
    data.columns = ['open', 'high', 'low', 'close', 'volume']
    data.sort_index(inplace=True)
    return data


# 获取指定股票指定时间段的周线数据
def get_week_data(code, start_date, end_date):
    """
    获取指定股票指定时间段的周线数据
    """
    data = pro.weekly(ts_code=code, start_date=start_date, end_date=end_date)
    if data.empty:
        data = pro.index_weekly(ts_code=code, start_date=start_date, end_date=end_date)
    data.index = data.trade_date
    data = data.rename(index=pd.Timestamp)
    data.drop(columns=['ts_code', 'trade_date', 'pre_close', 'change', 'pct_chg', 'amount'], inplace=True)
    data.columns = ['open', 'high', 'low', 'close', 'volume']
    data.sort_index(inplace=True)
    return data

# 获取最后一天的实时行情数据
def get_realtime_quotes(code, start_date, end_date):
    """
    获取最后一天的实时行情数据
    """
    data = pro.daily(ts_code=code, start_date=start_date, end_date=end_date)
    if data.empty:
        data = pro.index_daily(ts_code=code, start_date=start_date, end_date=end_date)
    data.index = data.trade_date
    data = data.rename(index=pd.Timestamp)
    data.sort_index(inplace=True)
    return data.iloc[-1]

# 获取实时成交数据
def get_realtime_trades():
    stock = ak.stock_zh_a_spot_em()
    stock.index = stock['代码']
    stock = stock.drop(
        columns=['代码','序号', '涨跌额', '成交量', '成交额', '振幅', '最高', '最低', '量比', '换手率', '市盈率-动态',
                 '市净率',
                 '总市值', '流通市值', '涨速', '60日涨跌幅', '年初至今涨跌幅'])
    stock.columns = [ '名称', '最新价', '涨跌幅', '今开', '昨收', '5分钟涨跌']

    return stock.head(30)

模型预测:

import pandas as pd
import numpy as np
from stockData import get_day_data
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM
from sklearn.preprocessing import MinMaxScaler

def prediction_data(stock_code, start_date, end_date):
    data = get_day_data(stock_code, start_date, end_date)
    # 取最后30天的数据
    last_10_days = data[-30:]
    # 选择需要预测的列
    features = ['open', 'high', 'low', 'close', 'volume']
    scaler = MinMaxScaler()
    scaled_data = scaler.fit_transform(data[features])

    # 创建训练数据
    def create_dataset(data, time_step=1):
        X, Y = [], []
        for i in range(len(data) - time_step - 1):
            a = data[i:(i + time_step), :]
            X.append(a)
            Y.append(data[i + time_step, :])
        return np.array(X), np.array(Y)

    time_step = 10
    X, Y = create_dataset(scaled_data, time_step)

    # 构建LSTM模型
    model = Sequential()
    model.add(LSTM(50, return_sequences=True, input_shape=(time_step, len(features))))
    model.add(LSTM(50, return_sequences=False))
    model.add(Dense(len(features)))
    model.compile(optimizer='adam', loss='mean_squared_error')

    # 训练模型
    model.fit(X, # 输入
              Y, # 输出
              epochs=100, # 训练轮数
              batch_size=1, # 批处理大小
              verbose=2 # 显示训练过程
              )

    # 取最后10天的数据进行预测
    last_10_days_scaled = scaler.transform(last_10_days[features])
    X_test = np.array([last_10_days_scaled])

    # 预测未来15天的数据
    predictions = []
    for _ in range(15):
        pred = model.predict(X_test)
        predictions.append(pred[0])
        X_test = np.append(X_test[:, 1:, :], [[pred[0]]], axis=1)

    # 反归一化预测数据
    predictions = scaler.inverse_transform(predictions)

    # 将预测结果转换为DataFrame
    future_dates = pd.date_range(start=data.index[-1] + pd.Timedelta(days=1), periods=15, freq='D')
    predicted_data = pd.DataFrame(predictions, columns=features, index=future_dates)

    # # 合并历史数据和预测数据
    combined_data = pd.concat([last_10_days, predicted_data])
    return combined_data
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值