距离更新这个系统框架过了差不多半个多月了,在此期间学习了点基础知识,决定把这个系统分为三个.py文件,于是得到了如下效果图


这三个文件目前的思路是这样的:
main.py 负责总程序的运行
tk_window.py 负责窗口框架的设计
graphic.py 负责中间图形功能的实现
个人觉得这样分着文件写后面写功能开发的时候会方便很多,不会显得那么凌乱了,刚开始时觉得难在每个文件之间的变量共享问题,包括现在也是有点懵懵的,现在只能编写边巩固知识了。大体代码如下:
首先是main.py

import tk_window
import graphic

目前就这两句代码,要运行程序直接运行这个文件即可
然后是tk_window.py,窗口框架设计文件

import tkinter as tk
import graphicroot = tk.Tk()  # 创建主窗口
s = graphic.Show()  # Show实例化
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格式的图片文件在项目文件目录下# 构建上方菜单栏目框架
top_frame = tk.Frame(root, width=screenWidth, height=screenHeight, relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)
top_frame.pack(fill=tk.BOTH, side=tk.TOP, expand=0)# 构建底部状态栏目框架
bottom_frame = tk.Frame(root, width=screenWidth, height=screenHeight, relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)
bottom_frame.pack(fill=tk.BOTH, side=tk.BOTTOM, expand=0)# 构建左边功能栏目框架
left_frame = tk.Frame(root, width=screenWidth, height=screenHeight, relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)
left_frame.pack(fill=tk.BOTH, side=tk.LEFT, expand=0)# 构建右边信息栏目框架
right_frame = tk.Frame(root, width=screenWidth, height=screenHeight, relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)
right_frame.pack(fill=tk.BOTH, side=tk.RIGHT, expand=0)# 构建中间显示栏目框架
centre_frame = tk.Frame(root, width=screenWidth, height=screenHeight, relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)
centre_frame.pack(fill=tk.BOTH, expand=1)# 构建各个框架的标签或按钮
top_label = tk.Label(top_frame, text='菜单栏目', bd=1)
top_label.pack()bottom_label = tk.Label(bottom_frame, text='状态栏目', bd=1)
bottom_label.pack()right_label = tk.Label(right_frame, text='信息栏目', bd=1)
right_label.pack()left_button1 = tk.Button(left_frame, text='全景', bd=1, command=s.stockindex_function)
left_button1.pack()
left_button2 = tk.Button(left_frame, text='查询', bd=1, command=s.stock_query_function)
left_button2.pack()
left_button3 = tk.Button(left_frame, text='股票', bd=1, command=s.show_stocklist_function)
left_button3.pack()centre_label = tk.Label(centre_frame, text='显示栏目', bd=1)
centre_label.pack()root.mainloop()

最后是graphic.py, 中间图形框架功能设计

