把財報日丟進台積電的波動率模型——它真的有用嗎?
讀者互動
已追蹤瀏覽 0 次,登入會員可按讚與收藏。
把財報日丟進台積電的波動率模型,它真的有用嗎?
一個簡單的疑問:如果模型已經有 VIX,再加上「今天是不是台積電財報日」這個訊號,會不會讓波動率預測更準?我們在 2330.TW 上跑了 1697 個交易日的滾動驗證,答案是: 不會,而且方向還反了一點點 。這篇文章誠實記錄這個失敗,並說明為什麼這個失敗很重要。
[提出: 賴奕豪, 執行: Claude]
一個合乎直覺的假設,最後沒過
研究有個常見場景:你看著一個跑得不錯的模型,覺得「再多加一個變數應該會更好吧?」於是加了下去,結果發現,沒有。
這篇文章講的就是這樣一個故事。
我們手上有一個叫 A4f 的波動率模型。它的長期成分用一個變數來抓系統性不確定性: VIX (美國恐慌指數)。實作上,模型每天用昨天的 VIX 平方來預測今天台積電的波動率長期水準,再用一段 GARCH 結構抓短期波動的群聚。
這個架構本身已經被前面幾個實驗(K1058、K1059)驗證過,在 0050.TW 上,它跑得比傳統 GJR-GARCH 還好,特別是在「事件日」前後(財報、FOMC 之類)優勢更明顯。
那很自然的下一步: 把「財報事件」這個訊號明確放進長期成分裡 ,看會不會更準。
於是我們設計了 A4f+EAV 模型。EAV 是「Earnings Announcement Variable」的縮寫,當天是台積電財報公告日就是 1,其他日子是 0。實作上 code 採用保守 lag:先把公告日映射到「第一個 ≥該日期的交易日」,再額外 lag 1 day,所以即使公告時間落在盤中也不會發生同日洩漏(不依賴逐筆驗證盤後/盤中公告,原始 財報公告日.txt 也只有日期欄位、沒有公告時間欄位)。
數學式長這樣:
- 原版 A4f :今天的長期波動率水準 = θ₀ + θ₁ × 昨天的 VIX 平方
- 加強版 A4f+EAV :今天的長期波動率水準 = θ₀ + θ₁ × 昨天的 VIX 平方 + θ₂ × 昨天是否為財報日
如果 θ₂ 顯著大於 0,就代表「財報日的隔天波動率會被模型多算一些」,而且這個調整真的有用。
結果:θ₂ 平均是負的,t 檢定也站不住腳
樣本期間 :2010-01-05 ~ 2025-12-30,共 3911 個交易日的台積電日資料。 滾動視窗 :用前 2000 天估計、每 63 天(一季)重估一次。 OOS 期間 :2019-01-01 ~ 2025-12-30,共 1697 個交易日,27 次重估,包含 28 個財報日。
我們把兩個模型在這 1697 天並行跑,逐日比較它們對「明天波動率」的預測誤差(用 QLIKE 這個指標,是 Patton (2011) 提出對波動率代理偏誤穩健的損失函數)。
主結果:
| 指標 | 原版 A4f | 加 EAV 版本 |
|---|---|---|
| 平均 QLIKE 損失 | 2.8877 | 2.8897 |
| 排序相關(預測 vs 實際) | +0.2200 | +0.2144 |
| 樣本數 | 1697 | 1697 |
| QLIKE 改善幅度 | — | -0.070%(變差) |
兩模型比較檢定的統計強度只有 0.348 ,遠遠達不到嚴格統計檢驗門檻(這個門檻是 嚴格統計, Harvey et al. (2016) 為了控制金融研究的多重檢定問題建議的高標)。 而且方向還是原版 A4f 略勝 ——加了 EAV 不是「打平」,是「微微變差」。
那 θ₂ 自己呢?我們有 27 個重估視窗,每次都會吐出一個 θ₂ 估計值:
| 統計量 | 數值 |
|---|---|
| 27 次估計的平均 | -0.000448 |
| 中位數 | +0.000042 |
| 為正的比例 | 59%(27 次中 16 次) |
| 對「θ₂ > 0」的單尾檢定 | 沒過 |
| Bootstrap 95% 信賴區間 | [-0.000987, +0.0000036] |
最戲劇性的是 bootstrap 信賴區間—— 上界 +0.0000036 幾乎就在 0 上面 。也就是即使最樂觀的情境,θ₂ 也只比 0 大一點點,根本沒有可行動的訊號量。

