創新高策略:用 AI 打造年化 48% 報酬的動能選股系統
股價創新高才買?你瘋了嗎?
這是多數投資人的第一反應。
但讓我們先看數據:在 2015-2025 年的台股回測中,單純買進「創 250 日新高」的股票,年化報酬率可達 19.1%,夏普比率 0.81。
如果再加入營收篩選優化,績效更可提升至年化 48%、夏普比率 1.55。
這篇文章,我會帶你用 AI 一步步探索這個現象,並建立一個可執行的量化策略。
提醒:以下為歷史回測結果,不代表未來表現。
市場現象:創新高的股票,後續表現如何?
在建立策略之前,我們先驗證一個假設:股價創新高的股票,真的會繼續漲嗎?
請用 FinLab 統計台股中,股價創 N 日新高的股票, 在不同 N 值(20, 60, 120, 250, 300 日)下的回測績效表現。
顯示程式碼
from finlab import data
from finlab.backtest import sim
import pandas as pd
close = data.get('price:收盤價')
volume = data.get('price:成交股數')
# 測試不同的新高天數
results = []
for n_days in [20, 60, 120, 250, 300]:
# 價格創 N 日新高
price_new_high = (close == close.rolling(n_days).max())
# 流動性篩選
volume_filter = volume.average(20) > 300 * 1000
# 建立部位
cond = price_new_high & volume_filter
position = cond.is_largest(10)
# 回測(月度再平衡)
report = sim(position.loc['2015':], resample='M', upload=False)
stats = report.get_stats()
results.append({
'N日新高': n_days,
'年化報酬率': f"{stats['cagr']:.1%}",
'夏普比率': f"{stats['monthly_sharpe']:.2f}",
'最大回撤': f"{stats['max_drawdown']:.1%}"
})
pd.DataFrame(results)| N日新高 | 年化報酬率 | 夏普比率 | 最大回撤 |
|---|---|---|---|
| 20 | 13.0% | 0.66 | -31.6% |
| 60 | 11.0% | 0.50 | -48.8% |
| 120 | 13.1% | 0.64 | -37.2% |
| 250 | 19.1% | 0.81 | -44.9% |
| 300 | 18.8% | 0.77 | -45.4% |
參數敏感度熱力圖
為了更直觀地看出不同新高天數對績效的影響,我們用熱力圖來呈現完整的參數測試結果:
從熱力圖可以清楚看出:
- 新高天數 250 日是最佳甜蜜點,年化報酬達 19.1%、夏普比率 0.81
- 天數太短(20-100 日)容易捕捉到假突破,績效較差
- 天數超過 350 日後,績效開始下降(可能錯過啟動時機)
累積報酬比較圖
為了更清楚看出不同參數的長期表現差異,我們將 11 種新高天數(20-500日)的累積報酬曲線繪製在一起:
圖表說明:
- 🔵 藍色線條 = 短天期(20日)
- 🔴 紅色線條 = 長天期(500日)
- 顏色越紅,代表新高天數越長
從圖表可以觀察到:
- 長天期策略(紅色)的累積報酬明顯高於短天期(藍色)
- 250-350 日新高(偏紅)在整個回測期間表現最為穩定且報酬最高
- 短天期策略(50-100 日)長期累積報酬較低
數據清楚顯示:新高天數越長,策略績效越好(但有上限)。
250 日新高的年化報酬(19.1%)是 60 日新高(11.0%)的近 2 倍。這驗證了「動能效應」——過去表現強勢的股票,未來傾向繼續強勢。
為什麼「追高」反而有效?
從行為金融學的角度,這個現象可以解釋:
1. 損失規避心理
諾貝爾獎得主 Daniel Kahneman 的研究發現,人們對損失的痛苦是獲利快樂的 2.5 倍。這導致大多數人「不敢追高」。
但當股價創新高時,所有持有者都在獲利,沒有「解套賣壓」。害怕追高的人越多,這些股票被低估的程度就越大。
2. 動能效應(Momentum Effect)
學術研究已證實:過去 6-12 個月表現好的股票,未來 3-6 個月傾向繼續表現好。創新高是動能的最強信號。
用 AI 建立基礎策略
既然現象存在,我們把它變成可執行的策略。
請建立一個「創 300 日新高」的基礎策略:
- 買進條件:股價創 300 日新高
- 流動性:20 日均量 > 500 張
- 月度再平衡,單一持股上限 10%
- 回測期間:2015 年至今
顯示程式碼
from finlab import data
from finlab.backtest import sim
# 取得數據
close = data.get('price:收盤價')
volume = data.get('price:成交股數')
# 條件:價格創 300 日新高 + 流動性篩選
volume_filter = volume.average(20) > 500 * 1000
position = (close == close.rolling(300).max()) & volume_filter
# 執行回測(月度再平衡)
report = sim(
position.loc['2015':],
resample='M',
position_limit=0.1,
upload=False
)
# 生成專業報告
report.to_html('cumulative_returns.html')基礎策略績效
| 指標 | 數值 |
|---|---|
| 年化報酬率 | 20.1% |
| 夏普比率 | 0.83 |
| 最大回撤 | -36.4% |
| 總報酬率 | 650% |
績效不錯,但有兩個明顯問題:
- 最大回撤 -36.4% — 波動太大,很多人撐不住
- 夏普比率只有 0.83 — 風險調整報酬還有提升空間
有沒有辦法改善?
問題分析:為什麼會有假突破?
請分析「創新高」策略失敗的案例, 這些股票有什麼共同特徵?
觀察發現,許多「假突破」有以下特徵:
- 營收沒有跟上 — 股價創新高,但營收持平或下滑
- 動能不足 — RSI 偏低,只是短暫反彈
- 流動性問題 — 小型股容易被炒作後崩跌
這給了我們優化方向:加入基本面篩選,過濾假突破。