跳至主要內容
台股研究 約 9 分鐘閱讀

揭秘庫藏股:庫藏股投資策略再優化,
年化 28% 回測(Part 2)

重跑 1,308 個庫藏股事件並修掉兩處前視偏差後:年化 28.26%、日夏普 1.19,勝過同視窗 0050 含息的 16.30%、0.83。但報酬全在買回起日那一根,進場延後一個交易日就從 28.26% 變成 -0.51%。附事件研究逐日超額報酬與時點敏感度實測。

修掉前視偏差後庫藏股事件策略年化 28.26% 仍勝大盤,但晚一天進場就從賺變賠。 CAGR 28.0%

摘要

2026-07-30 用現行資料重跑,並修掉原文兩處拿不到的資訊之後:年化 28.26%、日夏普 1.19、最大回撤 -29.8%(2010-02-02 至 2026-07-30,共 16.5 年,1,308 個事件);同視窗 0050 含息買進持有是年化 16.30%、日夏普 0.83、最大回撤 -34.0%。 原文宣稱的「年化約 30%」方向站得住,可執行版本落在 28% 出頭。

依本文重跑

執行這個策略

複製提示詞,讓 AI 依照上方證據的資料、條件與風險檢查重跑一次。

告訴你的AI:

幫我設定 FinLab,重現這篇文章,請讀:https://finlab.finance/setup?relatedUrl=/blog/treasury-stock-buyback-strategy-part2

免安裝,開啟 FinLab Studio

兩件原文沒有交代的事,比報酬數字更重要。第一,報酬幾乎全部集中在買回起日當天那一根:進場延後一個交易日,年化從 28.26% 變成 -0.51%,由賺變賠。第二,原文的估值過濾用的是當天收盤才算得出來的股價淨值比,而下單時點在當天開盤,這是一天的前視偏差;把它改成前一日的值以後,年化反而由 24.07% 升到 28.26%。這 4 個百分點不該當成「修正帶來的績效」:兩次回測都只有 1,308 個事件,這種量級的差距在樣本內本來就會晃動。要改的理由是可執行性,不是報酬。

下面把三件事攤開:宣告前後的超額報酬長什麼樣、為什麼進場差一天會由賺變賠、以及哪些設定看起來很美但根本不能執行。完整程式碼與下載檔在 VIP 段。

這次重跑修了什麼

原文寫於 2024 年初,留下的是截圖與結論,沒有可以自己重跑的腳本,也沒有和大盤對照。這次補上真實指標、事件研究逐日數字與一份可執行腳本,並修掉三個問題。

問題一:程式碼在現行資料上會直接中斷。 treasury_stock:預定買回期間-起 目前有 5,830 筆揭露紀錄,其中 1 筆是同一檔股票在同一天出現兩個買回案,pivot 遇到重複索引會拋出 Index contains duplicate entries

問題二:估值過濾用到當日收盤。 原文以買回起日當天的股價淨值比篩選,但部位在當天開盤就進場,當天的收盤價那時還不存在。固定其他所有條件、只把這個過濾換回當日值重跑,年化是 24.07%、日夏普 1.05、回撤 -31.2%;改用前一日值之後是 28.26%、1.19、-29.8%。也就是說這處前視偏差並沒有把成績做得更漂亮,反而略差,但它讓策略在現實中無法照著執行,所以還是要修。

問題三:有些事件本來就不可能執行。 揭露日不早於買回起日的事件共 280 筆(占 4.8%),在買回起日開盤時消息還沒公開,這些已全部排除。

事件數的收斂過程:5,830 筆原始紀錄,去重掉 1 筆、排除 280 筆不可執行的,再對齊到交易日(買回起日不是交易日、或落在價格資料開始之前的事件會被丟掉)之後剩 3,804 個事件;加上股價淨值比小於 1 的過濾,最後 1,308 個事件進入策略。

事件研究:超額報酬集中在哪一天

把每個事件對齊到「預定買回起日」當作 T=0,計算個股相對 0050 含息的每日超額報酬,以 T-1 收盤當基準累積:

庫藏股宣告事件研究:相對 0050 含息的累積超額報酬與逐日柱狀圖,漲幅集中在買回起日當天

逐日平均超額報酬(相對大盤):

交易日 全部事件(n=3,755) 股價淨值比 < 1(n=1,302)
T-3 -0.55% -0.34%
T-2 -0.50% -0.35%
T-1 +0.18% +0.25%
T+0(買回起日) +2.27% +2.88%
T+1 +0.56% +0.62%
T+2 +0.26% +0.23%
T+5 +0.11% +0.11%

