從對帳單 PDF 到多帳戶權益數:我如何用 Python + Cron 打造自動化資產與研報追蹤系統
個人常駐助理系列:解密加密 PDF 對帳單解析、多經紀商 API 串接、T+2 交割款時差計算與自動化券商研報爬蟲系統設計。

前言 (Introduction)
在建立個人常駐助理系統(Resident Assistant System)的過程中,最核心的價值並非大語言模型「有多會對話」,而是「能否提供穩定、精準、絕不偷懶的個人數據與市場資訊」。
在投資與資產管理上,我們每天常面臨兩個非常繁瑣的痛點:
- 多帳戶權益數散落各處:海外券商、本地期貨與現股帳戶各自有獨立的登入介面或電子對帳單。每天盤後手動登入各平台記帳極度耗時且容易遺漏。
- 市場研報資訊過載:各大券商每日發布大量研究報告與產業深度分析,若無自動化抓取與結構化歸檔,資料很容易淹沒在郵件海中。
為了讓個人助理具備真實可靠的資產感知與資訊研讀能力,我設計了一套基於 Python 與 Cron 排程的自動化管道:從每日解密電子對帳單 PDF、呼叫經紀商 API 結算權益數,到自動抓取券商研報並提煉知識圖譜。
架構設計 (Architectural Overview)
這套自動化追蹤系統的數據流可以分為「資產權益數結算」與「券商研報爬蟲」兩大獨立軌道:

系統運作的核心原則是:資料擷取與計算走確定性 Python 腳本,LLM 僅負責後置的自然語言提煉與知識連結。
這條管道每天 23:00 自動吐出的成果長這樣——三家券商、五個帳戶,權益曲線、回撤與配置比重全部由前面那些對帳單 PDF 與 API 回應堆疊而成:

金額全部馬賽克掉了,剩下的才是這篇文章真正想講的東西:曲線的形狀、回撤的深度、配置的比重。2025 年 4 月那道 −53.6% 的回撤是真的虧損(回撤走的是 TWR,已經把入金出金剝掉了);2026 年 6 月中那條綠色帶狀的躍升則是新帳戶入金,不是報酬。這兩件事在圖上長得幾乎一樣,唯一能分辨的方法是把現金流獨立記錄下來——這也是為什麼下一節要花那麼多篇幅講 T+2 與交割款。
方法論拆解 (Methodology Breakdown)
1. 破解黑盒:加密電子對帳單 PDF 的自動化解析
本地期貨與券商通常不會提供即時開放的 REST API,而是於每日收盤後將加密的電子對帳單 PDF 寄至使用者信箱。
為了在不依賴 OCR 辨識(OCR 速度慢且容易出現數字誤判)的前提下精確提取數據,我採用了純 Python 處理管線:
- 郵件收件箱監控:透過自動化腳本於傍晚定時掃描信箱中特定主題的對帳單郵件,下載 PDF 附件至本地隔離收件匣。
- 密碼安全解密:利用 Python PDF 處理庫注入環境變數中的加密密碼進行無損解密。
- 結構化文字與表格提取:利用 PDF 文字提取技術定位對帳單中的關鍵欄位(如「權益數」、「期貨保證金餘額」),以確定性正規表示式 (Regex) 提取精確金額。
這套純程式碼解析流程能達到 100% 的數字精確度,徹底消除了人工對帳與 OCR 影像誤判的風險。
2. 時差與未交割款計算 (T+2 Settlement Handling)
在計算股票現股帳戶的當日資產總額(NAV)時,我遇到了一個極具代表性的「假失真」坑:T+2 股票交割款時差。
當天賣出股票時,交易所會立即將股票從集中保管帳戶中扣除,但賣出所得的現金在 T+2 結算日之前,並不會反映在券商交割銀行的實際可用現金餘額中。如果直接計算「銀行現金 + 股票市值」,賣出股票當天的帳戶總資產會發生瞬間假摔;反之,買進股票當天則會發生瞬間假增。

