使用tkinter编写一个非常简单的获取股价程序(数据源tushare)
先看结果:
主界面。“获取股票信息”为更新信息按钮,“查询股票信息”为功能按钮
查询股票信息界面
点击查询后,输入起始终止时间,可以查看对应的价格,并绘制K线图
价格
K线图
实现方法:
- 安装tushare、tkinter、numpy、pandas、pylab、pyecharts
(在命令行中输入pip install tushare)
- 注册tushare账号,获得token。(本程序用到的tushare数据均为免费权限)
-
import os
import tushare as ts
import numpy as np
import pandas as pd
import tkinter as tk
import tkinter.messagebox
from pylab import mpl
from pyecharts.charts import Kline
# 解决画图无法显示中文
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
# tushare的token,相当于登录账号
token = 'xxx' # 此处输入你的token
ts.set_token(token)
pro = ts.pro_api(token)
# 主界面
window = tk.Tk()
window.title('股票信息程序')
window.geometry('500x300')
# basic为全局变量,记录股票基础信息
basic = pd.core.frame.DataFrame
# 获取股票基础信息函数,存储在basic里
def get_stock():
global basic
basic = pro.stock_basic(list_status='L')
tkinter.messagebox.showinfo(title='', message='已获取最新的股票信息!')
# 查询股票信息函数
def search_stock():
if basic.empty:
tkinter.messagebox.showinfo(title='', message='未获取股票信息!')
return
window_search = tk.Toplevel(window)
window_search.geometry('500x400')
window_search.title('搜索股票')
label_search = tk.Label(window_search, text='输入股票(部分)名称或代码\n例如:银行,SZ')
label_search.grid(row=0, column=0, pady=10)
e = tk.Entry(window_search, show=None)
e.grid(row=0, column=1, pady=10)
lb = tk.Listbox(window_search)
lb.grid(row=1, column=1)
label_tip1 = tk.Label(window_search, text='先在列表中选中某支股票\n再点击查询')
label_tip1.grid(row=1, column=0)
# 搜索股票功能
def vague_search():
lb.delete(0, "end")
# 获得输入框中的内容
var = e.get()
# 将basic中的代码和名称提取到basic3(list类型)中
basic2 = basic[['ts_code', 'name']]
basic2['new_col'] = basic2['ts_code'] + ' ' + basic2['name']
basic3 = np.array(basic2[['new_col']]).tolist()
result_list = []
search_success = False
for name in basic3:
if name[0].find(var) != -1:
result_list.append(name)
search_success = True
if not search_success:
tkinter.messagebox.showinfo(title='', message='不存在该名称或代码!')
for item in result_list:
lb.insert('end', item)
# 显示股票信息功能
def show_stock():
value_name = lb.get(lb.curselection())[0]
value = value_name[0:9]
window_info = tk.Toplevel(window_search)
window_info.geometry('500x300')
window_info.title(value_name)
label_time = tk.Label(window_info, text='请输入起始时间和终止时间,格式为年月日,例如:20200102')
label_time.place(x=100, y=10)
label_start = tk.Label(window_info, text='起始时间')
label_start.place(x=100, y=50)
label_end = tk.Label(window_info, text='终止时间')
label_end.place(x=100, y=100)
start_entry = tk.Entry(window_info, show=None)
start_entry.place(x=200, y=50)
end_entry = tk.Entry(window_info, show=None)
end_entry.place(x=200, y=100)
# 显示价格
def show_info():
s_date = start_entry.get()
e_date = end_entry.get()
if len(s_date) != 8 or len(e_date) != 8:
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(e_date[0:4]) > 2050:
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(s_date[4:6]) > 12 or int(e_date[4:6]) > 12:
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(s_date[6:8]) > 31 or (int(s_date[6:8]) > 30 and (
int(s_date[4:6]) == 2 or int(s_date[4:6]) == 4 or int(s_date[4:6]) == 6 or int(s_date[4:6]) == 9
or int(s_date[4:6]) == 11) or (int(s_date[6:8]) > 28 and int(s_date[4:6]) == 2)):
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(s_date) > int(e_date):
tkinter.messagebox.showinfo(title='', message='结束日期小于开始日期!')
return
elif int(e_date[0:4]) - int(s_date[0:4]) >= 10:
tkinter.messagebox.showinfo(title='', message='时间跨度长于十年!')
return
stock_data = pro.daily(ts_code=value, start_date=s_date, end_date=e_date)
stock_data.rename(columns={'ts_code': '代码', 'trade_date': '日期', 'open': '开盘价', 'high': '当日最高价',
'low': '当日最低价', 'close': '当日收盘价', 'pre_close': '昨日收盘价',
'change': '变动', 'pct_chg': '涨跌幅', 'vol': '当日成交量', 'amount': '成交金额'}, inplace=True)
stock_data.to_csv('价格/' + '价格 ' + value_name + ' ' + s_date + '到' + e_date + '.csv',
index=None, encoding='gb2312')
os.startfile('价格\\' + '价格 ' + value_name + ' ' + s_date + '到' + e_date + '.csv')
# 绘制K线图
def draw_kline():
s_date = start_entry.get()
e_date = end_entry.get()
if len(s_date) != 8 or len(e_date) != 8:
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(e_date[0:4]) > 2050:
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(s_date[4:6]) > 12 or int(e_date[4:6]) > 12:
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(s_date[6:8]) > 31 or (int(s_date[6:8]) > 30 and (
int(s_date[4:6]) == 2 or int(s_date[4:6]) == 4 or int(s_date[4:6]) == 6 or int(s_date[4:6]) == 9
or int(s_date[4:6]) == 11) or (int(s_date[6:8]) > 28 and int(s_date[4:6]) == 2)):
tkinter.messagebox.showinfo(title='', message='时间格式错误!')
return
elif int(s_date) > int(e_date):
tkinter.messagebox.showinfo(title='', message='结束日期小于开始日期!')
return
elif int(e_date[0:4]) - int(s_date[0:4]) >= 10:
tkinter.messagebox.showinfo(title='', message='时间跨度长于十年!')
return
stock_data = pro.daily(ts_code=value, start_date=s_date, end_date=e_date)
stock_data.index = pd.to_datetime(stock_data.trade_date)
stock_data = stock_data.sort_index()
v1 = list(stock_data.loc[:, ['open', 'close', 'low', 'high']].values)
v0 = list(stock_data.index.strftime('%Y%m%d'))
kline = Kline(value_name, title_text_size=15)
kline.add("", v0, v1, is_datazoom_show=True,
mark_line=["average"],
mark_point=["max", "min"],
mark_point_symbolize=60,
mark_line_valuedim=['highest', 'lowest'])
kline.render('K线图/' + 'K线图 ' + value_name + ' ' + s_date + '到' + e_date + '.html')
os.startfile('K线图\\' + 'K线图 ' + value_name + ' ' + s_date + '到' + e_date + '.html')
kline_button = tk.Button(window_info, text='绘制K线图', width=10, height=2, command=draw_kline)
kline_button.place(x=250, y=180)
info_button = tk.Button(window_info, text='显示价格', width=10, height=2, command=show_info)
info_button.place(x=150, y=180)
b1 = tk.Button(window_search, text='搜索', width=5, height=1, command=vague_search)
b1.grid(row=0, column=2)
b2 = tk.Button(window_search, text='查询', width=10, height=2, command=show_stock)
b2.grid(row=2, column=1)
# 获取股票信息按钮
get_stock_button = tk.Button(window, text='获取股票信息', width=20, height=2, command=get_stock)
get_stock_button.place(x=175, y=40)
# 查询股票信息按钮
search_stock_button = tk.Button(window, text='查询股票信息', width=20, height=2, command=search_stock)
search_stock_button.place(x=175, y=120)
# 主界面循环
window.mainloop()