三個讀得出來的事實。第一,宣告前這些股票在下跌:T-3 到 T-2 每天相對大盤跌 0.3% 到 0.55%,全部事件那組往前推到 T-20 累積跌約 6.2%,低估值那組 4.9%。公司在股價走弱時宣布買回,符合庫藏股的制度用途。第二,超額報酬集中在 T+0,全部事件 +2.27%、低估值那組 +2.88%,單日就占掉往後四十天累積量的 48.6% 與 41.3%。第三,宣告後的漂移存在但很慢:以 T-1 為基準,全部事件的累積超額報酬 T+1 是 +2.83%、T+5 +3.60%、T+20 +4.62%、T+40 +4.68%;股價淨值比小於 1 的那組更高,T+40 為 +6.97%。

這裡要修正原文的一句話。原文寫「到第四十天就沒有漲幅了,到最末尾甚至有一點跌幅」;以 0050 含息當基準量測,超額報酬在 T+20 之後幾乎停止累積,但沒有翻負,低估值那組還在緩步上升。停止累積代表早點出場沒有損失,由正翻負代表抱久會還錢,實際情況是前者。

為什麼進場差一天,由賺變賠

先講回測引擎的成交慣例:finlab 的部位在訊號日的隔一個交易日成交。所以 position.shift(-1) 把訊號往前挪一天,實際成交就落在買回起日 T+0 的開盤;不做這個位移,成交會落在 T+1 的開盤。

庫藏股策略進場時點敏感度:提前一日年化 28%,不提前變成 -0.5%

進場時點 成交在 年化報酬 日夏普 最大回撤 能不能執行
shift(-2) T-1 開盤 141.43% 3.37 -17.4% 不能,消息還沒公開
shift(-1)(原文設定) T+0 開盤 28.26% 1.19 -29.8% 可以
shift(0) T+1 開盤 -0.51% -0.03 -53.4% 可以,但晚一天
shift(1) T+2 開盤 -0.25% -0.03 -59.5% 可以,但晚兩天

對照上一節的逐日表就知道原因:T+0 有 +2.27%、T+1 只有 +0.56%、T+2 以後每天剩零點幾個百分點。晚一天進場等於把最肥的那一根讓掉。剩下的漂移之所以撐不住,主要不是稅費:以開盤價成交會放掉買回起日收盤到隔天開盤那段跳空,而這段正好包在 T+1 的 +0.62% 裡;再加上同時只持有三到四檔的集中度,單一事件失手對淨值的拖累就被放大。

shift(-1) 為什麼算拿得到的資訊?看揭露日與預定買回起日的落差:95.2% 的事件,揭露日至少比買回起日早 1 個日曆日(中位數正好 1 天)。公司在買回起日之前就公告了,你在前一天收盤時已經知道,於是可以掛 T+0 的開盤單。剩下 4.8% 揭露日不早於起日的事件無法這樣執行,已在資料處理階段排除。

shift(-2) 的 141% 呢?它成交在 T-1 的開盤,比多數公告的揭露時點更早,等於在消息公開前買進,賺到的是資訊落差而不是策略。任何人拿這支策略往前多位移一天,都會看到年化跳到三位數,那是踩到前視偏差,不是找到聖杯。

績效與基準對照

用可執行的設定(前一日股價淨值比小於 1、揭露早於起日、T+0 開盤買、持有 5 個交易日):

庫藏股事件策略與 0050 含息的淨值曲線對照,對數刻度

指標 庫藏股事件策略 0050 含息買進持有
年化報酬 28.26% 16.30%
日夏普 1.19 0.83
日索提諾 2.22 1.13
月夏普 1.09 0.80
最大回撤 -29.8% -34.0%
區間 2010-02-02 至 2026-07-30(16.5 年) 同左

兩邊的夏普都用 finlab get_stats() 的口徑、扣掉 2% 無風險利率後計算,所以可以直接比。策略贏在報酬與風險調整後報酬,回撤也比大盤淺 4 個百分點。

下面是這次重跑的互動式回測報告,可以自己拉時間軸看每一段的表現與持股明細:

要注意這是 16.5 年裡 1,308 次進出堆出來的結果,平均一年約 79 個事件、每次只持有 5 個交易日,屬於高換手的事件型策略,不是抱著不動的長期部位。

持有天數與估值過濾

庫藏股策略持有天數與估值過濾網格

六種設定都切在同一視窗(2010-02-02 起)才能比較:

設定 年化報酬 日夏普 最大回撤
股價淨值比 < 1,持有 5 日 28.26% 1.19 -29.8%
股價淨值比 < 1,持有 10 日 25.73% 1.14 -33.8%
股價淨值比 < 1,持有 20 日 33.94% 1.45 -31.1%
全部事件,持有 5 日 16.97% 0.68 -39.1%
全部事件,持有 10 日 19.11% 0.84 -33.9%
全部事件,持有 20 日 22.95% 1.13 -30.4%

