如果你只記一句話:這是一個每天跑一次的小工具——用 Google News RSS 抓台美股市場與產業新聞,英文標題丟 FinBERT 打情緒分數,中文新聞只列熱度不硬評分,最後產出三份檔案:市場情緒 CSV、Markdown 快報、加上情緒參考欄位的選股清單。
上一篇手記(從 Hugging Face 到 FinBERT)講的是「為什麼」——FinBERT 怎麼把情緒雜訊變成可量化的分數。這篇講「怎麼用」:我把它落成了一個每天可執行的小專案,這裡是完整的使用說明。
先講清楚它不是什麼:這不是交易系統,不預測市場漲跌,不下單。FinBERT 只是在判定「這段英文金融文字的語氣」,分數不是報酬機率,更不是買賣訊號。整個工具的定位是:每天早上幫我把「市場在講什麼、語氣偏多還是偏空」整理成一頁,當成盤前讀物。
資料流程
Google News RSS(市場/產業主題 + 個股 query)
│
├─ 英文新聞 ──→ FinBERT(ProsusAI/finbert)──→ 利多/中立/利空 + 信心分數
│
└─ 中文新聞 ──→ 只保存與統計篇數(不硬套英文模型)
│
▼
統計:篇數、正/中/負篇數、平均與加權情緒分數、極端標題
│
▼
輸出三份檔案(output/)
1. daily_market_sentiment_YYYY-MM-DD.csv ← 每主題一列的統計
2. daily_market_report_YYYY-MM-DD.md ← 繁中快報(人看的)
3. stock_candidates_with_sentiment_...csv ← 選股清單+情緒參考欄位
設計原則是「小而可用」:單機、單進程、無資料庫、無付費 API、無排程服務。只抓 RSS 的標題與摘要,不抓全文、不繞付費牆。所有時間以 Asia/Taipei 顯示,並保留 UTC 原始欄位供日後研究。
安裝(Windows PowerShell 與 WSL2 通用)
需要 Python 3.10–3.12(我用 3.11)。專案根目錄下:
python -m venv .venv
pip install -r requirements.txt
啟用虛擬環境:
# Windows PowerShell
.venv\Scripts\Activate.ps1
# WSL2 / Linux
source .venv/bin/activate
依賴就十個套件:feedparser、pandas、pyyaml、transformers、torch、sentencepiece、python-dateutil、tzdata、requests、tenacity,版本全部釘死在 requirements.txt。第一次執行會自動從 Hugging Face 下載 FinBERT 權重(約 440MB),之後走本地快取。CPU 就能跑(我這台沒有 GPU,device: auto 會自動退回 CPU);有 CUDA 的話會自動用。
每天只做兩件事
第一件:把今天的選股清單丟進 input/stock_candidates.csv。 格式很簡單:
ticker,company,market,language,news_query,existing_note
NVDA,NVIDIA,US,en,"NVIDIA OR NVDA stock",範例
TSM,Taiwan Semiconductor ADR,US,en,"Taiwan Semiconductor OR TSMC OR TSM stock",範例
2330.TW,台積電,TW,zh,"台積電 OR 2330 OR TSMC",範例
關鍵是 language 欄:en 的個股會被 FinBERT 評分,zh 的個股會被標記為 skipped_non_english——數值留空、報告寫「未評分(中文)」,绝不硬套英文模型。
第二件:跑 python run_daily.py。 幾個參數:
| 參數 | 作用 |
|---|---|
| (不帶參數) | 跑市場主題+個股清單,輸出三份檔案 |
--topics-only | 只跑市場/產業報告 |
--stocks-only | 只更新選股清單情緒欄位 |
--dry-run | 照抓照評分、顯示摘要,但不寫檔 |
--lookback-days 3 | 覆蓋回看天數(預設 2 天) |
--max-items 10 | 覆蓋每個主題/個股的抓取上限 |
不想手動跑就交給 Windows 工作排程器:動作填 .venv\Scripts\python.exe 的絕對路徑、參數填 run_daily.py、開始位置(Start in)填專案根目錄的絕對路徑,建議收盤後或晚間執行。
讀報告時要注意的三件事
一、中文新聞沒有分數,是刻意的。 FinBERT 是在英文財經語料上訓練的,直接套中文標題等於請一個只懂英文的分析師讀中文報紙——分數看起來有模有樣,其實是噪音。所以台股的五個主題(加權指數、櫃買、AI 板塊、半導體、電子零組件)只列新聞篇數和最新五則標題,讓我自己掃一眼,不給假分數。
二、情緒欄位是「參考」,不是「訊號」。 選股清單上每檔股票多出來的那欄情緒分數,只是研究時的背景資訊。報告裡固定印著這段警告:個股情緒欄僅供輔助,不得視為買賣訊號,請結合價格、成交量、基本面與樣本外驗證。
三、RSS 有它自己的坑。 Google News Search RSS 會有重複轉載(程式已做標題正規化去重)、搜尋誤差(query 抓到不相干的新聞)、以及發布時間偶爾解析不出來(保留資料但標 unknown)。它反映的是「Google News 收錄了什麼」,不是「市場發生了什麼」的全集。
給做量化研究的朋友:四個偏誤
如果之後想把這份情緒序列拿去回測,先過這四關:
- 新聞可得時間——新聞發布時間不等於你實際能看到的時間,回測若用發布時間對齊當日收盤價,就偷跑了幾個小時。
- 重複轉載——同一則新聞被三家媒體轉載,情緒分數會被灌水三倍,去重邏輯要對齊回測假設。
- 事後偏誤——用「今天知道哪些新聞重要」去挑選歷史新聞樣本,回測績效全是假的。
- walk-forward 驗證——任何參數(加權門檻 0.15、lookback 天數)都要只用當下可得的資料滾動驗證,樣本外不過關就不算數。
小結
這工具做的事很樸素:每天把幾十條新聞標題變成一頁溫度計。它的價值不在預測,而在強制我每天用同樣的鏡頭看一遍市場語氣——累積幾個月後,這份每日 CSV 就是一份乾淨的、可直接拿去做研究的心情序列資料。
模型與情緒分析的概念細節,請看上一篇:從 Hugging Face 到 FinBERT:幫自己的交易裝上一副情緒天線。