收盤資料下載好,報告還缺圖?用 mplfinance 把證交所資料做成 K 線與成交量圖
📌 數據僅限本工具現階段參考用。本文只示範工具怎麼安裝、設定、執行,不是投資建議,也不推薦任何股票。
重點摘要
- mplfinance 0.12.10b0 在 Python 3.12.14 成功安裝並產圖。
- 證交所2026年10月1日至27日共16筆日資料,必要數值缺漏為0。
- 同一份資料成功輸出K線PNG,以及含五日、十日均線和成交量的PNG,共兩張。
- 結論: 同一份證交所日資料成功做出兩種金融圖表,輸入需先整理日期與欄位。
- 適合: 會使用Python、需要定期整理金融圖表的人
- 不適合: 期待免程式操作介面的人
| 實測項目 | 結果 |
|---|---|
| 公開日資料 | 16筆,2026-10-01至2026-10-27 |
| 輸出 | 2張PNG及1份CSV |
| PNG尺寸 | 1430×1241、1440×1241 |
| CSV重新讀取 | 16列6欄,含日期 |
收盤資料已經下載成表格,報告卻還缺一張圖:日期要排好、價格要畫成 K 線,下面還想補成交量。每次換資料都重做一次,最麻煩的往往不是取得數字,而是把它整理成可以重複使用的報告畫面。這次用 mplfinance,從同一份證交所公開資料輸出兩種圖片,看這段工作能不能留下固定設定。
下載
專案在 matplotlib/mplfinance,這次安裝 PyPI 的 mplfinance 0.12.10b0,上游原始碼檢視版本為 493811d。實測使用 Python 3.12.14,這是本次成功組合,不代表專案最低版本。它依賴 Matplotlib、pandas;下載資料另外使用 requests。測試設備為 Mac mini M4 Pro(12 核、64GB),套件執行環境為 Python 3.12.14,非 Mac 原生安裝的效能測試。
python -m pip install mplfinance==0.12.10b0 requests
這是 Python 畫圖套件,沒有點開就能上傳表格的網站介面。需要能執行 Python 程式,首次設定完成後,再替換來源資料重畫。
設定
本文示範資料是證交所公開資料,採用個股日成交資訊 STOCK_DAY。查詢月份為 2026 年 10 月,資料日期為 2026-10-01 至 2026-10-27,共 16 筆完整日資料。2330 只是示範輸入代號;本文不解讀價格。查詢當時 10 月 27 日是最近一個已完成的交易日。
下面把回應保存成 monthly.json。套件不會替這份輸入自動抓證交所,下載與整理是本篇示範程式的工作。無須券商帳號或金鑰。
python - <<'PYDATA'
import requests,json
url='https://www.twse.com.tw/exchangeReport/STOCK_DAY'
r=requests.get(url,params={'response':'json','date':'20261001','stockNo':'2330'},timeout=45)
r.raise_for_status()
d=r.json()
assert d.get('stat')=='OK',d.get('stat')
with open('monthly.json','w') as f:
json.dump(d,f,ensure_ascii=False)
print(d['fields'])
print(d['data'][-1])
PYDATA
來源日期是民國年,要加 1911;數字裡的逗號也要移除,再轉成數值。這次用到日期、開盤、最高、最低、收盤、成交股數,輸入欄名依序對應 Date、Open、High、Low、Close、Volume。這些是資料格式的配對,不是修改原始價格。
跑起來
將以下內容存成 plot_demo.py,和 monthly.json 放在同一個資料夾。日期轉成 pandas 的日期索引後,mplfinance 才能依序畫圖。
import json
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import mplfinance as mpf
raw=json.load(open('monthly.json'))
rows=[]
for r in raw['data']:
y,m,d=map(int,r[0].split('/'))
rows.append([f'{y+1911}-{m:02}-{d:02}',
*[float(r[i].replace(',','')) for i in [3,4,5,6,1]]])
df=pd.DataFrame(rows,columns=['Date','Open','High','Low','Close','Volume'])
df=df.set_index('Date')
df.index=pd.to_datetime(df.index)
assert not df.isna().any().any()
df.to_csv('twse.csv')
style=mpf.make_mpf_style(base_mpf_style='nightclouds',
marketcolors=mpf.make_marketcolors(up='#f4696b',down='#4ad7b0',inherit=True))
mpf.plot(df,type='candle',style=style,figsize=(8,7),
savefig=dict(fname='candles.png',dpi=180,bbox_inches='tight'),tight_layout=True)
mpf.plot(df,type='candle',style=style,mav=(5,10),volume=True,figsize=(8,7),
savefig=dict(fname='report.png',dpi=180,bbox_inches='tight'),tight_layout=True)
print(len(df),df.index.min().date(),df.index.max().date())
python plot_demo.py
實測保留相同核心呼叫,另外調整背景、格線與文字色彩。產出 candles.png 與 report.png 兩張圖片,並保存 twse.csv;兩張 PNG 都成功解碼。下圖來自實測產物,為方便閱讀抽成靜態畫面。

| 實測項目 | 結果 |
|---|---|
| 公開日資料 | 16 筆,10 月 1 日至 27 日 |
| 必要數值缺漏 | 0 筆 |
| candles.png | 1430 × 1241,K 線 |
| report.png | 1440 × 1241,K 線、兩條均線與成交量 |
| CSV 重新讀取 | 16 列、6 欄,含日期欄 |

常見問題
為什麼資料日期不是今天? 這次在 10 月 28 日收盤前製作,所以使用 27 日完整資料。另查全市場 STOCK_DAY_ALL 時只回到 22 日,因此沒有拿那份回應冒充最新資料。每次更新都要看回應中的最後日期,不能只看請求成功。
均線開頭怎麼少一段? 五日均線需累積五筆,最前面四筆不會有值;十日均線同理,最前面九筆留空。不能為了讓圖連起來隨意補零。
有字型警告還能用嗎? 首次繪圖出現 DejaVu Sans 的 semibold 字重找不到、改用 700 的警告,但圖片成功保存並解碼。這次圖內使用英文標籤,沒有驗證中文圖表字型;若改中文,應先確認字型是否支援,不把本次成功延伸成所有字都能顯示。
這套流程適合會使用 Python、定期整理收盤報告的人:先整理日期欄位,留下畫圖設定,之後換資料再跑。不適合期待完全免程式操作的人。本次沒有驗證其他圖型、即時更新或長期自動執行;這些不影響已完成的兩張靜態圖,也不能算進本次成果。
專案:mplfinance。授權採專案自有的 LICENSE agreement,GitHub 未提供標準 SPDX 判定;使用或散布時應閱讀原文並保留要求的授權與著作權聲明,不自行標成 MIT。資料來源:證交所個股日成交資訊。
影片版面修訂
本次依審片意見把整片改成深藍金融報表。畫面中的K線、五日與十日均線、成交量圖及價格表,沿用上述實測產物;外框、日曆與教學卡為影片重排,不是工具內建操作介面。資料仍截至2026年10月27日,沒有把重剪日期說成新的行情查詢。