python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)

本文主要是介绍python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:
这次比上次新添了公司信息内容跟一个股票基本面指标选项卡,股票基本面指标选项卡用的是matplotlib写的,采用plt.subplot2grid()子图写的,没写主图,在此期间遇到了无法标题中文话,一写就乱码,用过网上很多解决方法,目前也是无解,先记录,后面有时间再解决,如果你有解决方法请务必赐教,实在这个问题卡了我一天多了,如果单单是只用matplotlib输出图形,乱码问题网上的很多方法也是能够解决,我也不清楚究竟是我写的代码哪里跟中文显示冲突了,一时间代码也开始有点乱了,后面估计会越写越乱,等再写一两个功能抽个时间简洁下代码。更新的代码如下:

import pandas as pd
import tushare as ts
import mplfinance as mpf
import tkinter.tix as tix
from tkinter import ttk
import tkinter.font as tf
from tkinter.constants import *
import matplotlib.pyplot as plt
import matplotlib.dates as mdates    #處理日期
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)pro = ts.pro_api('要到tushare官网注册个账户然后将token复制到这里,可以的话请帮个忙用文章末我分享的链接注册,谢谢')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# pd.set_option()就是pycharm输出控制显示的设置
pd.set_option('expand_frame_repr', False)  # True就是可以换行显示。设置成False的时候不允许换行
pd.set_option('display.max_columns', None)  # 显示所有列
# pd.set_option('display.max_rows', None)  # 显示所有行
pd.set_option('colheader_justify', 'centre')  # 显示居中root = tix.Tk()  # 创建主窗口
screenWidth = root.winfo_screenwidth()  # 获取屏幕宽的分辨率
screenHeight = root.winfo_screenheight()
x, y = int(screenWidth / 4), int(screenHeight / 4)  # 初始运行窗口屏幕坐标(x, y),设置成在左上角显示
width = int(screenWidth / 2)  # 初始化窗口是显示器分辨率的二分之一
height = int(screenHeight / 2)
root.geometry('{}x{}+{}+{}'.format(width, height, x, y))  # 窗口的大小跟初始运行位置
root.title('Wilbur量化复盘分析软件')
# root.resizable(0, 0)  # 固定窗口宽跟高,不能调整大小,无法最大窗口化
root.iconbitmap('ZHY.ico')  # 窗口左上角图标设置,需要自己放张图标为icon格式的图片文件在项目文件目录下# 首先创建主框架
main_frame = tix.Frame(root, width=screenWidth, height=screenHeight,relief=tix.SUNKEN, bg='#353535', bd=5, borderwidth=4)
main_frame.pack(fill=BOTH, expand=0)# 在主框架下创建股票代码输入子框架
code_frame = tix.Frame(main_frame, borderwidth=1, bg='#353535')
code_frame.pack()
# 创建标签‘股票代码’
stock_label = tix.Label(code_frame, text='股票代码', bd=1)
stock_label.pack(side=LEFT)
# 创建股票代码输入框
input_code_var = tix.StringVar()
code_widget = tix.Entry(code_frame, textvariable=input_code_var, borderwidth=1, justify=CENTER)
# input_code_get = input_code_var.set(input_code_var.get())  # 获取输入的新值
code_widget.pack(side=LEFT, padx=4)# 在主框架下创建股票日期输入框子框架
input_date_frame = tix.Frame(main_frame, borderwidth=1, bg='#353535')
input_date_frame.pack()
# 创建标签‘开始日期’
date_start_label = tix.Label(input_date_frame, text='开始日期', bd=1)
date_start_label.pack(side=LEFT)
# 创建开始日期代码输入框
input_startdate_var = tix.StringVar()
startdate_widget = tix.Entry(input_date_frame, textvariable=input_startdate_var, borderwidth=1, justify=CENTER)
input_startdate_get = input_startdate_var.set(input_startdate_var.get())  # 获取输入的新值
startdate_widget.pack(side=LEFT, padx=4)
# 创建标签‘结束日期’
date_end_label = tix.Label(input_date_frame, text='结束日期', bd=1)
date_end_label.pack(side=LEFT)
# 创建结束日期代码输入框
input_enddate_var = tix.StringVar()
enddate_widget = tix.Entry(input_date_frame, textvariable=input_enddate_var, borderwidth=1, justify=CENTER)
input_enddate_get = input_enddate_var.set(input_enddate_var.get())  # 获取输入的新值
enddate_widget.pack(side=LEFT, padx=4)# 以下函数作用是省略输入代码后缀.sz .sh
def code_name_transform(get_stockcode):  # 输入的数字股票代码转换成字符串股票代码str_stockcode = str(get_stockcode)str_stockcode = str_stockcode.strip()  # 删除前后空格字符if 6 > len(str_stockcode) > 0:str_stockcode = str_stockcode.zfill(6) + '.SZ'  # zfill()函数返回指定长度的字符串,原字符串右对齐,前面填充0if len(str_stockcode) == 6:if str_stockcode[0:1] == '0':str_stockcode = str_stockcode + '.SZ'if str_stockcode[0:1] == '3':str_stockcode = str_stockcode + '.SZ'if str_stockcode[0:1] == '6':str_stockcode = str_stockcode + '.SH'return str_stockcodetabControl = ttk.Notebook(root)  # 创建Notebook
stock_graphics_daily = tix.Frame(root, borderwidth=1, bg='#353535', relief=tix.RAISED)  # 增加新选项卡日K线图
# stock_graphics_daily.pack(expand=1, fill=tk.BOTH, anchor=tk.CENTER)
stock_graphics_daily_basic = tix.Frame(root, borderwidth=1, bg='#353535', relief=tix.RAISED)  # 增加新选项卡基本面指标
stock_graphics_week = tix.Frame(root, borderwidth=1, bg='#353535', relief=tix.RAISED)
stock_graphics_month = tix.Frame(root, borderwidth=1, bg='#353535', relief=tix.RAISED)
company_information = tix.Frame(root, borderwidth=1, bg='#353535', relief=tix.RAISED)tabControl.add(stock_graphics_daily, text='日K线图')  # 把新选项卡日K线框架增加到Notebook
tabControl.add(stock_graphics_daily_basic, text='基本面指标')
tabControl.add(stock_graphics_week, text='周K线图')
tabControl.add(stock_graphics_month, text='月K线图')
tabControl.add(company_information, text='公司信息')
tabControl.pack(expand=1, fill="both")  # 设置选项卡布局
tabControl.select(stock_graphics_daily)  # 默认选定日K线图开始# 创建股票图形输出框架
def go():# 清除stock_graphics_daily框架中的控件内容,winfo_children()返回的项是一个小部件列表,# 以下代码作用是为每次点击查询按钮时更新图表内容,如果没有以下代码句,则每次点击查询会再生成一个图表for widget_daily in stock_graphics_daily.winfo_children():widget_daily.destroy()for widget_daily_basic in stock_graphics_daily_basic.winfo_children():widget_daily_basic.destroy()for widget_week in stock_graphics_week.winfo_children():widget_week.destroy()for widget_month in stock_graphics_month.winfo_children():widget_month.destroy()for widget_company_information in company_information.winfo_children():widget_company_information.destroy()stock_name = input_code_var.get()code_name = code_name_transform(stock_name)start_date = input_startdate_var.get()end_date = input_enddate_var.get()stock_data = pro.daily(ts_code=code_name, start_date=start_date, end_date=end_date)stock_daily_basic = pro.daily_basic(ts_code=code_name, start_date=start_date, end_date=end_date,fields='close,trade_date,turnover_rate,volume_ratio,pe,pb')stock_week_data = pro.weekly(ts_code=code_name, start_date=start_date, end_date=end_date)stock_month_data = pro.monthly(ts_code=code_name, start_date=start_date, end_date=end_date)stock_name_change = pro.namechange(ts_code=code_name, fields='ts_code,name')stock_information = pro.stock_company(ts_code=code_name, fields='introduction,main_business,business_scope')# 日数据处理data = stock_data.loc[:, ['trade_date', 'open', 'close', 'high', 'low', 'vol']]  # :取所有行数据,后面取date列,open列等数据data = data.rename(columns={'trade_date': 'Date', 'open': 'Open', 'close': 'Close', 'high': 'High', 'low': 'Low','vol': 'Volume'})  # 更换列名,为后面函数变量做准备data.set_index('Date', inplace=True)  # 设置date列为索引,覆盖原来索引,这个时候索引还是 object 类型,就是字符串类型。# 将object类型转化成 DateIndex 类型,pd.DatetimeIndex 是把某一列进行转换,同时把该列的数据设置为索引 index。data.index = pd.DatetimeIndex(data.index)data = data.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列# 基本面指标数据处理stock_daily_basic.set_index('trade_date', inplace=True)  # 设置date列为索引,覆盖原来索引,这个时候索引还是 object 类型,就是字符串类型。# 将object类型转化成 DateIndex 类型,pd.DatetimeIndex 是把某一列进行转换,同时把该列的数据设置为索引 index。stock_daily_basic.index = pd.DatetimeIndex(stock_daily_basic.index)stock_daily_basic = stock_daily_basic.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列print(stock_daily_basic)# 周数据处理week_data = stock_week_data.loc[:, ['trade_date', 'open', 'close', 'high', 'low', 'vol']]week_data = week_data.rename(columns={'trade_date': 'Date', 'open': 'Open', 'close': 'Close', 'high': 'High','low': 'Low', 'vol': 'Volume'})  # 更换列名,为后面函数变量做准备week_data.set_index('Date', inplace=True)  # 设置date列为索引,覆盖原来索引,这个时候索引还是 object 类型,就是字符串类型。# 将object类型转化成 DateIndex 类型,pd.DatetimeIndex 是把某一列进行转换,同时把该列的数据设置为索引 index。week_data.index = pd.DatetimeIndex(week_data.index)week_data = week_data.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列# 月数据处理month_data = stock_month_data.loc[:, ['trade_date', 'open', 'close', 'high', 'low', 'vol']]month_data = month_data.rename(columns={'trade_date': 'Date', 'open': 'Open', 'close': 'Close', 'high': 'High','low': 'Low', 'vol': 'Volume'})  # 更换列名,为后面函数变量做准备month_data.set_index('Date', inplace=True)  # 设置date列为索引,覆盖原来索引,这个时候索引还是 object 类型,就是字符串类型。# 将object类型转化成 DateIndex 类型,pd.DatetimeIndex 是把某一列进行转换,同时把该列的数据设置为索引 index。month_data.index = pd.DatetimeIndex(month_data.index)month_data = month_data.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列# 公司信息处理stock_company_code = stock_name_change.at[0, 'ts_code']stock_company_name = stock_name_change.at[0, 'name']stock_introduction = stock_information.at[0, 'introduction']stock_main_business = stock_information.at[0, 'main_business']stock_business_scope = stock_information.at[0, 'business_scope']# K线图图形输出daily_fig, axlist = mpf.plot(data, type='candle', mav=(5, 10, 20), volume=True,show_nontrading=False, returnfig=True)# 注意必须按照选项卡的排列顺序渲染图形输出,假如你把matplotlib的图形放到最后,则会出现图像错位现象,不信你可以把以下的代码放到month_fig后试下plt_stock_daily_basic = plt.figure(facecolor='white')plt.suptitle('Daily Basic Indicator', size=10)fig_close = plt.subplot2grid((3, 2), (0, 0), colspan=2)  # 创建网格子绘图,按行切分成3份,列切分成2分,位置(0,0),横向占用2列fig_close.set_title('Close Price')plt.xticks(stock_daily_basic.index, rotation=45)  # 设置x轴时间显示方向,放在这跟放在最后显示效果不一样fig_close.plot(stock_daily_basic.index, stock_daily_basic['close'])plt.xlabel('Trade Day')plt.ylabel('Close')plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))  # 設置x軸主刻度顯示格式(日期)plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=1))  # 設置x軸主刻度間距fig_turnover_rate = plt.subplot2grid((3, 2), (1, 0))  # 创建网格子绘图,按行切分成3份,列切分成2分,位置(1,0)fig_turnover_rate.set_title('Turnover Rate')plt.xticks(stock_daily_basic.index, rotation=45)  # 设置x轴时间显示方向,放在这跟放在最后显示效果不一样fig_turnover_rate.bar(stock_daily_basic.index, stock_daily_basic['turnover_rate'], facecolor='red')plt.xlabel('Trade Day')plt.ylabel('Turnover Rate')plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))  # 設置x軸主刻度顯示格式(日期)plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=2))  # 設置x軸主刻度間距fig_volume_ratio = plt.subplot2grid((3, 2), (2, 0))  # 创建网格子绘图,按行切分成3份,列切分成2分,位置(1,2)fig_volume_ratio.set_title('Volume Ratio')plt.xticks(stock_daily_basic.index, rotation=45)  # 设置x轴时间显示方向,放在这跟放在最后显示效果不一样fig_volume_ratio.bar(stock_daily_basic.index, stock_daily_basic['volume_ratio'])plt.xlabel('Trade Day')plt.ylabel('Volume Ratio')plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m'))  # 設置x軸主刻度顯示格式(日期)plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=2))  # 設置x軸主刻度間距fig_pe = plt.subplot2grid((3, 2), (1, 1))  # 创建网格子绘图,按行切分成3份,列切分成2分,位置在第3行,第1列fig_pe.set_title('PE')plt.xticks(stock_daily_basic.index, rotation=45)  # 设置x轴时间显示方向,放在这跟放在最后显示效果不一样fig_pe.plot(stock_daily_basic.index, stock_daily_basic['pe'])plt.xlabel('Trade Day')plt.ylabel('PE')plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m'))  # 設置x軸主刻度顯示格式(日期)plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=2))  # 設置x軸主刻度間距fig_pb = plt.subplot2grid((3, 2), (2, 1))  # 创建网格子绘图,按行切分成3份,列切分成2分,位置在第3行,第2列fig_pb.set_title('PB')plt.xticks(stock_daily_basic.index, rotation=45)  # 设置x轴时间显示方向,放在这跟放在最后显示效果不一样fig_pb.plot(stock_daily_basic.index, stock_daily_basic['pb'])plt.xlabel('Trade Day')plt.ylabel('PB')plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m'))  # 設置x軸主刻度顯示格式(日期)plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=2))  # 設置x軸主刻度間距plt_stock_daily_basic.tight_layout(h_pad=-2, w_pad=0)  # 解决子图图形重叠问题week_fig, axlist = mpf.plot(week_data, type='candle', mav=(5, 10, 20), volume=True,show_nontrading=False, returnfig=True)month_fig, axlist = mpf.plot(month_data, type='candle', mav=(5, 10, 20), volume=True,show_nontrading=False, returnfig=True)canvas_daily = FigureCanvasTkAgg(daily_fig, master=stock_graphics_daily)  # 设置tkinter绘制区canvas_daily.draw()toolbar_daily = NavigationToolbar2Tk(canvas_daily, stock_graphics_daily)toolbar_daily.update()  # 显示图形导航工具条canvas_daily._tkcanvas.pack(side=BOTTOM, fill=BOTH, expand=1)canvas_stock_daily_basic = FigureCanvasTkAgg(plt_stock_daily_basic, master=stock_graphics_daily_basic)canvas_stock_daily_basic.draw()toolbar_stock_daily_basic = NavigationToolbar2Tk(canvas_stock_daily_basic, stock_graphics_daily_basic)toolbar_stock_daily_basic.update()  # 显示图形导航工具条canvas_stock_daily_basic._tkcanvas.pack(side=BOTTOM, fill=BOTH, expand=1)plt.close()canvas_week = FigureCanvasTkAgg(week_fig, master=stock_graphics_week)  # 设置tkinter绘制区canvas_week.draw()toolbar_week = NavigationToolbar2Tk(canvas_week, stock_graphics_week)toolbar_week.update()  # 显示图形导航工具条canvas_week._tkcanvas.pack(side=BOTTOM, fill=BOTH, expand=1)canvas_month = FigureCanvasTkAgg(month_fig, master=stock_graphics_month)  # 设置tkinter绘制区canvas_month.draw()toolbar_month = NavigationToolbar2Tk(canvas_month, stock_graphics_month)toolbar_month.update()  # 显示图形导航工具条canvas_month._tkcanvas.pack(side=BOTTOM, fill=BOTH, expand=1)company_text = tix.Text(company_information, bg='white', undo=True, wrap=tix.CHAR)company_text.insert(tix.INSERT, stock_company_code)company_text.tag_add('tag1', '1.0', '1.9')company_text.tag_config('tag1', foreground='red', justify=CENTER)company_text.insert(tix.INSERT, '\n')company_text.insert(tix.INSERT, stock_company_name)company_text.tag_add('tag2', '2.0', '2.9')company_text.tag_config('tag2', foreground='red', justify=CENTER)company_text.insert(tix.INSERT, '\n')company_text.insert(tix.INSERT, '    ')company_text.insert(tix.INSERT, '公司简介:')company_text.tag_add('tag3', '3.3', '3.9')company_text.tag_config('tag3', foreground='red', font=tf.Font(family='SimHei', size=12))company_text.insert(tix.INSERT, stock_introduction)company_text.tag_add('tag4', '3.9', 'end')company_text.tag_config('tag4', foreground='black', spacing1=20, spacing2=10,font=tf.Font(family='SimHei', size=12))company_text.insert(tix.INSERT, '\n')company_text.insert(tix.INSERT, '    ')company_text.insert(tix.INSERT, '主要业务及产品:')company_text.tag_add('tag5', '4.4', '4.12')company_text.tag_config('tag5', foreground='blue')company_text.insert(tix.INSERT, stock_main_business)company_text.tag_add('tag6', '4.12', 'end')company_text.tag_config('tag6', spacing1=20, spacing2=10,font=tf.Font(family='SimHei', size=12))company_text.insert(tix.INSERT, '\n')company_text.insert(tix.INSERT, '    ')company_text.insert(tix.INSERT, '经营范围:')company_text.tag_add('tag7', '5.4', '5.9')company_text.tag_config('tag7', foreground='#cc6600')company_text.insert(tix.INSERT, stock_business_scope)company_text.tag_add('tag8', '5.9', 'end')company_text.tag_config('tag8', spacing1=20, spacing2=10,font=tf.Font(family='SimHei', size=12))company_text.insert(tix.INSERT, '\n')company_text.pack(fill=BOTH, expand=1)# 在主框架下创建查询按钮子框架
search_frame = tix.Frame(main_frame, borderwidth=1, bg='#353535', relief=tix.SUNKEN)
search_frame.pack()
# 创建查询按钮并设置功能
stock_find = tix.Button(search_frame, text='查询', width=5, height=1, command=go)
stock_find.pack()root.mainloop()

效果图:
在这里插入图片描述
在这里插入图片描述

tushare注册链接:点我注册tushare

这篇关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/266313

相关文章

Python判断for循环最后一次的6种方法

《Python判断for循环最后一次的6种方法》在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态... 目录1.使用enuhttp://www.chinasem.cnmerate()和len()来判断for

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用