打通五個免費資料源,讓總經大事件自動整合進你的 Google Calendar
不付錢、不手動更新、FOMC/BOE/ECB/BOJ/CPI 全包的技術更新記錄
打通五個免費資料源,讓總經大事件自動整合進你的 Google Calendar
不付錢、不手動更新、FOMC/BOE/ECB/BOJ/CPI 全包的技術更新記錄
前幾年股市的走勢幾乎都圍繞著總體經濟,FOMC 的每一次決議都能牽動全市場。那段時間我最常用的工具之一是財經 M 平方的總經月曆,整合在 Google Calendar 裡的體驗非常好,研究員幾乎把它當基礎設施在用。
問題是那個月曆只開放給付費用戶。我去看了 investing.com 和 TradingView,同樣的功能也都要付費才能整合進 Google Calendar。
所以我決定自己串一個免費版本,把我認為最重要的那幾個總經事件,盡可能對接各國政府和機構的公開資料源,做成一個完全不需要付費的月曆。
這個工具叫 global-macro-calendar,FOMC、BOE、ECB、BOJ、美國 CPI/PPI/非農就業全包,大部分的事件接 API 自動更新,只有少數幾個因為技術限制需要每年年底手動更新一次。可以直接訂閱我維護的公開月曆,也可以 Fork 自己部署。
可以直接訂閱公開月曆,或 Fork 自己部署。詳細步驟在 README。
這篇文章記錄開發過程中遇到的四個技術問題和對應的應對方法,一起看下去吧!
約束條件:必須完全免費
整個工具的運行成本必須是零,這個限制從一開始就確立了。
技術選型因此很直接:GAS(Google Apps Script)寄生在 Google 帳號上免費運行,有內建的 cron 觸發器,可以直接寫入 Google Calendar API,不需要另開伺服器。資料源同樣只用公開 API 的免費版,或直接爬各央行的官網。
問題一:有些央行頁面 GAS 根本進不去
FOMC、BOE 的官網是靜態 HTML,GAS 的 UrlFetchApp 可以直接解析,沒有問題。
ECB 的行程頁面是 JS 渲染,GAS 沒有瀏覽器引擎,拿到的 HTML 是空殼。BOJ 同樣的情況,而且日銀的頁面結構更難處理。
應對方法:
對這兩個央行改用硬編碼。在 fetchHardcodedEvents() 裡維護一個手動更新的日期陣列,每年 10 月更新一次。明知道手動維護不優雅,但相比引入 Puppeteer 或外部服務,這個取捨顯然合理。為了讓自己不忘記,腳本在每年 11/15 自動寄一封提醒信到指定信箱。
問題二:美國數據的官方來源封鎖了 GAS
BLS.gov(發布 CPI/PPI)直接封鎖 GAS 的 IP 段,測試了幾個替代 URL,全部 403。
應對方法:
因此改用 Finnhub 的免費 API。代價是 Finnhub 免費版只提前一到兩週有數據,所以腳本不能只跑一次,必須每天跑一次持續填補。
這個選擇也確立了整個架構的節奏:每天 21:00 台北時間執行,同步未來 13 個月的事件。
問題三:夏令時間
各央行時區不同,多數時區有夏令時間。FOMC 在紐約時間 14:00 宣布,但冬令和夏令相差一小時;BOE 在倫敦時間,和台北的時差也會隨季節浮動。
應對方法:
用 JavaScript 內建的 Intl API 處理時區換算,不自己維護時差對照表。Intl.DateTimeFormat 支援完整的 IANA 時區字串,DST 的計算交給標準庫。
問題四:重複寫入
腳本每天跑,同一個事件可能在連續 30 天內都被偵測到並嘗試寫入月曆。
應對方法:
寫入前先查。createEventIfNotExists() 在同一天裡找標題相同的事件,找到就跳過,找不到才建立。邏輯簡單,每次同步的事件數量也就幾十筆,效能上不是問題。
最終架構
六個 fetch function 各自負責一個資料源,主函式統一收集、過濾 13 個月內的事件、去重後寫入 Calendar。cron 觸發器用自我排程方式避免累積(每次跑完刪掉舊 trigger,建一個明天的新 trigger)。
沒有資料庫、沒有伺服器、沒有付費 API。唯一需要人工介入的是每年 10 月更新 ECB 和 BOJ 的日程,大概需要十分鐘。
메타데이터
- post_id
- 3eef6ff16de5
- slug
- 打通五個免費資料源-讓總經大事件自動整合進你的-google-calendar-3eef6ff16de5
- url
- https://medium.com/@yyu0310/%E6%89%93%E9%80%9A%E4%BA%94%E5%80%8B%E5%85%8D%E8%B2%BB%E8%B3%87%E6%96%99%E6%BA%90-%E8%AE%93%E7%B8%BD%E7%B6%93%E5%A4%A7%E4%BA%8B%E4%BB%B6%E8%87%AA%E5%8B%95%E6%95%B4%E5%90%88%E9%80%B2%E4%BD%A0%E7%9A%84-google-calendar-3eef6ff16de5
- canonical_url
- https://medium.com/@yyu0310/%E6%89%93%E9%80%9A%E4%BA%94%E5%80%8B%E5%85%8D%E8%B2%BB%E8%B3%87%E6%96%99%E6%BA%90-%E8%AE%93%E7%B8%BD%E7%B6%93%E5%A4%A7%E4%BA%8B%E4%BB%B6%E8%87%AA%E5%8B%95%E6%95%B4%E5%90%88%E9%80%B2%E4%BD%A0%E7%9A%84-google-calendar-3eef6ff16de5
- author_url
- https://medium.com/@yyu0310
- status
- ok
- fetched_at
- 2026-06-25 12:15:08