jlzzjlzz亚洲乱熟在线播放

系統城裝機大師 - 唯一官網:www.farandoo.com!

當前位置:首頁 > 腳本中心 > python > 詳細頁面

關于python tushare Tkinter構建的簡單股票可視化查詢系統(Beta v0.13)

時間:2020-10-19來源:www.farandoo.com作者:電腦系統城

前言:

這次比上次新添了公司信息內容跟一個股票基本面指標選項卡,股票基本面指標選項卡用的是matplotlib寫的,采用plt.subplot2grid()子圖寫的,沒寫主圖,在此期間遇到了無法標題中文話,一寫就亂碼,用過網上很多解決方法,目前也是無解,先記錄,后面有時間再解決,如果你有解決方法請務必賜教,實在這個問題卡了我一天多了,如果單單是只用matplotlib輸出圖形,亂碼問題網上的很多方法也是能夠解決,我也不清楚究竟是我寫的代碼哪里跟中文顯示沖突了,一時間代碼也開始有點亂了,后面估計會越寫越亂,等再寫一兩個功能抽個時間簡潔下代碼。更新的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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()函數返回指定長度的字符串,原字符串右對齊,前面填充0
  if 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
 
 
tabControl = 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()

效果圖:

在這里插入圖片描述
在這里插入圖片描述

到此這篇關于python tushare Tkinter構建的簡單股票可視化查詢系統(Beta v0.13)的文章就介紹到這了

分享到:

相關信息

系統教程欄目

欄目熱門教程

人氣教程排行

站長推薦

熱門系統下載