import pandas as pd
import tushare as ts
import mplfinance as mpf
import tkinter as tk
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  # 处理日期
import matplotlib as mpl  # 用于设置曲线参数
from cycler import cycler  # 用于定制线条颜色
import datetime
import tk_window
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
# 解决mplfinance绘制输出中文乱码
s = mpf.make_mpf_style(base_mpf_style='yahoo', rc={'font.family': 'SimHei'})
# 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')  # 显示居中class Show:def stockindex_function(self):# 必须添加以下控件销毁代码,不然点击一次按钮框架长生一次,显示的画面会多一次,你可以将下面的代码删除测试看下for widget_graphic_main_frame in tk_window.centre_frame.winfo_children():widget_graphic_main_frame.destroy()# 在右边窗口的graphic_main_frame框架下再创建窗口# opaqueresize该选项的值为 False,窗格的尺寸在用户释放鼠标的时候才更新到新的位置stockindex_information_window = tk.PanedWindow(tk_window.centre_frame, opaqueresize=False)stockindex_information_window.pack(fill=BOTH, expand=1)# 在company_information_window窗口下设置指数信息显示功能stockindex_text = tk.Text(stockindex_information_window, bg='white', undo=True, wrap=tix.CHAR)stockindex_information_window.add(stockindex_text, width=200)# 首先获取今天时间now_time = datetime.datetime.now()# 转化成tushare的时间格式strf_time = now_time.strftime('%Y%m%d')# 获取上交所上一个交易日日期,PS:tushare指数的数据信息好像当天只能获取上一个交易日的数据pre_trade_date = pro.trade_cal(exchange='SSE', is_open='1', start_date=strf_time, fields='pretrade_date')pre_trade_d = pre_trade_date.at[0, 'pretrade_date']# print(pre_trade_d)shsz_index_dailybasic = pro.index_dailybasic(trade_date=pre_trade_d, fields='ts_code,trade_date, ''total_mv,float_mv, total_share, ''float_share, free_share, ''turnover_rate, turnover_rate_f, ''pe, pb')sh_index_daily = pro.index_daily(ts_code='000001.SH', trade_date=pre_trade_d)sz_index_daily = pro.index_daily(ts_code='399001.SZ', trade_date=pre_trade_d)cy_index_daily = pro.index_daily(ts_code='399006.SZ', trade_date=pre_trade_d)zx_index_daily = pro.index_daily(ts_code='399005.SZ', trade_date=pre_trade_d)# print(sh_index_daily)# 数据处理,将ts_code作为索引,方便准确调用数据,保留两位小数shsz_index_dailybasic.set_index('ts_code', inplace=True)# 数据获取sh_total_mv = round(shsz_index_dailybasic.at['000001.SH', 'total_mv'] / 100000000, 2)  # 元转换成亿单位sh_float_mv = round(shsz_index_dailybasic.at['000001.SH', 'float_mv'] / 100000000, 2)sh_total_share = round(shsz_index_dailybasic.at['000001.SH', 'total_share'] / 10000000000, 2)  # 股转化成亿手sh_float_share = round(shsz_index_dailybasic.at['000001.SH', 'float_share'] / 10000000000, 2)sh_free_share = round(shsz_index_dailybasic.at['000001.SH', 'free_share'] // 10000000000, 2)sh_turnover_rate = shsz_index_dailybasic.at['000001.SH', 'turnover_rate']sh_pe = shsz_index_dailybasic.at['000001.SH', 'pe']sh_pb = shsz_index_dailybasic.at['000001.SH', 'pb']sh_close = sh_index_daily.at[0, 'close']sh_pre_close = sh_index_daily.at[0, 'pre_close']sh_pct_chg = sh_index_daily.at[0, 'pct_chg']sh_vol = round(sh_index_daily.at[0, 'vol'] / 100000000, 2)  # 手转化成亿手sh_amount = round(sh_index_daily.at[0, 'amount'] / 100000, 2)  # 千元转换成亿元# 数据调用# 在文本框第一行添加股票代码,文字红色,居中显示stockindex_text.insert(tk.INSERT, '上证指数')stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总市值(亿):')stockindex_text.insert(tk.INSERT, sh_total_mv)stockindex_text.tag_add('tag1', '1.0', '1.9')  # 设置选定的内容stockindex_text.tag_config('tag1', foreground='red', justify=CENTER)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通市值(亿):')stockindex_text.insert(tk.INSERT, sh_float_mv)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总股本(亿手):')stockindex_text.insert(tk.INSERT, sh_total_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通股本(亿手):')stockindex_text.insert(tk.INSERT, sh_float_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '自由流通股本(亿手):')stockindex_text.insert(tk.INSERT, sh_free_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '换手率:')stockindex_text.insert(tk.INSERT, sh_turnover_rate)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市盈率:')stockindex_text.insert(tk.INSERT, sh_pe)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市净率:')stockindex_text.insert(tk.INSERT, sh_pb)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '收盘点位:')stockindex_text.insert(tk.INSERT, sh_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '昨日收盘点:')stockindex_text.insert(tk.INSERT, sh_pre_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '涨跌幅(%):')stockindex_text.insert(tk.INSERT, sh_pct_chg)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交量(亿手):')stockindex_text.insert(tk.INSERT, sh_vol)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交额(亿):')stockindex_text.insert(tk.INSERT, sh_amount)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.tag_add('content1', '2.0', 'end')  # 设置选定的内容stockindex_text.tag_config('content1', foreground='blue')sz_total_mv = round(shsz_index_dailybasic.at['399001.SZ', 'total_mv'] / 100000000, 2)  # 转换成亿单位sz_float_mv = round(shsz_index_dailybasic.at['399001.SZ', 'float_mv'] / 100000000, 2)sz_total_share = round(shsz_index_dailybasic.at['399001.SZ', 'total_share'] / 10000000000, 2)  # 转化成亿手sz_float_share = round(shsz_index_dailybasic.at['399001.SZ', 'float_share'] / 10000000000, 2)sz_free_share = round(shsz_index_dailybasic.at['399001.SZ', 'free_share'] // 10000000000, 2)sz_turnover_rate = shsz_index_dailybasic.at['399001.SZ', 'turnover_rate']sz_pe = shsz_index_dailybasic.at['399001.SZ', 'pe']sz_pb = shsz_index_dailybasic.at['399001.SZ', 'pb']sz_close = sz_index_daily.at[0, 'close']sz_pre_close = sz_index_daily.at[0, 'pre_close']sz_pct_chg = sz_index_daily.at[0, 'pct_chg']sz_vol = round(sz_index_daily.at[0, 'vol'] / 100000000, 2)  # 手转化成亿手sz_amount = round(sz_index_daily.at[0, 'amount'] / 100000, 2)  # 千元转换成亿元stockindex_text.insert(tk.INSERT, '深证指数')stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总市值(亿):')stockindex_text.insert(tk.INSERT, sz_total_mv)stockindex_text.tag_add('tag2', '15.0', '15.9')  # 设置选定的内容,stockindex_text.tag_config('tag2', foreground='red', justify=CENTER)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通市值(亿):')stockindex_text.insert(tk.INSERT, sz_float_mv)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总股本(亿手):')stockindex_text.insert(tk.INSERT, sz_total_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通股本(亿手):')stockindex_text.insert(tk.INSERT, sz_float_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '自由流通股本(亿手):')stockindex_text.insert(tk.INSERT, sz_free_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '换手率:')stockindex_text.insert(tk.INSERT, sz_turnover_rate)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市盈率:')stockindex_text.insert(tk.INSERT, sz_pe)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市净率:')stockindex_text.insert(tk.INSERT, sz_pb)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '收盘点位:')stockindex_text.insert(tk.INSERT, sz_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '昨日收盘点:')stockindex_text.insert(tk.INSERT, sz_pre_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '涨跌幅(%):')stockindex_text.insert(tk.INSERT, sz_pct_chg)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交量(亿手):')stockindex_text.insert(tk.INSERT, sz_vol)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交额(亿):')stockindex_text.insert(tk.INSERT, sz_amount)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.tag_add('content2', '16.0', 'end')  # 设置选定的内容stockindex_text.tag_config('content2', foreground='DarkViolet')cy_total_mv = round(shsz_index_dailybasic.at['399006.SZ', 'total_mv'] / 100000000, 2)  # 转换成亿单位cy_float_mv = round(shsz_index_dailybasic.at['399006.SZ', 'float_mv'] / 100000000, 2)cy_total_share = round(shsz_index_dailybasic.at['399006.SZ', 'total_share'] / 10000000000, 2)  # 转化成亿手cy_float_share = round(shsz_index_dailybasic.at['399006.SZ', 'float_share'] / 10000000000, 2)cy_free_share = round(shsz_index_dailybasic.at['399006.SZ', 'free_share'] // 10000000000, 2)cy_turnover_rate = shsz_index_dailybasic.at['399006.SZ', 'turnover_rate']cy_pe = shsz_index_dailybasic.at['399006.SZ', 'pe']cy_pb = shsz_index_dailybasic.at['399006.SZ', 'pb']cy_close = sh_index_daily.at[0, 'close']cy_pre_close = cy_index_daily.at[0, 'pre_close']cy_pct_chg = cy_index_daily.at[0, 'pct_chg']cy_vol = round(cy_index_daily.at[0, 'vol'] / 100000000, 2)  # 手转化成亿手cy_amount = round(cy_index_daily.at[0, 'amount'] / 100000, 2)  # 千元转换成亿元stockindex_text.insert(tk.INSERT, '创业板指数')stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总市值(亿):')stockindex_text.insert(tk.INSERT, cy_total_mv)stockindex_text.tag_add('tag3', '29.0', '29.9')  # 设置选定的内容,stockindex_text.tag_config('tag3', foreground='red', justify=CENTER)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通市值(亿):')stockindex_text.insert(tk.INSERT, cy_float_mv)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总股本(亿手):')stockindex_text.insert(tk.INSERT, cy_total_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通股本(亿手):')stockindex_text.insert(tk.INSERT, cy_float_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '自由流通股本(亿手):')stockindex_text.insert(tk.INSERT, cy_free_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '换手率:')stockindex_text.insert(tk.INSERT, cy_turnover_rate)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市盈率:')stockindex_text.insert(tk.INSERT, cy_pe)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市净率:')stockindex_text.insert(tk.INSERT, cy_pb)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '收盘点位:')stockindex_text.insert(tk.INSERT, cy_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '昨日收盘点:')stockindex_text.insert(tk.INSERT, cy_pre_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '涨跌幅(%):')stockindex_text.insert(tk.INSERT, cy_pct_chg)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交量(亿手):')stockindex_text.insert(tk.INSERT, cy_vol)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交额(亿):')stockindex_text.insert(tk.INSERT, cy_amount)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.tag_add('content3', '30.0', 'end')  # 设置选定的内容stockindex_text.tag_config('content3', foreground='DarkCyan')zx_total_mv = round(shsz_index_dailybasic.at['399005.SZ', 'total_mv'] / 100000000, 2)  # 转换成亿单位zx_float_mv = round(shsz_index_dailybasic.at['399005.SZ', 'float_mv'] / 100000000, 2)zx_total_share = round(shsz_index_dailybasic.at['399005.SZ', 'total_share'] / 10000000000, 2)  # 转化成亿手zx_float_share = round(shsz_index_dailybasic.at['399005.SZ', 'float_share'] / 10000000000, 2)zx_free_share = round(shsz_index_dailybasic.at['399005.SZ', 'free_share'] // 10000000000, 2)zx_turnover_rate = shsz_index_dailybasic.at['399005.SZ', 'turnover_rate']zx_pe = shsz_index_dailybasic.at['399005.SZ', 'pe']zx_pb = shsz_index_dailybasic.at['399005.SZ', 'pb']zx_close = zx_index_daily.at[0, 'close']zx_pre_close = zx_index_daily.at[0, 'pre_close']zx_pct_chg = zx_index_daily.at[0, 'pct_chg']zx_vol = round(zx_index_daily.at[0, 'vol'] / 100000000, 2)  # 手转化成亿手zx_amount = round(zx_index_daily.at[0, 'amount'] / 100000, 2)  # 千元转换成亿元stockindex_text.insert(tk.INSERT, '中小板指数')stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总市值(亿):')stockindex_text.insert(tk.INSERT, zx_total_mv)stockindex_text.tag_add('tag4', '43.0', '43.9')  # 设置选定的内容,stockindex_text.tag_config('tag4', foreground='red', justify=CENTER)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通市值(亿):')stockindex_text.insert(tk.INSERT, zx_float_mv)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '总股本(亿手):')stockindex_text.insert(tk.INSERT, zx_total_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '流通股本(亿手):')stockindex_text.insert(tk.INSERT, zx_float_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '自由流通股本(亿手):')stockindex_text.insert(tk.INSERT, zx_free_share)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '换手率:')stockindex_text.insert(tk.INSERT, zx_turnover_rate)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市盈率:')stockindex_text.insert(tk.INSERT, zx_pe)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '市净率:')stockindex_text.insert(tk.INSERT, zx_pb)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '收盘点位:')stockindex_text.insert(tk.INSERT, zx_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '昨日收盘点:')stockindex_text.insert(tk.INSERT, zx_pre_close)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '涨跌幅(%):')stockindex_text.insert(tk.INSERT, zx_pct_chg)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交量(亿手):')stockindex_text.insert(tk.INSERT, zx_vol)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '成交额(亿):')stockindex_text.insert(tk.INSERT, zx_amount)stockindex_text.insert(tk.INSERT, '\n')stockindex_text.tag_add('content4', '44.0', 'end')  # 设置选定的内容stockindex_text.tag_config('content4', foreground='Sienna')stockindex_text.insert(tk.INSERT, '\n')stockindex_text.insert(tk.INSERT, '数据交易日期:')stockindex_text.insert(tk.INSERT, pre_trade_d)stockindex_text.tag_add('content5', '58.0', 'end')  # 设置选定的内容stockindex_text.tag_config('content5', foreground='Crimson')stockindex_window = tk.PanedWindow(orient='vertical', opaqueresize=False)stockindex_information_window.add(stockindex_window)# 创建显示上证指数的框架跟窗口stockindex_sh_frame = tk.Frame(stockindex_window, width=tk_window.screenWidth, height=tk_window.screenHeight,relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)stockindex_sh_frame.pack(fill=BOTH)stockindex_window.add(stockindex_sh_frame, height=tk_window.screenHeight / 2)# 创建显示深证指数的框架跟窗口stockindex_sz_frame = tk.Frame(stockindex_window, width=tk_window.screenWidth, height=tk_window.screenHeight,relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)stockindex_sz_frame.pack(fill=BOTH)stockindex_window.add(stockindex_sz_frame)for widget_stockindex_sh_frame in stockindex_sh_frame.winfo_children():widget_stockindex_sh_frame.destroy()for widget_stockindex_sz_frame in stockindex_sz_frame.winfo_children():widget_stockindex_sz_frame.destroy()for widget_stockindex_text in stockindex_text.winfo_children():widget_stockindex_text.destroy()# 上证指数index_data_sh = pro.index_daily(ts_code='000001.SH', start_date=20100101)# 日数据处理# :取所有行数据,后面取date列,open列等数据index_data_sh = index_data_sh.loc[:, ['trade_date', 'open', 'close', 'high', 'low', 'vol']]index_data_sh = index_data_sh.rename(columns={'trade_date': 'Date', 'open': 'Open', 'close': 'Close','high': 'High', 'low': 'Low', 'vol': 'Volume'})  # 更换列名,为后面函数变量做准备index_data_sh.set_index('Date', inplace=True)  # 设置date列为索引,覆盖原来索引,这个时候索引还是 object 类型,就是字符串类型。# 将object类型转化成 DateIndex 类型,pd.DatetimeIndex 是把某一列进行转换,同时把该列的数据设置为索引 index。index_data_sh.index = pd.DatetimeIndex(index_data_sh.index)index_data_sh = index_data_sh.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列# print(index_data_sh)# 设置marketcolors,up:设置K线线柱颜色,up意为收盘价大于等于开盘价,down:与up相反,这样设置与国内K线颜色标准相符# edge:K线线柱边缘颜色(i代表继承自up和down的颜色),wick:灯芯(上下影线)颜色,volume:成交量直方图的颜色,inherit:是否继承,选填sh_mc = mpf.make_marketcolors(up='red', down='green', edge='i', wick='i', volume='in', inherit=True)# 设置图形风格,gridaxis:设置网格线位置,gridstyle:设置网格线线型,y_on_right:设置y轴位置是否在右sh_s = mpf.make_mpf_style(gridaxis='both', gridstyle='-.', y_on_right=False, marketcolors=sh_mc)# 设置线宽mpl.rcParams['lines.linewidth'] = .5# 设置均线颜色,这里可以设置6条均线的颜色mpl.rcParams['axes.prop_cycle'] = cycler(color=['dodgerblue', 'deeppink', 'navy', 'teal', 'maroon', 'darkorange'])index_sh_fig, axlist = mpf.plot(index_data_sh, type='candle', mav=(5, 10, 20), volume=True, tight_layout=False,show_nontrading=False, returnfig=True, style=sh_s)canvas_index_sh = FigureCanvasTkAgg(index_sh_fig, master=stockindex_sh_frame)  # 设置tkinter绘制区canvas_index_sh.draw()toolbar_index_sh = NavigationToolbar2Tk(canvas_index_sh, stockindex_sh_frame)toolbar_index_sh.update()  # 显示图形导航工具条canvas_index_sh._tkcanvas.pack(fill=BOTH, expand=1)# 深圳指数index_data_sz = pro.index_daily(ts_code='399001.SZ', start_date=20100101)# 日数据处理# :取所有行数据,后面取date列,open列等数据index_data_sz = index_data_sz.loc[:, ['trade_date', 'open', 'close', 'high', 'low', 'vol']]index_data_sz = index_data_sz.rename(columns={'trade_date': 'Date', 'open': 'Open', 'close': 'Close','high': 'High', 'low': 'Low', 'vol': 'Volume'})  # 更换列名,为后面函数变量做准备index_data_sz.set_index('Date', inplace=True)  # 设置date列为索引,覆盖原来索引,这个时候索引还是 object 类型,就是字符串类型。# 将object类型转化成 DateIndex 类型,pd.DatetimeIndex 是把某一列进行转换,同时把该列的数据设置为索引 index。index_data_sz.index = pd.DatetimeIndex(index_data_sh.index)index_data_sz = index_data_sz.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列# print(index_data_sz)index_sz_fig, axlist = mpf.plot(index_data_sz, type='candle', mav=(5, 10, 20), volume=True, tight_layout=False,show_nontrading=False, returnfig=True)canvas_index_sz = FigureCanvasTkAgg(index_sz_fig, master=stockindex_sz_frame)  # 设置tkinter绘制区canvas_index_sz.draw()toolbar_index_sz = NavigationToolbar2Tk(canvas_index_sz, stockindex_sz_frame)toolbar_index_sz.update()  # 显示图形导航工具条canvas_index_sz._tkcanvas.pack(fill=BOTH, expand=1)def stock_query_function(self):# 必须添加以下控件销毁代码,不然点击一次按钮框架长生一次,显示的画面会多一次,你可以将下面的代码删除测试看下for widget_graphic_main_frame in tk_window.centre_frame.winfo_children():widget_graphic_main_frame.destroy()# 在主框架下创建股票代码输入子框架code_frame = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535')code_frame.pack()# 创建标签‘股票代码’stock_label = tk.Label(code_frame, text='股票代码', bd=1)stock_label.pack(side=LEFT)# 创建股票代码输入框input_code_var = tk.StringVar()code_widget = tk.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 = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535')input_date_frame.pack()# 创建标签‘开始日期’date_start_label = tk.Label(input_date_frame, text='开始日期', bd=1)date_start_label.pack(side=LEFT)# 创建开始日期代码输入框input_startdate_var = tk.StringVar()startdate_widget = tk.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 = tk.Label(input_date_frame, text='结束日期', bd=1)date_end_label.pack(side=LEFT)# 创建结束日期代码输入框input_enddate_var = tk.StringVar()enddate_widget = tk.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)# 创建Notebook标签选项卡tabControl = ttk.Notebook(tk_window.centre_frame)# 增加新选项卡日K线图stock_graphics_daily = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535', relief=tk.RAISED)# stock_graphics_daily.pack(expand=1, fill=tk.BOTH, anchor=tk.CENTER)stock_graphics_daily_basic = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535',relief=tk.RAISED)  # 增加新选项卡基本面指标stock_graphics_week = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535', relief=tk.RAISED)stock_graphics_month = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535', relief=tk.RAISED)company_information = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535', relief=tk.RAISED)tabControl.add(stock_graphics_daily, text='日K线图')  # 把新选项卡日K线框架增加到NotebooktabControl.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():  # 图形输出渲染# 以下函数作用是省略输入代码后缀.sz .shdef 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_stockcode# 清除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)  # 解决子图图形重叠问题# 周K线图形输出week_fig, axlist = mpf.plot(week_data, type='candle', mav=(5, 10, 20), volume=True,show_nontrading=False, returnfig=True)# 月k线图形输出month_fig, axlist = mpf.plot(month_data, type='candle', mav=(5, 10, 20), volume=True,show_nontrading=False, returnfig=True)# 将获得的图形渲染到画布上# 日K线图形渲染到tkinter画布上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)# 基本面指标图形渲染到tkinter画布上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()# 周K线图形渲染到tkinter画布上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)# 月K线图形渲染到tkinter画布上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_information框架下设置文字选项卡功能内容company_text = tk.Text(company_information, bg='white', undo=True, wrap=tix.CHAR)# 在文本框第一行添加股票代码,文字红色,居中显示company_text.insert(tk.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(tk.INSERT, '\n')company_text.insert(tk.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(tk.INSERT, '\n')company_text.insert(tk.INSERT, '    ')company_text.insert(tk.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(tk.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(tk.INSERT, '\n')company_text.insert(tk.INSERT, '    ')company_text.insert(tk.INSERT, '主要业务及产品:')company_text.tag_add('tag5', '4.4', '4.12')company_text.tag_config('tag5', foreground='blue')company_text.insert(tk.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(tk.INSERT, '\n')company_text.insert(tk.INSERT, '    ')company_text.insert(tk.INSERT, '经营范围:')company_text.tag_add('tag7', '5.4', '5.9')company_text.tag_config('tag7', foreground='#cc6600')company_text.insert(tk.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(tk.INSERT, '\n')company_text.pack(fill=BOTH, expand=1)# 在主框架下创建查询按钮子框架search_frame = tk.Frame(tk_window.centre_frame, borderwidth=1, bg='#353535', relief=tix.SUNKEN)search_frame.pack(before=tabControl)  # 必须加上before,否则控件则会出现在底部,除非tabControl设置了bottom布局属性# 创建查询按钮并设置功能stock_find = tk.Button(search_frame, text='查询', width=5, height=1, command=go)stock_find.pack()def show_stocklist_function(self):for widget_graphic_main_frame in tk_window.centre_frame.winfo_children():widget_graphic_main_frame.destroy()# 首先获取今天时间now_time = datetime.datetime.now()# 转化成tushare的时间格式strf_time = now_time.strftime('%Y%m%d')# 获取上交所上一个交易日日期,PS:tushare指数的数据信息好像当天只能获取上一个交易日的数据pre_trade_date = pro.trade_cal(exchange='SSE', is_open='1', start_date=strf_time, fields='pretrade_date')pre_trade_d = pre_trade_date.at[0, 'pretrade_date']# print(pre_trade_d)df_basic = pro.stock_basic(exchange='', list_status='L')  # 再获取所有股票的基本信息df_daily = pro.daily(trade_date=pre_trade_d)  # 先获得所有股票的行情数据,成交额单位是千元,成交量是手df_daily_basic = pro.daily_basic(ts_code='', trade_date=pre_trade_d,fields='ts_code, turnover_rate, turnover_rate_f,'' volume_ratio, pe, pe_ttm, pb, ps, ps_ttm,'' dv_ratio, dv_ttm, total_share, float_share,'' free_share, total_mv, circ_mv ')  # 获取每日指标,单位是万股,万元df_first = pd.merge(left=df_basic, right=df_daily, on='ts_code',how='outer')  # on='ts_code'以ts_code为索引,合并数据,how='outer',取并集df_all = pd.merge(left=df_first, right=df_daily_basic, on='ts_code', how='outer')# 数据清洗,删除symbol列数据,跟ts_code数据重复df_all = df_all.drop('symbol', axis=1)df_all = df_all[df_all['trade_date'].notna()]  # 删除当天不交易的股票df_all = df_all[df_all['list_date'].notna()]  # 删除退市或将要退市的股票for w in ['name', 'area', 'industry', 'market']:  # 在'name', 'area', 'industry', 'market'列内循环填充NaN值df_all[w].fillna('退市股', inplace=True)# print(type(df_all.at[1, 'pb']))# df_all['amount'] = df_all['amount'] / 100000  # 千转亿# df_all['circ_mv'] = df_all['circ_mv'] / 10000  # 万转亿# df_all['total_mv'] = df_all['total_mv'] / 10000  # 万转亿# 对获取的股票数据列名称进行重命名以方便阅读df_all = df_all.rename(columns={'ts_code': '股票代码', 'name': '股票名称', 'area': '所在地域', 'industry': '行业','market': '市场类型', 'list_date': '上市日期', 'trade_date': '交易日期','open': '开盘价', 'high': '最高价', 'low': '最低价', 'close': '收盘价','pre_close': '昨日价', 'change': '涨跌额', 'pct_chg': '涨跌幅','vol': '成交量(手)', 'amount': '成交额(千元)', 'turnover_rate': '换手率(%)','turnover_rate_f': '流通换手率', 'volume_ratio': '量比', 'pe': '市盈率','pe_ttm': '滚动市盈率', 'pb': '市净率', 'ps': '市销率', 'ps_ttm': '滚动市销率','dv_ratio': '股息率', 'dv_ttm': '滚动股息率', 'total_share': '总股本(万股)','float_share': '流通股本 (万股)', 'free_share': '自由流通股本(万股)','total_mv': '总市值 (万元)', 'circ_mv': '流通市值(万元)'})# 亏损的为空值# 先设置表的列名有哪些area = ('股票代码', '股票名称', '所在地域', '行业', '市场类型', '上市日期', '交易日期', '开盘价', '最高价', '最低价','收盘价', '昨日价', '涨跌额', '涨跌幅', '成交量(手)', '成交额(千元)', '换手率(%)', '流通换手率', '量比','市盈率', '滚动市盈率', '市净率', '市销率', '滚动市销率', '股息率', '滚动股息率', '总股本(万股)','流通股本 (万股)', '自由流通股本(万股)', '总市值 (万元)', '流通市值(万元)')stock_treeview = ttk.Treeview(tk_window.centre_frame, columns=area, show='headings')# 在treeview布局钱先布局横竖滚动条,不然会出现布局问题,你可以试着将滚动条代码放在最后试下VScroll1 = ttk.Scrollbar(tk_window.centre_frame, orient='vertical', command=stock_treeview.yview)stock_treeview.configure(yscrollcommand=VScroll1.set)VScroll1.pack(side=RIGHT, fill=Y)HScroll1 = ttk.Scrollbar(tk_window.centre_frame, orient='horizontal', command=stock_treeview.xview)stock_treeview.configure(xscrollcommand=HScroll1.set)HScroll1.pack(side=BOTTOM, fill=X)for i in range(len(area)):  # 命名列表名stock_treeview.column(area[i], width=70, anchor='center')stock_treeview.heading(area[i], text=area[i])stock_treeview.pack(fill=BOTH, expand=1)j = 0for i in range(len(df_all.index)):  # 导入插入股票数据stock_treeview.insert('', 'end', values=df_all.values[i].tolist())  # 插入的值数组格式转化成list格式,否则显示会多出‘跟[这种字符串# print(df_all.values[i].tolist())j += 1print('已经插入到第%s个股票了,请耐心等待' % j)def stock_treeview_sort(tv, col, reverse):  # Treeview、列名、排列方式try:# tv.set指定item,如果不设定column和value,则返回他们的字典,如果设定了column,则返回该column的value,如果value也设定了,则作相应更改。# get_children()函数,其返回的是treeview中的记录号# 参照网上的treeview排序方法函数,由于股票的价格排序数据类型是浮点数字,在排序钱将价格类型有str转换成float,否则排序会不正确stockdata_list = [(float(tv.set(k, col)), k) for k in tv.get_children('')]except Exception:stockdata_list = [(tv.set(k, col), k) for k in tv.get_children('')]# print(tv.get_children(''))# print(stockdata_list)stockdata_list.sort(reverse=reverse)  # 排序方式# rearrange items in sorted positions# 根据排序后索引移动,enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标for index, (val, k) in enumerate(stockdata_list):tv.move(k, '', index)# print(k)tv.heading(col, command=lambda col=col: stock_treeview_sort(tv, col, not reverse))  # 重写标题,使之成为再点倒序的标题for col in area:stock_treeview.column(col, width=70, anchor='center')stock_treeview.heading(col, text=col, command=lambda col=col: stock_treeview_sort(stock_treeview, col, False))# 创建选中股票显示K线图形功能函数def stock_k_show():for item in stock_treeview.selection():item_text = stock_treeview.item(item, "values")print(item_text[0])  # 输出所选行的第一列的值stock_kline_window = tk.Toplevel()stock_kline_window.geometry('{}x{}'.format(800, 600))code_name = item_text[0]start_date = '20150101'end_date = pre_trade_dstock_data = pro.daily(ts_code=code_name, start_date=start_date, end_date=end_date)print(stock_data)# :取所有行数据,后面取date列,open列等数据data = stock_data.loc[:, ['trade_date', 'open', 'close', 'high', 'low', 'vol']]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)  # 将时间顺序升序,符合时间序列fig, axlist = mpf.plot(data, title=item_text[1], type='candle', mav=(5, 10, 20), volume=True,show_nontrading=False, returnfig=True, style=s)canvas = FigureCanvasTkAgg(fig, master=stock_kline_window)  # 设置tkinter绘制区canvas.draw()toolbar = NavigationToolbar2Tk(canvas, stock_kline_window)toolbar.update()  # 显示图形导航工具条canvas._tkcanvas.pack(side=BOTTOM, fill=BOTH, expand=1)# 创建弹出菜单,为后面功能开发做准备stocklist_menu = tk.Menu(tk_window.centre_frame, tearoff=False)  # tearoff=True显示分割线stocklist_menu.add_command(label='K线图', command=stock_k_show)def pop(event):stocklist_menu.post(event.x_root, event.y_root)stock_treeview.bind('<Button-3>', pop)