估值過濾是主要的報酬來源:同樣持有 5 日,加上股價淨值比小於 1 之後年化由 16.97% 升到 28.26%,日夏普由 0.68 升到 1.19。不加這個過濾的版本年化 16.97%,和大盤的 16.30% 幾乎沒有差別,卻要承擔 -39.1% 的回撤,白忙一場。持有天數則不敏感:5、10、20 日都落在 26% 到 34% 之間,20 日版本反而最高,說明宣告後的緩慢漂移仍有貢獻,只是遠不如 T+0 那一根。

方法與限制

  • 稅費:手續費以 1.425‰ 的兩折計算(0.285‰),證交稅 3‰ 由 finlab sim() 對台股預設套用,所以上表的 28.26% 已經是扣掉手續費與證交稅之後的數字,不需要再自行打折。
  • 成交價假設:以開盤價成交。買回起日的開盤常常跳空,回測拿到的是開盤價本身,沒有模擬滑價,也沒有考慮開盤搓合買不到的情況。
  • 流動性與容量:沒有做成交量或市值過濾。庫藏股宣告在小型股上更常見,同時持股檔數平均只有個位數,資金量放大後這部分報酬會先被吃掉,屬於容量受限的策略。
  • 前視偏差:兩處已修(估值過濾改用前一日值、排除揭露不早於起日的事件)。shift(-2) 是刻意保留的不可執行對照組,列出來是為了讓讀者看到往前位移的誘惑與代價。
  • 樣本流失:5,830 筆原始紀錄到 1,308 個進場事件,中間流失來自去重、排除不可執行事件、對齊交易日與估值過濾,各步數字都在上面列出。
  • 標的範圍:計算範圍就是 finlab 收盤價資料表的所有上市櫃股票,沒有排除金融股、KY 股或全額交割股。
  • 換手率與樣本外:平均一年約 79 個事件、每次持有 5 個交易日,稅費敏感度高。本文沒有切分樣本內外,frontmatter 標記 in_sample_only;策略只有兩個參數(估值門檻與持有天數),過度配適空間小,敏感度就是上面那張網格。

學術上怎麼看庫藏股宣告

開放市場買回後的異常報酬是財務文獻的經典題目。Ikenberry、Lakonishok 與 Vermaelen (1995) 研究美股 1980 到 1990 年的開放市場買回,發現宣告後四年的異常報酬達 12%,並指出市場對買回訊號反應不足,效果在帳面市值比高的價值型公司身上最強。Peyer 與 Vermaelen (2009) 用更長的樣本重驗,確認這個異常沒有隨時間消失,並把來源指向分析師過度悲觀之後的修正。

本文量到的台股結果和這條文獻一致的地方是低估值那組的超額報酬更高(T+40 累積 +6.97% 對全體 +4.68%),這正是 Ikenberry 等人所說的價值效應。不一致的地方是時間尺度:美股文獻談的是數年的緩慢修正,台股資料的反應集中在買回起日當天,之後的漂移很小。同一個制度訊號在不同市場的定價速度差很多,這也是把美股論文的持有期直接搬到台股會失望的原因。

誰能執行、誰不該碰

能執行的條件很硬:你要在盤後追蹤重大訊息公告、當晚就把隔天的開盤單準備好,而且接受開盤跳空的價格。做得到,這支策略在過去 16.5 年年化 28.26%,勝過大盤的 16.30%;做不到而延後一天,年化就是 -0.51%,連本金都留不住。

不適合的情況同樣清楚:想用盤中判斷進場點、資金量大到會影響小型股開盤、或是無法承受高換手帶來的稅費,都不該用這個版本。名詞定義(庫藏股、股價淨值比、夏普比率)可以查 FinLab 名詞庫;想理解庫藏股制度本身,先讀 庫藏股是什麼;想看庫藏股在大盤層級當底部訊號的用法,看 庫藏股與底部訊號;國安基金與庫藏股同時出手的情境在 國安基金與庫藏股分析;本文用到的估值因子細節在 股價淨值比選股策略;同屬事件型的信用交易題目可以對照 恢復信用交易策略優化;另一個事件型的法人題目在 外資連買選股。要判讀本文的風險調整後報酬,夏普比率是什麼 解釋了口徑;想把事件策略接進完整的選股框架,台股選股方法 是總覽。

VIP 段有完整可執行程式碼(年化 28.26% 的那一版)、三個下載檔,以及把 SHIFT 改成 0 立刻看到 -0.51% 的驗證方式。


投資有風險,過去績效不代表未來表現。本內容僅供教學參考,不構成投資建議,請依個人風險承受度審慎評估。

最後更新:2026-07|回測區間:2010-02-02 至 2026-07-30|作者:FinLab 量化研究團隊

VIP 區域包含策略細節

登入後可看策略優化、完整程式碼與互動式回測報告

FinLab AI

想建立自己的策略?

用自然語言描述你的選股想法,AI 自動驗證、回測、給你答案

免費開始

更多價值與基本面研究

查看全部