Taiwan Stock:把交易紀錄變成含費用的回本價與領息月曆
在本機記錄台股與 ETF 交易,自動同步證交所、櫃買中心與公開資訊觀測站的行情、配息及股票異動,試算含費用回本價、扣息回本價與每月預計領息。
Taiwan Stock 是在本機執行的投資紀錄工具,支援上市與上櫃的股票及 ETF。交易由使用者輸入,股票清單、收盤價、配息、股票股利與上下市狀態則盡量從證交所(TWSE)、櫃買中心(TPEx)與公開資訊觀測站(MOPS)自動同步,所有資料都存在本機的 SQLite 資料庫。
問題與目標
想知道一筆投資到底賺了多少,除了買進成本,還得算進賣出時的手續費與證交稅,以及這段期間已經領到的股利;持股分散在不同券商帳戶時,就得自己把數字加總。持有多檔 ETF 時,還要整理每一檔的除息日、發放日與金額,才知道下個月會領到多少錢。
這個專案的目標,是讓交易紀錄成為唯一需要手動維護的資料,其餘的行情、配息與股票異動都自動補齊,並直接回答三個問題:
- 全部賣掉的話,含所有費用的回本價是多少?
- 扣掉已經領到的配息後,回本價又是多少?
- 這個月、下個月預計會領到多少股息?
設計考量
- 單人、單機使用:資料庫與網站都在使用者的電腦上執行,預設只接受本機連線
- 金額必須精確,手續費與證交稅依商品種類及交易日期當時的法規計算
- 官方來源各有不同的格式、更新時間與請求頻率限制,同步失敗時不能寫入錯誤的資料
- 分割、股票股利等事件要能套用到持股,但不能改寫原始的交易紀錄
使用方式
安裝後執行:
taiwan-stock web
程式會在 http://127.0.0.1:2330 啟動本機網站並開啟瀏覽器。網站提供六個頁面:
| 頁面 | 用途 |
|---|---|
| 我的持股 | 市值、未實現損益、當日損益、殖利率,以及每筆持股的回本價 |
| 領息月曆 | 依持股試算每月預計領息,可依證券帳戶或領息銀行篩選 |
| 交易紀錄 | 逐筆買賣與期初持股,費用自動試算,支援 CSV 匯出與預覽後匯入 |
| 商品查詢 | 查詢股票與 ETF,包含規模、受益人數、保管銀行與配息頻率 |
| 股票異動 | 自動同步分割與股票股利,官方來源未涵蓋的事件可手動補登 |
| 備份與設定 | 資料庫備份與還原、手續費折扣與證券帳戶管理 |
第一次使用時,先在「商品查詢」頁按「同步商品名單」,取得上市櫃股票與 ETF 清單,再到「交易紀錄」新增交易或匯入 CSV;之後在首頁按「同步最新股價」,即可更新行情與損益。
以下截圖使用示範資料:股票清單、收盤價與配息為 2026 年 11 月同步的官方公開資料,證券帳戶與交易紀錄則是虛構的。
我的持股
首頁上方顯示總市值、未實現損益、持有成本與當日損益。展開任一筆持股,可以看到含買賣費用的回本價、扣除已領配息後的扣息回本價,以及每一批買進各自的成本與報酬率。

領息月曆
依照目前持股與各商品的除息、發放日期,試算每天預計入帳的股息。官方尚未公布金額的配息會標示「待確認」,月合計只加總已知的金額,不會自行推估。

商品查詢
ETF 列表整合了證交所、櫃買中心與各投信的資料,可以一次比較規模、受益人數、保管銀行、配息頻率、下次配息與近一年殖利率。

三個關鍵設計
1. 交易紀錄是唯一的事實來源
資料庫不儲存持股或成本的計算結果。每次查詢時,都從交易紀錄依先進先出(FIFO)重新計算持股、批次成本與回本價,並在計算當下套用分割與股票股利。例如 0050 在 2025 年 1 股拆 4 股,拆分前買進的 1,000 股會顯示為 4,000 股、均價同步除以 4,原本的交易紀錄則維持不變。
新增或修改交易前,程式會把該帳戶、該商品的完整交易歷史重新計算一次;若修改後會出現「賣出的股數超過當時持有」的情況,就直接拒絕寫入。
2. 金額不使用浮點數
所有金額與單價都以 Python Decimal 計算,並以文字格式儲存在 SQLite,避免浮點數的進位誤差累積在回本價與殖利率上。
手續費依設定的折扣試算,證交稅則依商品種類與交易日期套用當時的法規,例如被動式債券 ETF 的免稅期間及股票當沖的減稅期間。法規期限接近時,畫面會提醒之後將依當時已生效的規定計算。
3. 同步任務獨立於網站執行
同步由獨立的 Python 程序執行,網站只負責送出任務並顯示進度。重新整理頁面或重新啟動網站,都不會中斷正在執行的同步;網站與 CLI 送出的任務透過跨程序的鎖互相排除,同一個資料來源不會同時被兩個任務寫入。
官方來源有請求頻率限制,全市場同步可能需要數十分鐘。程式會控制請求間隔;若判斷遭到限流,會提前停止並印出重試指令,之後只需重試尚未完成的部分。寫入前也會驗證日期、欄位與年度是否合理,有疑慮的資料寧可不寫入,也不會讓錯誤資料進入持股計算。
系統架構
flowchart LR
Sources[TWSE / TPEx / MOPS<br/>投信網站] -->|行情、配息、異動| Worker[同步程序<br/>驗證 / 限流 / 重試]
Worker -->|交易式寫入| DB[(SQLite)]
CLI[CLI] -->|送出同步任務| Worker
Web[Web 介面<br/>FastAPI / Jinja2] -->|送出同步任務| Worker
Web <-->|交易與查詢| DB
Web --> Browser[本機瀏覽器]
網站預設只綁定 127.0.0.1,並檢查每個寫入請求的 Host 與 Origin,擋下其他網站發出的跨站請求。程式沒有登入機制,若改為綁定其他網路介面,啟動時會顯示警告。資料庫可在設定頁備份與還原;網站無法開啟時,也能用 taiwan-stock backup restore 從終端機還原。
成果
- 輸入交易後,即可看到含費用回本價、扣息回本價、成本殖利率與實際領息殖利率
- 從空白資料庫開始,同步上市櫃約 2,000 檔股票、近 400 檔 ETF 的清單、收盤價、配息與 ETF 基本資料
- 自動化測試涵蓋超過 1,200 個測試案例,包含持股重算、費用與稅率、官方資料解析、同步任務與網站操作
取捨與後續方向
專案採用單機、單人的架構,持股在每次查詢時即時計算。以個人數百筆的交易量來說效能綽綽有餘,也省下維護計算結果與原始資料一致性的複雜度;相對地,目前不支援多人共用與遠端存取。
官方來源未涵蓋的情況,例如較早年度的股票異動,仍需手動補登。未來可以加入更多投信資料來源,並延伸資產配置與歷史報酬的圖表。
使用技術
- Python 3.13、
argparse與decimal - SQLite 結構版本管理、交易式寫入與跨程序鎖定
- FastAPI、Jinja2、Uvicorn 與 httpx2
- Pytest、Ruff、pip-audit 與 pre-commit