目前就这么多,这次比上一次添加了股票列表功能,选中股票,然后右键鼠标弹出菜单,选择K线显示股票图标功能,还有排序的功能,同时也解决 了上一版本全景指数周日星期一不显示问题,看到这里如果你觉得可以麻烦给个赞,在思考解决问题的时候,头发好像掉了不少,哈哈哈

python 股票量化盘后分析系统 V0.3相关推荐

  1. python 股票量化盘后分析系统 V0.4

    前言: 思考了段时间,分析股票回测最终还是选择了backtrader,大体写了个框架,目前的效果图如下(后期还会改): 这次新添加了两个py文件,分别是stock_backtrader.py跟func ...

  2. python 股票量化盘后分析系统V0.42

    前言:先放效果图吧 开发的过程中因为知识水平有限,且对backtrader的各种不熟悉,相关的属性跟对象操作资料较少,实在写的很吃力,看官方那个API,水平有限,实在看得头晕. 效果图的图形输出用的是 ...

  3. python 股票量化盘后分析系统V0.45

    前言: 先放效果先吧: 一:这次更新主要是增加了策略文件这一功能,主要目的是为了方便切换策略测试.增添了弹出菜单新建策略.编辑.运行该策略.重命名.删除.刷新功能. 二:其中在点击回测是会在你项目的路 ...

  4. python 股票量化盘后分析系统V0.46

    前言: 就只更新了一个多股策略运行线程关闭功能按钮,由于添加了线程管理代码,多股回测的结果实时显示在tkinter,回测一个显示一个.只更改了stock_backtrader.py这个文件,其他不变. ...

  5. python 股票量化盘后分析系统V0.43

    前言: 先放效果图: 这次更新主要是增加了多股跟全市股票回测,策略方面还是跟上篇文章的一样,21日跟55日均线相交的策略.多股方面考虑到了均线的周期跟实际股票的数据数量是否适合问题,例如假设55日的均 ...

  6. python 金融量化盘后分析系统V0.48.5

    前言: 添加了多股回测结果导出CSV功能,点击回测结果导出将自动在项目的文件夹下自动创建 '策略结果' 文件夹,之后会根据你策略文件的名称在'策略结果'文件夹下再次创建一个以策略文件名命名的文件夹,最 ...

  7. python 金融量化盘后分析系统V0.5

    前言: 学习遇到瓶颈,暂停一段时间更新代码去充更多的电.目前写的这个系统,细节很多方面都没有处理好,比如回测模块的涨跌停处理,多股投资组合处理,代码的简洁优化等等方面,因为细节多,目前感觉无从下手,凌 ...

  8. 【python量化】ChatGPT4 实现股票量化盯盘系统

    如果你还不知道 ChatGPT 是什么 建议看这篇文章:ChatGPT 为什么这么火?它能干什么? 昨天,我,一个 python 小白,花了 2 个小时时间,让 ChatGPT4 帮我实现了一个股票量 ...

  9. 《Python股票量化交易从入门到实践》随书赠送“回测框架”的使用帮助

    点击:QTYX最新版本使用指南[文字版] 点击:QTYX最新版本使用指南[视频版] 点击: QTYX历史版本更新说明 赠送"回测框架"的目的 为了帮助读者再建立一座从书本知识到实战 ...