把樣本切到財報日隔天(T+1),會不會看到不一樣的東西?
「也許整體看不出來,是因為財報日本來就只有 28 天,被剩下 1669 天的雜訊蓋過去?」
這是合理的懷疑,所以我們把樣本切兩半,分別跑,注意此處的 event window 嚴格定義是 財報日隔天 (T+1) (code 採用 event_t1_mask,與 README 定義一致):
| 子樣本 | 樣本數 | 兩模型比較統計強度 | QLIKE 改善 |
|---|---|---|---|
| 財報日隔天(T+1) | 28 | +0.083 | -0.249%(更差) |
| 非事件日 | 1669 | +0.323 | -0.172%(更差) |
按理講,如果 EAV 真的捕捉了財報日的訊息,那「財報日隔天 (T+1)」應該要比「平日」表現更明顯,我們預期事件日的統計強度要大一些。 但結果反過來:事件日的統計強度(0.083)比平日(0.323)還小,而且兩邊都是 A4f 原版略勝。
EAV 旗標在它最該發揮作用的日子,反而最沒有用。

這個失敗為什麼有意義,兩個假設的對決
故事其實有個更大的背景。
在這個實驗之前,我們已經在 0050.TW(台灣 50 ETF)上做過同類測試(K1064),結果三種權重方案(等權重、產業權重、前 50 大)的 EAV 指標 全部失敗 ——QLIKE 改善從 -0.205% 到 -0.419%,沒一個是正的。
當時有兩個競爭假設可以解釋這個失敗:
| 假設 | 說法 |
|---|---|
| H_div(分散稀釋) | 50 檔股票每家財報日不同,加總平均後彼此抵銷,個股的訊息在 ETF 層級被稀釋掉了 |
| H_vix(VIX 已吸收) | 不是稀釋的問題——是 VIX 這個變數已經把系統性不確定性吃光了,再加 EAV 邊際資訊量為零 |
如果是 H_div,那把實驗從 ETF 縮到「單一公司」應該會看到 EAV 浮出來。 如果是 H_vix,那即使縮到單一公司,EAV 還是不會起作用。
台積電是這個對決的最佳測試標的 ——它是台股權重最大的個股、財報日明確、樣本期長、有獨立的事件公告日歷。如果 EAV 在台積電身上都拉不出訊號,那 H_div 的解釋就站不住。
結果就是上面那張表—— 台積電的 EAV 也失敗了 。
我們把 K1067 的結果跟 K1064 的三個 ETF 變體並列:
| 對照 | QLIKE 改善(負值代表變差) |
|---|---|
| 台積電 A4f+EAV(本實驗) | -0.070% |
| 0050 等權重 | -0.205% |
| 0050 產業權重 | -0.207% |
| 0050 前 50 大 | -0.419% |

