首頁 > 軟體

Python+Tkinter實現股票K線圖的繪製

2022-08-25 14:01:46

在前面的文章中,我們一起學習瞭如何通過 Python 抓取東方財富網的實時股票資料以及如何製作成 Tkinter GUI 程式,連結如下

用 Python 爬取股票實時資料 

Tkinter製作股票資料抓取小程式,有點秀!

今天我們就在這個基礎上,在 Tkinter 程式中繪製 K 線圖,一起來看看吧

子視窗

我們今天的整體程式碼還是基於上次的 Tkinter 股票程式,在主類 MainCreator 下面建立一個函數 create_subwindow

    def create_subwindow(self):
        t = ttk.Toplevel()
        t.wm_title("K線圖")
        sub_window = SubWindiw()
        sub_window.subWindow(t)

我們這裡使用 Toplevel 來建立子視窗,再來看看子視窗相關的程式碼

class SubWindiw:
    def __init__(self):
        pass
    def all_files(self):
      ...
    def getDate(self):
      ...
    def subWindow(self, root_frame):
      ...
    def go(self):
      ...

對於子視窗程式碼,subWindow 函數是子視窗的主要函數

子視窗框架

子視窗主要程式碼如下

    def subWindow(self, root_frame):
        file_list = self.all_files()

        # 建立主框架
        main_frame = ttk.Frame(root_frame)
        main_frame.pack()

        # 在主框架下建立股票日期輸入框子框架
        date_frame = ttk.Frame(main_frame, relief=tix.SUNKEN)
        date_frame.pack(fill=X, side=TOP)
        # 建立標籤‘開始日期'
        date_start_label = ttk.Label(date_frame, text='開始日期')
        date_start_label.pack(side=LEFT)
        # 建立開始日期程式碼輸入框
        re_date = self.getDate()
        self.de_start = ttk.DateEntry(date_frame, startdate=re_date)
        self.de_start.pack(side=LEFT, padx=4, pady=4)
        # 建立標籤‘結束日期'
        date_end_label = ttk.Label(date_frame, text='結束日期')
        date_end_label.pack(side=LEFT)
        # 建立結束日期程式碼輸入框
        self.de_end = ttk.DateEntry(date_frame)
        self.de_end.pack(side=LEFT, padx=4, pady=4)

        # 在主框架下建立查詢按鈕子框架
        search_frame = ttk.Frame(main_frame, relief=tix.SUNKEN)
        search_frame.pack(fill=X, side=TOP)
        # 檔案選擇框
        search_label = ttk.Label(search_frame, text='選擇股票檔案')
        search_label.pack(side=LEFT)
        values = file_list
        self.cbo = ttk.Combobox(
            master=search_frame,
            values=values,
            width=45,
        )
        self.cbo.pack(side=LEFT, expand=YES, pady=5, fill=X)

        # 佔位 check button
        cb = ttk.Checkbutton(search_frame, text="佔位")
        # cb.pack(side=LEFT, padx=5, fill=X)

        # 建立查詢按鈕並設定功能
        stock_find = ttk.Button(search_frame, text='查詢', command=self.go)
        stock_find.pack(pady=4, expand=YES, side=LEFT)

        # 建立股票圖形輸出框架
        self.stock_graphics = tk.Frame(root_frame, relief=tix.RAISED)
        self.stock_graphics.pack(expand=1, fill=tix.BOTH, anchor=tix.CENTER)

主要還是分三個區域,日期選擇區域,股票檔案選擇區域以及K線圖展示區域

還有兩個功能性函數 all_files 和 getDate

all_files

    def all_files(self):
        file_list = []
        for root, dirs, files in os.walk("./"):
            for f in files:
                if 'csv' in f and 'days' in f:
                    file_list.append(f)
        return file_list

getDate

    def getDate(self):
        today = datetime.datetime.now()
        offset = datetime.timedelta(days=-1)
        re_date = (today + offset).strftime('%Y/%m/%d')
        return today + offset

繪製K線圖

最後我們看看繪製K線圖的程式碼

    def go(self):
        code_name = self.cbo.get()
        start_date = self.de_start.entry.get()
        end_date = self.de_end.entry.get()
        gupiao_file = self.cbo.get()
        if not gupiao_file:
            messbox.showerror("股票檔案為空", "請選擇股票資料檔案!")
            return
        stock_data = pd.read_csv(gupiao_file)
        data = stock_data.loc[:, ['時間', '開盤價',
                                  '收盤價', '最高價', '最低價', '成交量(手)']]  # :取所有行資料,後面取date列,open列等資料
        data = data.rename(columns={'時間': 'Date', '開盤價': 'Open',
                                    '收盤價': 'Close', '最高價': 'High', '最低價': 'Low',
                                    '成交量(手)': '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)  # 將時間順序升序,符合時間序列
        data = data[data.index < end_date][data.index > start_date]

        if not data.values.any():
            print("股票資料為空")
            messbox.showerror("股票資料為空", "請選擇合理的時間!")
            return
        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='#002B36',
                                      facecolor='#002B36',
                                      edgecolor='w',
                                      # gridcolor='(0.82, 0.83, 0.85)',
                                      rc={'font.family': 'SimHei',
                                          'xtick.labelcolor': 'white',
                                          'ytick.labelcolor': 'white',
                                          'axes.labelcolor': 'white',
                                          })
        self.fig, self.axlist = mpf.plot(data, style=my_style, type='candle',
                                         mav=(5, 10, 20), volume=True, show_nontrading=False, returnfig=True)
        canvas = FigureCanvasTkAgg(self.fig, master=self.stock_graphics)  # 設定tkinter繪製區
        if len(self.stock_graphics.winfo_children()) == 2:
            self.stock_graphics.winfo_children()[0].destroy()
        canvas.draw()

        canvas._tkcanvas.pack(side=BOTTOM, fill=BOTH, expand=1)

我們通過 Matplotlib + mplfinance 來繪製K線圖

首先是通過 Pandas 來處理資料,把我們爬取到的資料處理成 mplfinance 需要的格式,如下

接下來只需要呼叫plot函數即可

self.fig, self.axlist = mpf.plot(data, style=my_style, type='candle',
                                         mav=(5, 10, 20), volume=True, show_nontrading=False, returnfig=True)

到此這篇關於Python+Tkinter實現股票K線圖的繪製的文章就介紹到這了,更多相關Python Tkinter股票K線圖內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com