# 收盤資料下載好，報告還缺圖？用 mplfinance 把證交所資料做成 K 線與成交量圖

- 網址：https://blog.valenvan.uk/posts/matplotlib-mplfinance.html
- 發布日期：2026-10-28
- 測試設備：Mac mini M4 Pro（12 核、64GB）
- 專案：matplotlib/mplfinance（https://github.com/matplotlib/mplfinance），NOASSERTION 授權
- 測試版本：mplfinance 0.12.10b0 / inspected source 493811d
- 實測影片：https://www.youtube.com/shorts/zRDj5-jk4no
- 分類：金融工具區（https://blog.valenvan.uk/finance.html）

> 📌 數據僅限本工具現階段參考用。本文只示範工具怎麼安裝、設定、執行，不是投資建議，也不推薦任何股票。

## 重點摘要

- 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](https://github.com/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 原生安裝的效能測試。

```bash
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。套件不會替這份輸入自動抓證交所，下載與整理是本篇示範程式的工作。無須券商帳號或金鑰。

```bash
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 才能依序畫圖。

```python
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())
```

```bash
python plot_demo.py
```

實測保留相同核心呼叫，另外調整背景、格線與文字色彩。產出 candles.png 與 report.png 兩張圖片，並保存 twse.csv；兩張 PNG 都成功解碼。下圖來自實測產物，為方便閱讀抽成靜態畫面。

![證交所資料產生的K線圖，示範資料截至2026年10月27日](https://blog.valenvan.uk/img/matplotlib-mplfinance-article_1.png)

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

![同一份資料加上五日、十日均線與成交量](https://blog.valenvan.uk/img/matplotlib-mplfinance-article_2.png)

## 常見問題

**為什麼資料日期不是今天？** 這次在 10 月 28 日收盤前製作，所以使用 27 日完整資料。另查全市場 STOCK_DAY_ALL 時只回到 22 日，因此沒有拿那份回應冒充最新資料。每次更新都要看回應中的最後日期，不能只看請求成功。

**均線開頭怎麼少一段？** 五日均線需累積五筆，最前面四筆不會有值；十日均線同理，最前面九筆留空。不能為了讓圖連起來隨意補零。

**有字型警告還能用嗎？** 首次繪圖出現 DejaVu Sans 的 semibold 字重找不到、改用 700 的警告，但圖片成功保存並解碼。這次圖內使用英文標籤，沒有驗證中文圖表字型；若改中文，應先確認字型是否支援，不把本次成功延伸成所有字都能顯示。

這套流程適合會使用 Python、定期整理收盤報告的人：先整理日期欄位，留下畫圖設定，之後換資料再跑。不適合期待完全免程式操作的人。本次沒有驗證其他圖型、即時更新或長期自動執行；這些不影響已完成的兩張靜態圖，也不能算進本次成果。

專案：[mplfinance](https://github.com/matplotlib/mplfinance)。授權採專案自有的 [LICENSE agreement](https://github.com/matplotlib/mplfinance/blob/493811d/LICENSE)，GitHub 未提供標準 SPDX 判定；使用或散布時應閱讀原文並保留要求的授權與著作權聲明，不自行標成 MIT。資料來源：[證交所個股日成交資訊](https://www.twse.com.tw/exchangeReport/STOCK_DAY?response=json&date=20261001&stockNo=2330)。


## 影片版面修訂

本次依審片意見把整片改成深藍金融報表。畫面中的K線、五日與十日均線、成交量圖及價格表，沿用上述實測產物；外框、日曆與教學卡為影片重排，不是工具內建操作介面。資料仍截至2026年10月27日，沒有把重剪日期說成新的行情查詢。
