總算組起來了 `````` # -*- coding: utf-8 -*- import twstock import pandas as pd # 導入twstock及pandas模組,pandas模組縮寫為pd import matplotlib import mplfinance as mpf # 導入pandas、matplotlib、mplfinance模組,將mplfinance模組縮寫為mpf # 這邊要導入matplotlib的原因是因為mplfinance繪圖時需要調用mptplotlib模組 print("這是台灣股市各股自2022年起的爬蟲畫圖程式~") print("也繪製出股價5日、20日、60日線") op = 'y' while op == 'y': target_stock = input('請輸入要查詢的股票代號:') #股票代號變數 stock = twstock.Stock(target_stock) #告訴twstock我們要查詢的股票 target_price = stock.fetch_from(2023, 1) #取用至今每天的交易資料 name_attribute = [ 'Date', 'Capacity', 'Turnover', 'Open', 'High', 'Low', 'Close', 'Change', 'Transcation' ] #幫收集到的資料設定表頭 df = pd.DataFrame(columns=name_attribute, data=target_price) #將twstock抓到的清單轉成Data Frame格式的資料表 filename = f'./data/{target_stock}.csv' #指定Data Frame轉存csv檔案的檔名與路徑 df.to_csv(filename) #將Data Frame轉存為csv檔案 df = pd.read_csv(f'./data/{target_stock}.csv', parse_dates=True, index_col=1) #讀取目標股票csv檔的位置 df.rename(columns={'Turnover':'Volume'}, inplace = True) #這裡針對資料表做一下修正,因為交易量(Turnover)在mplfinance中須被改為Volume才能被認出來 mc = mpf.make_marketcolors(up='r',down='g',inherit=True) s = mpf.make_mpf_style(base_mpf_style='yahoo',marketcolors=mc) #針對線圖的外觀微調,將上漲設定為紅色,下跌設定為綠色,符合台股表示習慣 #接著把自訂的marketcolors放到自訂的style中,而這個改動是基於預設的yahoo外觀 kwargs = dict(type='candle', mav=(5,20,60), volume=True, figratio=(10,8), figscale=0.75, title=f'Chart of {target_stock} ', style=s) #設定可變參數kwargs,並在變數中填上繪圖時會用到的設定值,並且設上標題 mpf.plot(df, **kwargs) #選擇df資料表為資料來源,帶入kwargs參數,畫出目標股票的走勢圖 op = input("你還要繼續找資料嗎(y/n)? ") `````` 看起來有點突破了 修成這樣 `````` import twstock import pandas as pd import os from datetime import datetime, timedelta import matplotlib import mplfinance as mpf import tkinter as tk from tkinter import simpledialog, messagebox def fetch_stock_data(target_stock): filename = f'./data/{target_stock}.csv' # 檢查檔案是否存在 if os.path.exists(filename): # 讀取現有數據的最後一天日期 existing_data = pd.read_csv(filename, parse_dates=True, index_col=0, dayfirst=True) existing_data.index = pd.to_datetime(existing_data.index, errors='coerce', format='%Y-%m-%d') last_date = pd.to_datetime(existing_data.index[-1]) # 如果最後一天日期不是今天,則重新抓取數據 if last_date < pd.Timestamp(datetime.now().date()): messagebox.showinfo("更新中......","更新 至最新的日期記錄中~") stock = twstock.Stock(target_stock) target_price = stock.fetch_from(2022, 1) name_attribute = [ 'Date', 'Capacity', 'Turnover', 'Open', 'High', 'Low', 'Close', 'Change', 'Transcation' ] new_data = pd.DataFrame(columns=name_attribute, data=target_price) new_data.set_index('Date', inplace=True) # 使用日期作為索引 # 將新數據添加到現有數據 df = pd.concat([existing_data, new_data]) # 將 "Turnover" 更名為 "Volume" df.rename(columns={'Turnover': 'Volume'}, inplace=True) # 寫入檔案 df.to_csv(filename) else: messagebox.showinfo("已更新","已經是最新的數據,無需重新抓取!") df = existing_data else: # 如果檔案不存在,則重新抓取數據 messagebox.showinfo("抓取中......", "正在拼命抓取中~") stock = twstock.Stock(target_stock) target_price = stock.fetch_from(2022, 1) name_attribute = [ 'Date', 'Capacity', 'Turnover', 'Open', 'High', 'Low', 'Close', 'Change', 'Transcation' ] df = pd.DataFrame(columns=name_attribute, data=target_price) df.set_index('Date', inplace=True)# 使用日期作為索引 # 將 "Turnover" 更名為 "Volume" df.rename(columns={'Turnover': 'Volume'}, inplace=True) # 寫入檔案 df.to_csv(filename) return df def plot_stock_chart(df, target_stock): mc = mpf.make_marketcolors(up='r', down='g', inherit=True) s = mpf.make_mpf_style(base_mpf_style='yahoo', marketcolors=mc) kwargs = dict(type='candle', mav=(5, 20, 60), volume=True, figratio=(10, 8), figscale=0.75, title=f'Chart of {target_stock} ', style=s) mpf.plot(df, **kwargs) def main(): root = tk.Tk() root.withdraw() op = 'y' target_stock = simpledialog.askstring("股票走勢查詢系統", "這是台灣股市自2022年開始的爬蟲資料總和~\n他能繪製出股價5日、20日、60日線~\n請輸入要查詢的股票代號:") df = fetch_stock_data(target_stock) while op == 'y': plot_stock_chart(df, target_stock) op = simpledialog.askstring("繼續查詢", "你還要繼續找資料嗎?(y/n)") root.destroy() if __name__ == "__main__": main() ``````