為了解決這個問題,資產計算器引入了未交割款修正算式:
- 總資產金額等於「已結算銀行現金餘額」加上「未交割款應收/應付總額(T+1 / T+2)」再加上「當前持股總市值」。
- 透過向經紀商查詢當前未交割款明細,成功維持了資產總額在交易日與交割日之間的平滑與準確。
3. 多經紀商 API 整合與自動繪圖
對於提供開放 API 的海外券商與衍生品帳戶,系統利用 REST API 與輕量交易 SDK 定時抓取當前帳戶清算價值(Liquidation Value)與保證金權益數。
每日晚間收盤後(如 23:00),排程器會啟動資產彙整工作:
- 將各帳戶當日數字追加寫入本地 JSON 歷史檔案。
- 自動調用繪圖模組,產生多帳號資產走勢疊加圖。
- 將當日淨值與變動百分比格式化為 Markdown 表格,自動插入當天的每日反思日誌(Daily Journal)中。
4. 券商研報自動爬蟲與知識圖譜構建
除了資產追蹤,系統每日亦會自動執行券商研報爬蟲:
- 自動掃描並下載合作券商每日發布的個股與產業報告 PDF。
- 提取報告中的目標價、評等變更與核心論點。
- 將原始 PDF 與 Markdown 摘要分類歸檔至本地知識庫,並建立按個股標的與產業分類的索引標籤,使個人助理能在聊天視窗中隨時檢索原檔。
生產環境踩坑與優化 (Production Optimization)
1. 誤把「最新已知數值」充當「當天數據」
在早期版本中,當某個帳戶的郵件尚未寄達或 API 連線逾時,腳本若自動帶入前一天的數據並標記為今天,會造成持續數天的資產數據停滯卻不自知。解法是:無資料時明確標記資料缺失(Data Missing),並在日誌中顯示預警,直到資料真正補齊。
2. 郵件到達時間不固定
不同經紀商的結算郵件寄發時間並不固定(有些在傍晚 18:00,有些在晚上 21:30)。如果 Cron 排程太早執行,容易抓到空檔。為此,排程器設計了 4 天滾動補發視窗 (4-Day Window Backfill),每次執行時都會自動檢查並補齊過去 4 天內可能漏抓的日結對帳單。
3. PDF 格式變更與防護
券商偶爾會更換對帳單 PDF 的版型或表格排版。為防範版型變更導致提取金額錯誤,解析器加入了合理性邊界檢查:如果提取出的權益數變動超過單日預設百分比上限,系統會阻斷寫庫並發出警報,等待人工確認版型。
實例:交割款如何偽造出一次 −6.6% 的假崩盤
前面 T+2 那一段講的是機制,但機制我是在它騙過我之後才補上的。這裡把那天的數字攤開,因為它示範了這整套系統最危險的失效模式。
2026 年 7 月 9 日,現股帳戶做了一次換股:賣掉兩檔、減碼一檔、買進兩檔,賣超約當帳戶淨值的 6.9%。當晚排程跑完,Discord 收到的訊息是 −6.61%。
問題是那天帳戶其實幾乎沒動。當時的算式是:
NAV = 已結算現金 (acc_balance) + 持股市值
看起來很合理,錯在 acc_balance 是已結算現金。賣出的股票在成交當下就從市值消失了,但賣股所得要到 T+2 才會匯進交割帳戶。那筆錢在 7 月 9 日晚上既不在「市值」裡,也不在「現金」裡——它在半空中,而算式沒有一格能裝它。
向券商查 settlements() 才看到它躺在那:T=2, 交割日 7/13。加回去:
| 算式 | 已結算現金 | 持股市值 | 未交割款 (T+1/T+2) | 對前日變動 |
|---|---|---|---|---|
| 原本(錯) | ✓ | ✓ | ✗ | −6.61% |
| 修正後 | ✓ | ✓ | ✓ | +0.25% |
修正後的算式多了一項,正負號跟著交易方向走:賣出是「應收」為正,買進是「應付」為負,所以買進日的假暴增也一併修掉了。
NAV = 已結算現金 + Σ 未交割款 + 持股市值
這個修正之所以成立,是因為它在整個週期上自洽:等交割款入帳,未交割款歸零、現金增加同一筆數字,NAV 從頭到尾平滑。
真正值得記下來的是它為什麼難抓。一個 −6.61% 不會觸發任何警報——市場真的會跌 6%,前面那個「合理性邊界檢查」只擋得住版型解析錯亂級別的離譜數字,擋不住一個看起來完全像真的的數字。它沒有 crash,沒有寫 log,沒有紅字,就只是安靜地說了一個謊。在資料工程裡,會 raise 的錯誤是最便宜的錯誤;貴的是那種長得跟正確答案一模一樣的。
(順帶:用 API 清算價值 (liquidation value) 的海外券商帳戶完全沒這個問題——那個數字本來就含未交割部位。這個坑只屬於「自己把 NAV 加出來」的帳戶。)
總結 (Conclusion)
一個真正值得信賴的個人常駐助理,其底層必然建立在高穩定度、低維護成本的數據工程之上。
透過 Python 腳本處理加密對帳單 PDF、利用 API 結算多帳戶權益數、修正 T+2 交割時差,並以單一 Git Sweeper 進行純文字 Vault 歸檔,我們成功在完全不洩漏隱私與金鑰的前提下,打造了一座自動化個人資產與研報中心。
Reference
- Python pikepdf Documentation:基於 QPDF 的高效能加密 PDF 解密與處理庫。
- pdfplumber Documentation:精準提取 PDF 內文文字、表格與座標佈局的 Python 工具。
- Python matplotlib Documentation:自動化圖表繪製與趨勢圖生成。