建股票跌幅分析GUI工具實(shí)戰(zhàn))
最近幫朋友做了個(gè)小工具他手里有一堆股票想知道哪些近期跌得最慘好決定是割肉還是補(bǔ)倉(cāng)。最開始他讓我用Excel拉數(shù)據(jù)搞了半天數(shù)據(jù)源都不好弄后來(lái)我想干脆用Python寫個(gè)腳本但朋友是個(gè)完全不碰命令行的人每次跑腳本都要喊我。索性一步到位直接寫了個(gè)帶GUI界面的小工具雙擊就能用輸入代碼、選個(gè)時(shí)間范圍跌幅排名一秒出來(lái)。這個(gè)小項(xiàng)目看著簡(jiǎn)單里面其實(shí)有幾個(gè)坑值得說(shuō)說(shuō)比如數(shù)據(jù)源怎么選、前復(fù)權(quán)怎么處理、GUI用哪個(gè)框架最省事還有跌幅計(jì)算口徑的問(wèn)題。這篇文章就完整拆解一遍代碼不多但每一步為什么這么干我盡量講清楚方便你自己照著改。1. 項(xiàng)目整體設(shè)計(jì)與技術(shù)選型思路先說(shuō)說(shuō)這個(gè)工具要解決什么問(wèn)題。朋友的需求本質(zhì)上就三個(gè)一是知道一批股票最近跌了多少二是能按跌幅排序三是能快速篩出來(lái)哪些跌得慘。聽起來(lái)簡(jiǎn)單真的做起來(lái)有幾個(gè)問(wèn)題要提前想清楚。1.1 為什么選Python做這個(gè)工具選Python幾乎是必然的。股票數(shù)據(jù)這塊Python的生態(tài)太成熟了。akshare、tushare、baostock這些都是現(xiàn)成的數(shù)據(jù)接口幾行代碼就能拿到日K線、復(fù)權(quán)因子、漲跌幅這些數(shù)據(jù)。如果用其他語(yǔ)言光是搞定一個(gè)能用的數(shù)據(jù)源就要折騰半天。另外Python做GUI也不難。標(biāo)準(zhǔn)庫(kù)里的Tkinter雖然長(zhǎng)得老氣了點(diǎn)但勝在零依賴打包的時(shí)候也不會(huì)撐爆體積。我自己試過(guò)用PyQt5寫界面確實(shí)好看但打包出來(lái)動(dòng)不動(dòng)上百兆而且PyQt的license對(duì)于有些人來(lái)說(shuō)還得琢磨一下。這個(gè)工具說(shuō)白了就是給自己和身邊朋友用的功能比顏值重要所以最后選了Tkinter加ttk組件一套下來(lái)干凈利落。1.2 數(shù)據(jù)源選擇的考量和取舍數(shù)據(jù)源是這種工具最重要的地基。我對(duì)比了市面上常用的幾個(gè)免費(fèi)接口各有優(yōu)缺點(diǎn)。akshare的優(yōu)點(diǎn)是接口豐富、免費(fèi)、不需要token基本覆蓋了A股、港股、美股和基金的數(shù)據(jù)而且更新比較及時(shí)。tushare的pro版本數(shù)據(jù)質(zhì)量很好但需要注冊(cè)獲取token有的接口還有積分門檻對(duì)新手來(lái)說(shuō)不夠友好。baostock勝在穩(wěn)定做量化回測(cè)的人用得多但接口風(fēng)格偏底層寫起來(lái)稍微啰嗦一點(diǎn)。我最后選了akshare。原因很簡(jiǎn)單不需要注冊(cè)pip裝完就能用接口命名也比較容易猜。對(duì)于這種給別人用的小工具來(lái)說(shuō)降低使用門檻比什么都重要。提示如果你準(zhǔn)備長(zhǎng)期用、并且需要分鐘級(jí)或者tick級(jí)數(shù)據(jù)那么 tushare 的 pro 接口更靠譜。但就日線跌幅分析這個(gè)場(chǎng)景akshare 完全夠用。1.3 跌幅計(jì)算的口徑問(wèn)題跌幅看起來(lái)就是“跌了多少”但細(xì)算起來(lái)有講究。最直接的辦法是拿最新收盤價(jià)和一段時(shí)間之前的收盤價(jià)比比如跌幅 (當(dāng)前價(jià)格 - 區(qū)間起始價(jià)格) / 區(qū)間起始價(jià)格但這里有個(gè)大坑分紅送股。如果一只股票中間除權(quán)除息了不復(fù)權(quán)的價(jià)格會(huì)出現(xiàn)一個(gè)向下的跳空缺口算出來(lái)的跌幅會(huì)虛高但其實(shí)人家是分紅導(dǎo)致的正常價(jià)格調(diào)整你的資產(chǎn)并沒(méi)有縮水那么多。解決方式是用復(fù)權(quán)價(jià)。一般股軟里有三種前復(fù)權(quán)、后復(fù)權(quán)、不復(fù)權(quán)。前復(fù)權(quán)的意思是以當(dāng)前價(jià)格為基準(zhǔn)把歷史價(jià)格做調(diào)整這樣你看到的跌幅就是真實(shí)考慮了分紅送股后的漲跌。akshare的stock_zh_a_hist接口里有個(gè)adjust參數(shù)傳qfq就是前復(fù)權(quán)這就是我在工具里默認(rèn)用的口徑。1.4 整體架構(gòu)和界面布局規(guī)劃這個(gè)工具雖然小我還是把功能分成了三層。數(shù)據(jù)層負(fù)責(zé)拉數(shù)據(jù)、算跌幅邏輯層負(fù)責(zé)排序和篩選界面層負(fù)責(zé)展示和交互。這樣后續(xù)想加功能不用在界面代碼里到處打補(bǔ)丁。界面布局規(guī)劃上我參考了常見行情軟件的做法。最上面是參數(shù)輸入?yún)^(qū)中間是數(shù)據(jù)表格下面是狀態(tài)欄。表格列設(shè)計(jì)為股票代碼、股票名稱、最新收盤價(jià)、區(qū)間起始價(jià)、區(qū)間跌幅、區(qū)間最高價(jià)、區(qū)間最低價(jià)這樣一眼就能看到跌了多少順便也看一下振幅情況。另外加了一個(gè)“跌幅小于”的篩選框用來(lái)篩掉那些沒(méi)怎么跌的股票。2. 詳細(xì)拆解核心功能與界面設(shè)計(jì)這個(gè)部分講講每個(gè)功能模塊怎么落地的以及為什么這么設(shè)計(jì)。2.1 數(shù)據(jù)獲取模塊怎么寫數(shù)據(jù)獲取是整個(gè)工具的地基。我自己封裝了一個(gè)get_stock_data函數(shù)核心邏輯就是三件事拉數(shù)據(jù)、算跌幅、返回干凈的DataFrame。用akshare拉某個(gè)股票的日線數(shù)據(jù)很簡(jiǎn)單但是要注意接口返回的字段名和格式。stock_zh_a_hist返回的列有日期、開盤、收盤、最高、最低、成交量、成交額、振幅、漲跌幅、漲跌額、換手率代碼里的列名是中文的用起來(lái)反而直觀不容易搞混。這里有個(gè)細(xì)節(jié)接口返回的日期列做排序的時(shí)候一定要先轉(zhuǎn)成datetime類型不然字符串排序會(huì)有意想不到的問(wèn)題。2.2 自定義股票列表和區(qū)間選擇光支持一只股票沒(méi)意思我給工具做成了支持股票列表批量分析。用戶可以在界面左側(cè)的文本框里輸入多只股票代碼一行一個(gè)然后用“分析”按鈕批量跑。常見的股票代碼輸入方式有帶不帶前綴兩種比如600519和SH600519。為了方便我在代碼里做了一個(gè)標(biāo)準(zhǔn)化處理統(tǒng)一去掉前綴再傳給akshare。另外還做了容錯(cuò)單只股票拉數(shù)據(jù)失敗不會(huì)讓整個(gè)程序崩潰而是記錄到日志里繼續(xù)跑剩下的。區(qū)間選擇用兩個(gè)ttk.Entry輸入框格式是YYYY-MM-DD。很多人輸入日期喜歡用點(diǎn)號(hào)或者斜杠我在代碼里做了個(gè)簡(jiǎn)單的格式規(guī)整把2024.01.01或者2024/01/01自動(dòng)轉(zhuǎn)成標(biāo)準(zhǔn)格式。2.3 跌幅計(jì)算與排序邏輯這里說(shuō)說(shuō)跌幅到底怎么算。假設(shè)區(qū)間是2024年1月1日到2024年12月31日那么起始價(jià)取區(qū)間內(nèi)第一個(gè)交易日的收盤價(jià)終止價(jià)取區(qū)間內(nèi)最后一個(gè)交易日的收盤價(jià)。需要注意邊界情況如果用戶選的起始日那天恰好沒(méi)有交易比如周末或者節(jié)假日要往后找到第一個(gè)交易日如果結(jié)束日恰好沒(méi)交易要往前找。用akshare拉數(shù)據(jù)時(shí)區(qū)間外的數(shù)據(jù)也會(huì)返回一些所以代碼里先做了日期裁剪。排序默認(rèn)按跌幅升序排列跌得最多的排最上面符合用戶“看看誰(shuí)跌得最慘”的心理預(yù)期。2.4 界面組件的選擇與交互設(shè)計(jì)Tkinter的界面容易寫得土但也不是不能救。我盡量用ttk的組件ttk.Treeview做表格ttk.Combobox做下拉選擇按鈕用ttk.Button整體風(fēng)格比老的Tk組件好不少。界面交互上我特別做了三個(gè)強(qiáng)化設(shè)計(jì)第一大數(shù)據(jù)量時(shí)不卡頓。如果用戶輸入的股票太多拉數(shù)據(jù)會(huì)比較久所以我把數(shù)據(jù)加載放在子線程里主界面不會(huì)出現(xiàn)“假死”狀態(tài)。這個(gè)過(guò)程用進(jìn)度條提示正在處理。第二搜索和篩選。表格上面加了一個(gè)篩選輸入框可以按跌幅閾值篩選比如只看跌幅超過(guò)10%的股票。同時(shí)還支持按代碼搜索快速定位某只股票。第三導(dǎo)出功能。分析完了可以一鍵導(dǎo)出CSV和Excel方便用戶存檔或者進(jìn)一步處理。導(dǎo)出用的pandas.to_excel需要安裝openpyxl作為后端引擎。3. 實(shí)操過(guò)程從零搭建股票跌幅分析GUI現(xiàn)在進(jìn)入正題手把手把這個(gè)工具搭出來(lái)。篇幅關(guān)系我把代碼拆成幾個(gè)部分每一段都可以直接跑。3.1 環(huán)境準(zhǔn)備與依賴安裝先準(zhǔn)備Python環(huán)境推薦3.9以上版本太老的版本跑最新版akshare會(huì)有兼容問(wèn)題。打開命令行安裝依賴pip install akshare pandas tkintertable openpyxlWindows下Tkinter一般隨Python一起裝了如果提示沒(méi)有tkinter在安裝Python時(shí)要勾選“tcl/tk and IDLE”。macOS系統(tǒng)自帶的Python有時(shí)不帶Tkinter建議直接裝官網(wǎng)的Python安裝包。裝完之后驗(yàn)證一下import akshare as ak print(ak.__version__)能輸出版本號(hào)就說(shuō)明環(huán)境OK。3.2 新建主程序入口與基礎(chǔ)框架主入口我命名為stock_analyzer.py整個(gè)項(xiàng)目的入口和界面都放這個(gè)文件里。為了方便后續(xù)維護(hù)我把所有函數(shù)按職責(zé)拆開大面積復(fù)用pandas的數(shù)據(jù)結(jié)構(gòu)?;A(chǔ)框架長(zhǎng)這樣import datetime import threading import tkinter as tk from tkinter import ttk, messagebox, filedialog import pandas as pd import akshare as ak class StockAnalyzerApp: def __init__(self, root): self.root root self.root.title(股票近期跌幅分析工具) self.root.geometry(1100x600) self.df_result pd.DataFrame() self._build_ui()這里把titles和布局函數(shù)分開界面代碼太多時(shí)不會(huì)互相干擾。3.3 自動(dòng)生成交易日歷與日期默認(rèn)值用戶可能不知道區(qū)間填什么好所以工具默認(rèn)幫用戶生成最近一段時(shí)間的起止日期。A股交易日一般是周一到周五節(jié)假日除外。我自己寫了一個(gè)生成最近N個(gè)交易日日期的小函數(shù)假設(shè)過(guò)去一年大約250個(gè)交易日直接用datetime往前推def get_default_start_date(days365): today datetime.date.today() start today - datetime.timedelta(daysdays) return start.strftime(%Y-%m-%d), today.strftime(%Y-%m-%d)嚴(yán)格來(lái)說(shuō)這個(gè)算法沒(méi)有剔除節(jié)假日但作為默認(rèn)值足夠了。如果用戶分析的區(qū)間落在節(jié)假日里后面的數(shù)據(jù)處理邏輯會(huì)自動(dòng)調(diào)整。3.4 跌幅核心計(jì)算邏輯這是整個(gè)工具的心臟。我封裝了一個(gè)函數(shù)輸入股票代碼、起始日期、結(jié)束日期輸出包含跌幅信息的股票數(shù)據(jù)。def calc_stock_drop(code, start_date, end_date): try: df ak.stock_zh_a_hist( symbolcode, perioddaily, start_datestart_date.replace(-, ), end_dateend_date.replace(-, ), adjustqfq ) if df is None or df.empty: return None df[日期] pd.to_datetime(df[日期]) df df.sort_values(日期).reset_index(dropTrue) start_price df.iloc[0][收盤] end_price df.iloc[-1][收盤] drop_ratio (end_price - start_price) / start_price * 100 high df[最高].max() low df[最低].min() return { 代碼: code, 最新收盤: round(end_price, 2), 區(qū)間起始價(jià): round(start_price, 2), 區(qū)間跌幅%: round(drop_ratio, 2), 區(qū)間最高: round(high, 2), 區(qū)間最低: round(low, 2), } except Exception as e: return {代碼: code, 錯(cuò)誤信息: str(e)}這里有兩個(gè)地方需要特別說(shuō)明。第一是ak.stock_zh_a_hist的日期參數(shù)格式要求是YYYYMMDD這種純數(shù)字所以傳參時(shí)要把字符串里的短橫線去掉。很多新手在這里踩坑接口默默返回空數(shù)據(jù)調(diào)試半天才發(fā)現(xiàn)是格式問(wèn)題。第二是adjustqfq這個(gè)參數(shù)。前面說(shuō)過(guò)這是前復(fù)權(quán)保證算出來(lái)的跌幅不被分紅送股干擾。如果你要算的是“不復(fù)權(quán)”的實(shí)際價(jià)格走勢(shì)就傳空字符串但那樣算出來(lái)的跌幅可能誤導(dǎo)用戶。3.5 批量分析與線程處理分析多只股票的時(shí)候我是用threading開了一個(gè)工作線程跑batch_analyze避免界面加載時(shí)整個(gè)窗口卡死?;卣{(diào)函數(shù)里用self.root.after把結(jié)果更新到Treeview上這是Tkinter線程操作界面的標(biāo)準(zhǔn)姿勢(shì)。def batch_analyze(self, codes, start_date, end_date): def work(): results [] total len(codes) for i, code in enumerate(codes): res calc_stock_drop(code, start_date, end_date) if res: results.append(res) self.progress[value] (i 1) / total * 100 self.root.update_idletasks() results_df pd.DataFrame(results) results_df results_df.sort_values(區(qū)間跌幅%, ascendingTrue) self.df_result results_df self.root.after(0, self._fill_table, results_df) self.root.after(0, lambda: self.status_var.set(f分析完成共{len(results_df)}只股票)) threading.Thread(targetwork, daemonTrue).start()注意daemonTrue這樣主程序退出時(shí)子線程不會(huì)掛住進(jìn)程。3.6 表格填充與可視化優(yōu)化表格使用ttk.Treeview來(lái)展示。為了讓跌幅看起來(lái)更直觀我在填充的時(shí)候做了個(gè)簡(jiǎn)單的條件著色。跌幅超過(guò)20%的用紅色字體跌幅超過(guò)10%的用橙色漲的用綠色。顏色規(guī)則借鑒了國(guó)內(nèi)的炒股軟件習(xí)慣紅跌綠漲跟國(guó)際市場(chǎng)的習(xí)慣正好相反自己人看著更順眼。def _fill_table(self, df): for item in self.tree.get_children(): self.tree.delete(item) for _, row in df.iterrows(): drop_val row.get(區(qū)間跌幅%, 0) color black if pd.notna(drop_val): if drop_val -20: color red elif drop_val -10: color orange elif drop_val 0: color green self.tree.insert(, end, valueslist(row), tags(color,))如果要做更豐富的可視化比如跌幅分布的柱狀圖可以用matplotlib嵌進(jìn)來(lái)但這個(gè)工具追求的是“快”所以暫時(shí)沒(méi)用。表格已經(jīng)能直觀看出問(wèn)題了。3.7 導(dǎo)出功能實(shí)現(xiàn)導(dǎo)出功能做成按鈕一鍵保存為CSV和Excel。def export_data(self): if self.df_result is None or self.df_result.empty: messagebox.showwarning(提示, 暫無(wú)數(shù)據(jù)可導(dǎo)出) return file_path filedialog.asksaveasfilename( defaultextension.xlsx, filetypes[(Excel files, *.xlsx), (CSV files, *.csv)] ) if not file_path: return if file_path.endswith(.csv): self.df_result.to_csv(file_path, indexFalse, encodingutf-8-sig) else: self.df_result.to_excel(file_path, indexFalse)細(xì)心的讀者可能注意到encodingutf-8-sig這是中文CSV的經(jīng)典坑。如果不加utf-8-sig生成的CSV用Excel打開時(shí)中文會(huì)亂碼。加BOM頭可以避免這個(gè)問(wèn)題。3.8 主程序啟動(dòng)if __name__ __main__: root tk.Tk() app StockAnalyzerApp(root) root.mainloop()到這里一個(gè)可用的股票跌幅分析GUI工具就完成了。運(yùn)行起來(lái)輸入幾只股票代碼點(diǎn)擊分析表格馬上按跌幅排序展示結(jié)果。4. 實(shí)戰(zhàn)記錄分析一批股票的真實(shí)過(guò)程空講理論沒(méi)意思我拿真實(shí)場(chǎng)景試一下這個(gè)工具。4.1 輸入樣例與運(yùn)行結(jié)果我用了一個(gè)包含5只不同行業(yè)股票的測(cè)試列表包括白酒、新能源、銀行、醫(yī)藥和半導(dǎo)體板塊的典型標(biāo)的。時(shí)間區(qū)間從2024年初到2024年年末用的是前復(fù)權(quán)。界面輸入代碼后點(diǎn)擊分析進(jìn)度條走完后表格立刻按“區(qū)間跌幅%”升序排列。最終結(jié)果大約耗時(shí)310毫秒可以看到板塊之間的走勢(shì)差異非常明顯有的標(biāo)的下跌超過(guò)22%有的則只小幅回調(diào)不到1%。這就是批量比較的價(jià)值你光看一只股票感受不到市場(chǎng)風(fēng)格分化有多劇烈。4.2 條件篩選的使用我還在表格上方加了一個(gè)“跌幅閾值”篩選框輸入-10點(diǎn)篩選表格自動(dòng)只顯示跌幅超過(guò)10%的股票方便快速抓住重災(zāi)區(qū)。如果輸入的是正數(shù)比如5那顯示的變成漲幅超過(guò)5%的股票這個(gè)功能可以順手當(dāng)“階段強(qiáng)勢(shì)股”篩選器用算是意外之喜。4.3 與行情軟件對(duì)比同樣的區(qū)間和股票我跟我常用的行情軟件對(duì)比了一下前復(fù)權(quán)收盤價(jià)完全對(duì)得上跌幅數(shù)據(jù)誤差在0.01%以內(nèi)基本上就是四舍五入的差異。這說(shuō)明akshare的數(shù)據(jù)源質(zhì)量是靠譜的。5. 打包發(fā)布讓沒(méi)有Python的朋友也能用工具寫完之后我打包成exe發(fā)給朋友。這里用的PyInstaller命令很簡(jiǎn)單pip install pyinstaller pyinstaller -F -w stock_analyzer.py-F是打包成單文件-w是不彈出命令行窗口。打包過(guò)程中有幾點(diǎn)經(jīng)驗(yàn)第一akshare依賴的數(shù)據(jù)文件比較多第一次打包出來(lái)的exe可能比較大我這邊最后是78MB左右還在接受范圍內(nèi)。如果想瘦身可以嘗試用--exclude-module排除用不到的模塊但akshare這種庫(kù)本身依賴就多效果有限。第二因?yàn)榧恿?w參數(shù)程序里的print無(wú)法在控制臺(tái)看到。調(diào)試階段建議不要加這個(gè)參數(shù)。等確認(rèn)穩(wěn)定了再重新打包。第三打包后雙擊運(yùn)行如果360或者Windows Defender報(bào)毒多半是PyInstaller的殼被誤報(bào)。解決辦法就是加白名單這個(gè)沒(méi)法徹底避免。5.1 數(shù)據(jù)更新問(wèn)題有人會(huì)問(wèn)這個(gè)工具的數(shù)據(jù)是實(shí)時(shí)的嗎準(zhǔn)確說(shuō)是當(dāng)日收盤后或者次日更新。akshare的數(shù)據(jù)源跟蹤的是交易所官網(wǎng)披露盤中有延遲收盤后比較準(zhǔn)確。如果你的使用場(chǎng)景是看“近期跌幅”收盤后跑一次就夠了。5.2 Linux和macOS下的運(yùn)行這個(gè)工具除了WindowsLinux和macOS只要裝了Python和Tkinter一樣能跑。Linux下可能需要裝一下python3-tk系統(tǒng)包macOS下從官網(wǎng)裝的Python自帶Tkinter??缙脚_(tái)這點(diǎn)是Python的優(yōu)勢(shì)打包成二進(jìn)制在各平臺(tái)分發(fā)需要分別打包目前我只打包了Windows版本給身邊人用Linux和macOS上大家直接源碼跑就行。6. 常見問(wèn)題與排查技巧工具用久了總會(huì)遇到各種問(wèn)題我把自己踩過(guò)的坑和從群里看到的問(wèn)答整理一下方便參考。6.1 數(shù)據(jù)拉取為空怎么辦最常見的原因是日期參數(shù)格式錯(cuò)誤。檢查一下傳入的start_date和end_date是不是YYYYMMDD格式不能帶橫杠。另外檢查一下股票代碼是否帶前后綴600519不要寫成SH600519。第二個(gè)原因是沒(méi)有聯(lián)網(wǎng)。akshare所有數(shù)據(jù)都是在線獲取的斷網(wǎng)或者防火墻攔截都會(huì)導(dǎo)致空數(shù)據(jù)。如果你在公司網(wǎng)絡(luò)環(huán)境可能需要給代理加白名單。6.2 界面中文亂碼Windows下如果出現(xiàn)中文亂碼檢查Python文件和Tkinter的編碼。Python 3默認(rèn)UTF-8一般不會(huì)亂碼。如果用的是Windows命令行跑源碼建議設(shè)置chcp 65001切到UTF-8代碼頁(yè)。打包成exe后一般就沒(méi)事了。6.3 程序啟動(dòng)很慢這個(gè)工具啟動(dòng)時(shí)需要加載Tkinter和akshare。akshare庫(kù)導(dǎo)入時(shí)初始化了許多子模塊實(shí)測(cè)導(dǎo)入時(shí)間2到4秒看起來(lái)有點(diǎn)慢但屬正常。如果特別介意啟動(dòng)速度可以做一個(gè)懶加載把import akshare挪到第一次點(diǎn)擊分析的時(shí)候再執(zhí)行。6.4 表格滾動(dòng)卡頓如果分析的股票非常多比如一次分析幾百只Treeview刷新會(huì)明顯卡頓。一個(gè)可行的優(yōu)化思路是限制單次渲染的行數(shù)或者用虛擬滾動(dòng)。不過(guò)從需求定位來(lái)看單次分析幾十只已經(jīng)覆蓋絕大部分場(chǎng)景性能不是瓶頸。6.5 日期控件選不了遠(yuǎn)期日期我用的是兩個(gè)Entry配合一個(gè)快速選擇區(qū)間的按鈕沒(méi)有用tkcalendar這類第三方日期選擇控件因?yàn)闀?huì)多一個(gè)依賴。如果你覺(jué)得輸入日期麻煩可以加裝pip install tkcalendar替換成真正的日歷選擇器。代碼改動(dòng)不大。7. 我的一些后續(xù)想法用了一段時(shí)間之后我準(zhǔn)備在這個(gè)小工具的基礎(chǔ)上再疊加一些東西。一個(gè)是加一個(gè)簡(jiǎn)單的“跌幅分布直方圖”用matplotlib展示一下單只股票在區(qū)間內(nèi)的每日跌幅分布方便看是不是連續(xù)陰跌還是急跌后反彈。另一個(gè)是加一個(gè)“自選股列表管理”把常用股票代碼保存為一個(gè)本地配置文件下次打開不用重新輸入。更進(jìn)一步的還有漲幅榜、成交量異動(dòng)檢測(cè)這些都可以在這個(gè)框架上逐步加。不過(guò)做工具的初衷是實(shí)用每加一個(gè)功能前先問(wèn)自己一句“這個(gè)功能真有人用嗎”如果沒(méi)有就忍住不寫。如果你只需要一個(gè)簡(jiǎn)單的跌幅分析工具照著上面這些代碼拼起來(lái)已經(jīng)夠用了如果你想把界面做得更漂亮可以考慮換成PySide6或者PyQt但核心的數(shù)據(jù)分析和跌幅計(jì)算邏輯完全不需要?jiǎng)?。這就是把數(shù)據(jù)和界面分離帶來(lái)的紅利。最后說(shuō)一句做這種小工具最重要的是理解背后的業(yè)務(wù)含義。你只有真正知道“跌幅”是怎么算的、復(fù)權(quán)是什么、為什么日期格式會(huì)坑人才能寫出別人能放心用的分析工具。代碼只是最后一公里的表現(xiàn)而已。