最新文章

  1. validating和validated的区别
  2. vivo android8公测,vivo 开启安卓P公测不限人数!这四款机型用户别错过了
  3. Spring4基础 学习笔记(3) ---- AOP(1) ---- 基于Xml
  4. 干货整理及PPT下载福利 2017(上海)人工智能产品经理大会
  5. php_connect_nonb,net2ftp无法显示文件列表输出为空
  6. LayaAir destroy 销毁与 removeChild 移除节点
  7. SIM900A常用指令
  8. plist文件详细说明
  9. 七、项目进度管理(二)【题】
  10. 一点笔记,好记性不如烂笔头
  11. android仿钉钉日程日历,Flutter仿钉钉考勤日历的示例代码
  12. 图片上的文字用CSS写出毛玻璃效果
  13. appium滑动操作(向上、向下、向左、向右滑动)
  14. 新员工碰到新问题 公司论坛帮解决
  15. MOSFET是什么器件,它的作用是什么
  16. 分享一篇我很喜欢的文章《不破不立的哲学与个人成长》
  17. 快手集福气中国牛 2021快手集福卡活动规则
  18. 沁恒低功耗M0单片机CH579功耗低至0.2uA——带蓝牙USB以太网等接口
  19. android 对数标度 图库,对数标度
  20. RK3399+FPGA+MIPI 方案细节之subLVDS to MIPI处理

热门文章

  1. ArcGIS GA、RA环境搭建
  2. 列车运行图的编制原则是什么_铁道部关于列车运行图编制规则
  3. 修改视频音频图片文件MD5软件教程傻瓜式操作
  4. OpenCV——归一化函数normalize
  5. Dapper官方文档(一)【介绍】
  6. 代码中mvc的注意事项
  7. 【STM32CubeMX】F103独立看门狗
  8. Android 基于MediaCodec开发抖音短视频录制(贰)
  9. 【综合案例】信用卡虚拟交易识别
  10. 用智能ABC输入不认识的汉字