台積電的損失(-0.070%)確實比三個 ETF 變體都小一點,分散稀釋這個假設 有一點 證據(單一公司的訊號損失比 ETF 小一些)。但「比較不糟」不等於「有用」,台積電的 EAV 仍然是負改善,達不到顯著水準。
加總所有證據:
| 證據點 | 傾向哪個假設 |
|---|---|
| 單一公司層級依然失敗(H1 沒過) | H_vix |
| θ₂ 平均為負,bootstrap 上界幾乎跨 0 | H_vix |
| 事件日和非事件日都是 A4f 原版略勝 | H_vix |
| 台積電損失比 ETF 小 | H_div(弱) |
結論:H_vix 主導(with weak H_div + marginal H4 + 低檢定力 caveat) ——VIX 在這個架構裡似乎已經把系統性不確定性吸收得相當徹底,EAV 拿不到邊際資訊。但我們 沒有 做到排他性識別:H_div 仍有微弱證據(台積電 -0.070% 比 ETF -0.205%~-0.419% 都好)、H4「TSMC vs ETF」是 marginal PASS、單一公司只有 28 個 OOS 事件日,conditional DM 檢定力本就受限。本實驗的證據強度不足以完全排除 ETF 加總稀釋假說,只能說在 A4f+VIX 框架下 EAV 沒拿到顯著的增量訊號。
一個內部診斷數字也呼應這個結論
實驗執行前我們做了一個簡單的描述統計:在所有樣本內,台積電日報酬率平方(也就是當日波動率的代理)和「是否為財報日」這個二元旗標的相關係數是 -0.0011 。
換句話說: 樣本內這兩個變數本身就幾乎沒有線性關聯 。
這跟 K1060 前置研究一致,當時測了 10 檔台股個股的「財報日當天 r² / 平日 r²」,台積電的比值是 0.98(接近 1,代表財報日的波動率沒有比平日大),是 10 檔中最弱的訊號之一。對照之下,聯電(2303)的比值是 2.58,那才是「財報日波動真的會跳」的個股。
所以這個失敗其實是可以事先預期的 ——台積電本身就不是會在財報日「波動率噴出來」的那種股票。它太大、太多人盯、資訊太提早被消化。財報出來的當下,市場 likely already partially priced in(K1067 本身不直接量化這個 share,這是解釋性敘事不是本實驗推得的事實)。
給研究做下去的人三個提示
這個 NULL 結果直接影響我們論文 Paper 2 的設計。原本的計畫是把「台股財報事件因子」當成 A4f 的 exogenous regressor 之一,結果 K1067 告訴我們 這條路在 A4f 框架裡走不通 。三個方向的修正:
-
不要硬加,要換架構 :EAV 在 A4f 裡失敗不代表它沒有資訊,而是 A4f 裡的 VIX² 已經把那層資訊吸光。要看 EAV 真實貢獻,可以拿掉 VIX、改在純 GARCH 上測,那才是它的 fair test。
-
不要看指標,看 magnitude :把財報日從「0/1 旗標」換成「盈餘驚訝幅度」(actual EPS 減 consensus EPS 的標準化差),保留方向與強度,可能有機會拉出訊號。
-
不要選台積電,選 high-beta 個股 :台積電太「乾淨」,財報訊息提早消化。聯電(K1060 T+1 比值 2.58)這種規模較小、資訊不對稱較高的個股,做同樣的測試會比較公平。
寫這篇文章的初衷
研究會做出失敗的結果,這在學術研究裡是常態,但在外行讀者眼中常常被誤以為「白做了」。事實上, 這個 NULL 結果幫我們做了一件事 ——它 提供了證據傾向 H_vix 的解釋方向 (單一公司層級也拉不出 EAV 訊號),但 H_div 並未被完全排除。
如果我們沒做 K1067,論文裡就會出現一段「我們嘗試把 EAV 加進 A4f 模型,結果是 NULL,可能的解釋是分散稀釋」這種半截話。因為做了 K1067,我們可以寫得更精確:「我們在單一公司層級重做這個測試,結果仍是 NULL;證據加總後 H_vix(VIX 已吸收)相對 H_div(ETF 稀釋)更具支持,但因 H4 marginal PASS、single-firm 檢定力受限(28 OOS event days),無法做排他性識別。」
這就是為什麼研究誠實原則的第一條是「失敗也要如實報告」,失敗本身是有資訊量的,只是它的資訊量不在「找到了什麼」,而在「對哪個解釋方向多了一點證據」。
資料來源
- 2330.TW 日線資料 :yfinance(auto_adjust=True,自動處理除權息與分割),2010-01-05 ~ 2025-12-30,3911 個交易日。
- VIX 日收盤 :yfinance ^VIX,2010-01-01 ~ 2025-12-30,與台股交易日 forward-fill 對齊。
- 台積電財報公告日 :來自財報公告日.txt(Big5 編碼)filter code=2330,期間內共 64 筆,落入 60 個獨立交易日,其中 OOS 期間(2019-01-01 ~ 2025-12-30)28 個。原始檔只有日期欄位、沒有公告時間欄位。
- 預測時序 :所有訊號都是用 t-1 的資訊預測 t 的波動率,code 採用 lag-1 手動對齊(訓練端
eav_lag[1:] = eav_vals[:-1]、OOS forecast 端eav_lag_val = eav_arr[abs_idx - 1]),結構上排除同日洩漏;不是 pandas 的signal.shift(1),但等效。Garman-Klass 波動率代理也使用同一交易日的 OHLC 計算,與訊號日對齊。 - 隨機種子 :seed = 42(bootstrap、滾動估計初始值都固定)。
- 方法論依據 :Patton (2011) QLIKE proxy-robust loss function;嚴格統計, Harvey et al. (2016) 嚴格統計檢驗門檻;Engle, Ghysels & Sohn (2013) 長期成分變動率分解架構。
- 完整實驗紀錄 :experiments/k1067/(README.md、k1067.py、k1067_results.json、3 張圖表)。
引用實驗
K1067 — TSMC (2330.TW) Single-Stock A4f-EAV — Isolating the Diversification Channel(2026-04-12 完成)。本實驗為 K1064(0050 ETF 三權重 EAV NULL)的單一公司層診斷,配合 K1058(A4f baseline 驗證)、K1059(A4f vs GJR 事件窗放大)、K1060(10 檔個股財報日比值)、K1062(ETF T+1 比值 1.132)構成 Paper 2 的論證鏈。後續延伸 K1067e/K1067f(110 檔股票上的 EAV 與 VIX 通道獨立性驗證)顯示在不同模型架構下兩通道彼此乾淨無共線,進一步補強本實驗對「VIX 在 A4f 框架已吸收系統性不確定性」的結構性解釋。
[2026-05-09 Errata] 本文於 2026-05-08 發佈後,經 Codex 24h-rule audit 找出 6 處過度宣稱與 citation 錯誤,已校正:(1) SEVERE :原文「H_vix 主導」「可以判定問題出在 VIX 已吸收系統性不確定性,而不是 ETF 加總稀釋」改寫為「H_vix 主導 + 弱 H_div + marginal H4 + 低檢定力 caveat,無法做排他性識別」;(2) MAJOR-1 :event window 定義原文 L61/L72 寫「財報日當天」、表格 L69 寫「財報日隔天 (T+1)」前後不一致,現全文統一為「財報日隔天 (T+1)」與 code (event_t1_mask) / README 對齊;(3) MAJOR-2 :原文「Liu & Zhu (2016)」為 hallucinated citation,已改為實際使用的 Harvey et al. (2016);(4) MED-1 :原文「代碼有明確的 signal.shift(1) 對齊」literal 不對,已改為「lag-1 手動對齊(訓練端 eav_lag[1:]=eav_vals[:-1]、OOS forecast 端 eav_arr[abs_idx-1]),等效但非 pandas shift(1)」;(5) MED-2 :原文「台股財報是盤後公告,所以無 lookahead」過滿,改為「code 採保守 lag 1-day(公告日 → 第一個 ≥該日交易日 + 再 lag 1)+ Garman-Klass 同日對齊,不依賴逐筆驗證盤後/盤中公告」;(6) MINOR :原文「市場通常已經 price in 了七八成」改為「market likely already partially priced in(K1067 不直接量化此 share)」。本次修正不改主結論(K1067 H_vix 相對 H_div 較有支持),只把 narrative 強度收回到證據能撐住的範圍。
延伸閱讀
相關文章
先讀正式關聯,若無則使用標籤與主題相似度補齊