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

aroon 阿隆指標怎麼用?台股回測:黃金交叉全輸 0050,
震盪選股策略全期勝出

aroon 阿隆指標怎麼用才對?台股回測:近 20 日剛黃金交叉就買,研究段年化僅 1.3%;震盪最高 10 檔加持續性濾網與廣度減碼,全期年化 25.2% 勝 0050 的 21.2%,但 2022 年起落後,換股日挪到每月 5~25 日只剩 11.4% 到 22.5%。

免安裝,用 AI 重跑這篇的策略

在瀏覽器開啟 FinLab Studio,AI 依本文的條件重跑回測,接著可以改條件再測。

在 Studio 重跑
aroon 真用法 CAGR 25.2% Sharpe 1.11

aroon 阿隆指標在台股怎麼用:震盪選股,配上宇宙內的 aroon 廣度減碼

aroon 最常見的教法是「AroonUp 上穿 AroonDown 就買」。我們把這個用法和幾種變體放進台股 2015 到 2026 年 9 月的真實回測,再把首發版(2026 年 6 月)的完整策略用新資料重跑一次,結果整理在下表:

依本文重跑

執行這個策略

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

告訴你的AI:

幫我設定 FinLab,重現這篇文章,請讀:https://finlab.finance/setup?relatedUrl=/blog/aroon-indicator-taiwan

免安裝,開啟 FinLab Studio
你想知道的 回測的回答
aroon 阿隆指標是什麼 Tushar Chande 提出的趨勢計時器,量的是「距離上次創新高、新低過了幾天」,跟漲跌幅度無關
黃金交叉買進有效嗎 近 20 個交易日內剛黃金交叉的股票全部買進,研究段(2015–2021)年化 1.3%、2022 年起 11.5%,兩段都輸含息 0050 的 15.1%、30.5%
震盪能拿來選股嗎 單用震盪最高 30 檔,研究段 12.7%、2022 年起 18.1%,同樣輸 0050;集中到最高 10 檔,全期年化 25.3% 但月夏普 0.94、最大回撤 -46.1%,再加持續性濾網、反波動加權與廣度減碼,月夏普才超過 0050(1.11 對 1.07)
完整策略效果 2015-01-30 到 2026-09-30 年化 25.2%、月夏普 1.11,勝含息 0050 的 21.2%、1.07;2022 年起年化 24.7%,落後 0050 的 30.5%
最大的風險 換股日從月底挪到每月 5~25 日,全期年化只剩 11.4%~22.5%;名次同分時換一種排序規則,2022 年起月夏普掉到 0.85~0.94;首發後到 2026-09-30 策略跌 10.9%,同期 0050 漲 8.9%

aroon 阿隆指標震盪選股加廣度減碼的純技術策略與含息 0050 的台股淨值對照圖,2015 年 1 月 30 日同日起算到 2026 年 9 月,策略全期在上方但 2026 年 6 月後回落

本文數字出自 finlab 套件(2.2.21)抓取的上市櫃真實價量資料,回測自策略第一個淨值日 2015-01-30 起到 2026-09-30,基準為含息 0050(etl:adj_close 還原價、純算術買進持有、同一天起算)。首發版資料截至 2026-06-09,這次把資料延長到 2026-09-30,策略參數維持首發設定。文末附可下載的 strategy.py 與 data.csv。對回測的觀念還不熟,可先看回測是什麼。

aroon 阿隆指標是什麼

aroon 阿隆指標是技術分析師 Tushar Chande 在 1995 年提出的趨勢指標,名字源自梵文「黎明前的曙光」。它跟大多數指標最不一樣的地方,在於它量的是「距離上次創新高、新低過了幾天」,跟漲跌幅度無關,本質上是一個趨勢的計時器。技術指標的基礎名詞可參考名詞詞彙表。

aroon 由兩條 0 到 100 的線組成:

AroonUp:(timeperiod − 期間內最高價距今天數)/ timeperiod × 100。越接近 100,代表最近才剛創新高,上升趨勢很「新鮮」。

AroonDown:(timeperiod − 期間內最低價距今天數)/ timeperiod × 100。越接近 100,代表最近才剛創新低。

Aroon 震盪(oscillator):AroonUp − AroonDown,範圍 −100 到 +100,越高代表上升趨勢越領先。

中文教學裡 aroon 幾乎只被當成「兩條線交叉」的進出場訊號:AroonUp 上穿 AroonDown 就買、下穿就賣。下面先在單一個股上看這兩種常見用法長什麼樣子,再用全市場回測檢查它們有沒有賺到錢。

aroon 阿隆指標的數學定義

設 timeperiod 為 nn,AroonUp 與 AroonDown 的定義是:

AroonUp=n−(自 n 期最高點以來天數)n×100,AroonDown=n−(自 n 期最低點以來天數)n×100AroonUp = \frac{n - (\text{自 } n \text{ 期最高點以來天數})}{n}\times 100,\qquad AroonDown = \frac{n - (\text{自 } n \text{ 期最低點以來天數})}{n}\times 100

震盪則是兩者相減:

AroonOsc=AroonUp−AroonDownAroonOsc = AroonUp - AroonDown

逐個符號拆開來看:

  • nn 是回看窗格。本文的教科書用法與單股示意用 25 個交易日,完整策略用 20 個交易日。nn 越大越偏中長期趨勢,越小越敏感也越多雜訊。
  • 「自 nn 期最高點以來天數」是從今天往回數,最近一次 nn 日新高發生在幾天前。今天剛創新高時這個天數是 0,代入後 AroonUp=100AroonUp = 100;最高點落在窗格最左端時天數是 nn,AroonUp=0AroonUp = 0。AroonDown 對最低點同理。
  • 兩條線都被鎖在 0 到 100 之間,震盪落在 −100-100 到 +100+100。

兩個實務上會碰到的性質:

  1. 震盪只有少數幾個值。 因為天數是整數,n=20n = 20 時兩條線都是 5 的倍數,震盪只有 41 種取值。拿它排名選股,同分的股票很多,同分怎麼排會直接改變選到哪幾檔,後面有一整段實測。
  2. 除權息會製造假新低。 finlab 的 data.indicator("AROON") 預設用未還原的最高價、最低價。除息日股價往下跳,可能讓個股出現一個假的 nn 日新低,AroonDown 跳到 100。台股 7、8 月除權息旺季,宇宙內每天平均有 4.2 檔、2.5 檔股票出現這種只在未還原價才有的新低。

單股示意圖:兩個派別的買賣點

把 aroon 畫到單一個股上最清楚。下圖是台積電(2330)2023-08 到 2024-06 的日線,下半部是 AroonUp(25)、AroonDown(25)與震盪三條線,價格面板標出兩個教科書派別的買賣點:

  • 交叉派:AroonUp 上穿 AroonDown 進場、跌破出場(三角形)。
  • 震盪派:震盪升破 50 進場、跌破 0 出場(圓點與叉號)。

台積電 2330 的 aroon 阿隆指標 25 日 AroonUp、AroonDown 與震盪三條線,價格面板以三角形標出交叉派、以圓點與叉號標出震盪派的買賣點,2023 年 8 月到 2024 年 6 月

同一段、同一套參數換到聯發科(2454):

聯發科 2454 的 aroon 阿隆指標 25 日三條線與交叉派、震盪派買賣訊號示意圖,2023 年 8 月到 2024 年 6 月,股價這段上漲 96%

這 11 個月(222 個交易日)裡,台積電交叉派買 4 次、賣 3 次,震盪派買 6 次、賣 3 次;聯發科交叉派買 4 次、賣 3 次,震盪派買 5 次、賣 3 次。兩派有好幾次在同一天出手,所以圖上部分記號疊在一起。這段兩檔分別漲了 70.4%、96.4%,算是很順的上升趨勢,兩派還是各自進出了七到九次;台積電在 2023 年 9、10 月於 520 到 560 元附近橫盤,交叉派 9 月 8 日買進、9 月 21 日就賣出,10 月 26 日再買回來。逐檔照訊號進出,每一次都要付手續費與證交稅。

畫圖的程式如下(判斷穿越時要用完整歷史的前一天,先切期間再判斷,期間第一天會被誤判成訊號):

顯示程式碼
import matplotlib.pyplot as plt
import finlab
from finlab import data
 
# finlab 會在需要資料時自動引導登入
finlab.login()
 
# 載入收盤價與 Aroon(25):data.indicator 回傳 AroonDown 與 AroonUp 兩個 DataFrame
close = data.get("price:收盤價")
aroon_down, aroon_up = data.indicator("AROON", timeperiod=25)
oscillator = aroon_up - aroon_down
 
sid = "2330"
window = slice("2023-08-01", "2024-06-30")
up, down, osc = aroon_up[sid], aroon_down[sid], oscillator[sid]
 
 
def turns_true(condition):
    """條件由 False 變 True 的那一天(用完整歷史判斷,再切出想看的期間)。"""
    condition = condition.fillna(False).astype(bool)
    previous = condition.shift(1, fill_value=False).astype(bool)
    return (condition & ~previous).loc[window]
 
 
cross_buy = turns_true(up > down)      # 交叉派:AroonUp 上穿 AroonDown
cross_sell = turns_true(up < down)     # 交叉派:AroonUp 跌破 AroonDown
osc_buy = turns_true(osc > 50)         # 震盪派:震盪升破 50
osc_sell = turns_true(osc < 0)         # 震盪派:震盪跌破 0
 
price = close[sid].loc[window]
print("交叉派 買", int(cross_buy.sum()), "賣", int(cross_sell.sum()),
      "| 震盪派 買", int(osc_buy.sum()), "賣", int(osc_sell.sum()))
 
# 上半部畫股價並標買賣點、下半部畫 aroon 三條線
fig, (ax_price, ax_aroon) = plt.subplots(2, 1, figsize=(12, 7), sharex=True)
ax_price.plot(price.index, price, color="black", label=sid)
ax_price.scatter(price[cross_buy].index, price[cross_buy], marker="^", label="交叉派買進")
ax_price.scatter(price[cross_sell].index, price[cross_sell], marker="v", label="交叉派賣出")
ax_price.scatter(price[osc_buy].index, price[osc_buy], marker="o", label="震盪派買進")
ax_price.scatter(price[osc_sell].index, price[osc_sell], marker="x", label="震盪派賣出")
ax_price.legend()
 
ax_aroon.plot(up.loc[window].index, up.loc[window], label="AroonUp(25)")
ax_aroon.plot(down.loc[window].index, down.loc[window], label="AroonDown(25)")
ax_aroon.plot(osc.loc[window].index, osc.loc[window], label="震盪(Up−Down)")
ax_aroon.axhline(50, linestyle="--")
ax_aroon.axhline(0, linestyle="--")
ax_aroon.legend()
plt.show()

台積電這段會印出「交叉派 買 4 賣 3 | 震盪派 買 6 賣 3」。

黃金交叉在台股:近 20 日剛交叉的股票,研究段年化只有 1.3%

單股看不出輸贏,我們把幾種常見用法放到可交易宇宙裡回測:60 日均量 > 100 萬股、收盤 > 10 元、60 日均成交金額前 300 名,排除 ETF、金融保險股、處置與全額交割股。全部用 Aroon(25)、等權、每月最後一個交易日換股、不擇時、扣手續費(打三折)與證交稅:

aroon 用法 研究段年化 研究段月夏普 2022 年起年化 全期最大回撤 月底持股檔數(中位)
震盪最高 30 檔 12.7% 0.67 18.1% -45.0% 30
AroonUp 在 AroonDown 上方的全部股票 11.9% 0.60 16.7% -41.7% 119
近 20 個交易日內剛黃金交叉、月底仍在上方 1.3% 0.17 11.5% -46.2% 51
月底當天剛黃金交叉 -3.3% -0.02 3.5% -77.1% 3
震盪最低 30 檔(等反彈) 0.1% 0.12 15.4% -48.2% 30
含息 0050 15.1% 1.00 30.5% -34.0%

aroon 阿隆指標四種裸用法的研究段與 2022 年起年化報酬長條圖,震盪最高 30 檔研究段 12.7%、AroonUp 在上方的全部股票 11.9%、近 20 日剛黃金交叉 1.3%、震盪最低 30 檔 0.1%,兩段都低於含息 0050

這張表有三個重點:

一、剛交叉的那一刻反而最差。 同樣是 AroonUp 在上方的股票,全部持有研究段 11.9%;只挑最近 20 天才剛穿越的股票(月底中位數 51 檔),研究段掉到 1.3%。只買月底當天剛交叉的股票,中位數只有 3 檔、141 個月裡有 14 個月一檔都沒有,全期最大回撤 -77.1%。把交叉當買點,買到的是剛脫離下跌、還沒走出趨勢的股票。

二、五種裸用法兩段都輸 0050。 表現最好的「震盪最高 30 檔」,研究段 12.7% 低於 0050 的 15.1%,2022 年起 18.1% 也遠低於 30.5%。

三、低震盪股在 2022 年後沒有一直落後。 震盪最低 30 檔研究段只有 0.1%,2022 年起卻有 15.4%,跟最高 30 檔的 18.1% 相差不多。下一段的五分位會看得更清楚。

2026 年 6 月首發版的這張表有一列「黃金交叉持有」,程式實際上是「AroonUp 在上方的股票中震盪最高 30 檔」。震盪最高的 30 檔幾乎都已經 AroonUp 在上方,141 個月裡有 136 個月跟「震盪最高 30 檔」是同一籃,所以兩列數字幾乎相同,量不到穿越時點的效果;這次改成真的看穿越日。延伸閱讀:技術面與基本面選股的差異、動能策略。

震盪當選股因子:研究段排得出高低,2022 年起排不出來

把可交易宇宙依 Aroon(25) 震盪由低到高切成五等分,各組等權、月換股、扣成本:

分位(震盪由低到高) 研究段年化 研究段月夏普 2022 年起年化 2022 年起月夏普
Q1(最低) 2.5% 0.22 15.2% 0.71
Q2 6.4% 0.40 10.8% 0.58
Q3 10.7% 0.57 12.0% 0.66
Q4 10.5% 0.59 14.7% 0.72
Q5(最高) 11.1% 0.61 23.1% 0.92

aroon 震盪五分位 Q1 到 Q5 的研究段與 2022 年起年化報酬長條圖,研究段由 2.5% 升到 11.1%,2022 年起 Q1 的 15.2% 高於 Q2 到 Q4

研究段 Q1 到 Q3 由 2.5% 升到 10.7%,Q3 到 Q5 幾乎持平,最高分位 11.1% 仍低於 0050 的 15.1%。2022 年起 Q5 的 23.1% 最高,但 Q1 的 15.2% 高過 Q2 到 Q4,高低順序排不出來,Q5 也低於 0050 的 30.5%。

再把高低兩端拆成多空價差(震盪最高 30 檔的月報酬減最低 30 檔,各自等權、扣成本,未計放空成本):

Aroon 週期 研究段價差(年化) 研究段月夏普 2022 年起價差(年化) 2022 年起月夏普
14 7.4% 0.49 10.6% 0.53
25 11.5% 0.78 2.1% 0.10
35 15.9% 0.89 7.4% 0.39

週期 25 的價差在研究段每年 11.5%、正報酬月份 55.4%,2022 年起只剩每年 2.1%、正報酬月份 52.6%。原因在空腿:震盪最低 30 檔 2022 年起年化 15.4%,多腿是 18.1%。

宇宙內 aroon 25 日震盪大於 0 的股票比例與高低震盪多空價差累積的雙軸圖,2015 年 1 月到 2026 年 9 月,價差在 2022 到 2023 年回吐、2024 年後再上升、2026 年 7 月大跌

圖上藍線是週期 25 的多空價差累積,紫線是宇宙內震盪大於 0 的股票比例(20 日平均)。價差在 2015 到 2021 年整體往上(2019 到 2020 年有一段回落),2022 到 2023 年吐回一大段,2024 年後再創新高,2026 年 7 月又一次大跌。紫線在 5% 到 95% 之間大幅擺動,市場上升趨勢的廣度變化很快。

高 Aroon 震盪代表最近才創新高、很久沒創新低,跟 Jegadeesh & Titman (1993) 記錄的中期動能效應是同一類現象;他們的形成期是 3 到 12 個月,Aroon(20~25) 看的是一個月左右的新高新低時間,期間較短,只能算方向相近。台股 2015 到 2021 年這個排序有效,2022 年後單靠它已經分不出好壞,所以完整策略在震盪排序之外又加了三道工序。

完整策略:Aroon 震盪選股+持續性濾網+反波動加權+廣度減碼

首發版定案的規則如下,這次刷新沒有改任何參數:

  1. 可交易宇宙:上市櫃股票,60 日均成交金額前 300 名、60 日均量 > 100 萬股、收盤 > 10 元;只留代號剛好 4 碼數字的股票(排除權證、特別股與 6 碼代號),排除 ETF(00 開頭)、金融保險股、處置與全額交割股。KY 股代號也是 4 碼數字,沒有被排除。
  2. 因子:TA-Lib AROON(timeperiod=20),震盪 = AroonUp − AroonDown,用未還原價計算。
  3. 持續性濾網:只留近 20 個交易日內震盪 > 0 至少 15 天的股票。
  4. 選股:合格池內震盪最高 10 檔。震盪是 5 的倍數,同分時代號小者排前面,這是首發版所用 finlab 2.0.13 的排名方式。
  5. 加權:權重與個股 60 日日報酬標準差成反比,組內正規化,單檔不設上限。
  6. 廣度減碼:每天算宇宙內震盪 > 0 的股票比例(流動性宇宙,不是全市場),取 14 日平均;跌破自身 120 日均值減 1.2 倍標準差時,整籃曝險乘 0.5,其餘放現金。
  7. 換股:每月最後一個交易日換股一次。選股與減碼判定都只在換股日讀取,月中廣度轉弱不會提前減碼。

完整策略的程式碼如下。印出的 cagr(0.252)與 max_drawdown(-0.356)就是下一節主表的全期年化與最大回撤;get_stats() 的夏普、索提諾扣了 2% 無風險利率,主表的月夏普、月索提諾不扣,所以數字不同:

顯示程式碼
import numpy as np
import pandas as pd
import finlab
from finlab import data
from finlab.backtest import sim
 
# finlab 會在需要資料時自動引導登入
finlab.login()
data.truncate_end = "2026-09-30"   # 本文資料截止日;拿掉這行就用最新資料
 
# 1) 載入價量資料
close = data.get("price:收盤價")
volume = data.get("price:成交股數")
amount = data.get("price:成交金額")
 
# 2) 可交易宇宙:60 日均量 > 100 萬股、收盤 > 10 元、60 日均成交金額前 300 名,
#    只留代號剛好 4 碼數字的股票,排除 ETF(00 開頭)、金融保險股、處置/全額交割股
categories = data.get("security_categories")
financial = set(categories.loc[categories["category"].astype(str)
                               .str.contains("金融|保險|銀行", na=False), "stock_id"].astype(str))
is_common = pd.Series({sid: len(str(sid)) == 4 and str(sid).isdigit()
                       and not str(sid).startswith("00") and str(sid) not in financial
                       for sid in close.columns})
universe = ((volume.rolling(60, min_periods=20).mean() > 1_000_000)
            & (close > 10) & close.notna()
            & amount.rolling(60, min_periods=20).mean().is_largest(300))
universe = universe & pd.DataFrame([is_common.values] * len(close), index=close.index, columns=close.columns)
flagged = data.get("etl:is_flagged_stock").reindex_like(universe).fillna(False).astype(bool)
universe = universe & ~flagged
 
# 3) Aroon(20) 震盪 = AroonUp − AroonDown(越高 = 上升趨勢越領先)
aroon_down, aroon_up = data.indicator("AROON", timeperiod=20)
oscillator = (aroon_up - aroon_down).reindex(columns=close.columns)
 
# 4) 持續性濾網:近 20 個交易日內震盪 > 0 的天數至少 15 天
persistence = (oscillator > 0).rolling(20, min_periods=10).sum()
qualified = universe & (persistence >= 15).reindex_like(close).fillna(False).astype(bool)
 
# 5) 選股:震盪最高 10 檔。震盪是 5 的倍數,同分很多;method="first" 讓同分時代號小者排前面
basket = oscillator.where(qualified).rank(axis=1, ascending=False, method="first") <= 10
 
# 6) 反波動加權:權重與 60 日日報酬標準差成反比
vol60 = close.pct_change().rolling(60, min_periods=30).std()
inverse_vol = (1.0 / vol60).where(basket)
weights = inverse_vol.div(inverse_vol.sum(axis=1).replace(0, np.nan), axis=0).fillna(0.0)
 
# 7) 廣度減碼:宇宙內震盪 > 0 的比例取 14 日平均,
#    跌破自身 120 日均值減 1.2 倍標準差 → 整籃曝險乘 0.5
breadth = (oscillator > 0).where(universe).sum(axis=1) / universe.sum(axis=1).replace(0, np.nan)
breadth = breadth.astype(float).rolling(14, min_periods=7).mean()
floor = breadth.rolling(120, min_periods=60).mean() - 1.2 * breadth.rolling(120, min_periods=60).std()
risk_on = (breadth >= floor).reindex(close.index).ffill().fillna(True).astype(bool)
weights = weights.mul(np.where(risk_on.values, 1.0, 0.5), axis=0)
 
# 8) 回測:每月最後一個交易日換股,手續費打三折,sim 另扣賣出證交稅 0.3%
report = sim(weights.loc["2015-01-01":], resample="M", fee_ratio=1.425 / 1000 * 0.3, upload=False)
print(report.get_stats())

rank 一定要寫 method="first"。finlab 2.2 起 rank 遇到同分會取平均名次,跨過第 10 名的同分組整組入選或整組落選(平均名次 ≤ 10 才入選),同一行程式每月會選到 0 到 18 檔,結果也不同(見後面「同分怎麼排」一節)。

完整策略的真實績效

區段 策略年化 策略月夏普 策略月索提諾 策略最大回撤 0050 年化 0050 月夏普 0050 月索提諾 0050 最大回撤
研究段 2015-01-30~2021 25.7% 1.33 3.08 -24.1% 15.1% 1.00 1.47 -28.2%
2022 年起~2026-09-30 24.7% 1.02 2.08 -35.3% 30.5% 1.21 2.44 -34.0%
全期 25.2% 1.11 2.28 -35.6% 21.2% 1.07 1.85 -34.0%

全期年化、月夏普、月索提諾三項勝過含息 0050,最大回撤 -35.6% 比 0050 深 1.6 個百分點,年化波動 22.3% 也高於 0050 的 19.8%。2022 年起年化 24.7% 落後 0050 的 30.5%,月夏普 1.02 對 1.21。年換手約 10.0 次,全期 1,391 筆交易。

我們每季重跑時的判準是「2022 年起月夏普 ≥ 1.0 且年化 ≥ 15%」。這次 2022 年起月夏普 1.02,只高出門檻 0.02,照原參數刷新、不調參;首發時同一段的月夏普是 1.17。下面幾節的檢查會說明這個 1.02 有多脆弱。

下面是完整互動式回測,月報酬熱力圖、權益曲線、年度績效都可以直接操作:

逐層拆開:持續性濾網、反波動加權與廣度減碼各自做了什麼

從宇宙內震盪最高 10 檔等權開始,一次加一道工序:

版本 研究段年化 研究段月夏普 研究段最大回撤 2022 年起年化 2022 年起月夏普 全期年化 全期最大回撤
震盪最高 10 檔等權 20.9% 0.91 -33.01% 32.1% 1.10 25.3% -46.1%
再加持續性濾網 25.9% 0.90 -35.55% 29.0% 1.01 27.1% -41.9%
改反波動加權(不擇時) 25.5% 1.03 -30.92% 24.3% 0.95 24.9% -35.9%
再加廣度減碼(完整策略) 25.7% 1.33 -24.10% 24.7% 1.02 25.2% -35.6%

aroon 策略逐層建構長條圖,比較震盪最高 10 檔等權、再加持續性濾網、改反波動加權與再加廣度減碼四個版本的全期年化、全期最大回撤與研究段及 2022 年起月夏普

持續性濾網有實際動手:不加濾網時的震盪前 10 名,平均每個月有 3.2 檔沒通過(141 個月裡 129 個月剔除過、共 447 檔次)。它把研究段年化從 20.9% 拉到 25.9%,2022 年起卻從 32.1% 降到 29.0%。

反波動加權用報酬換回撤:全期年化 27.1% → 24.9%、2022 年起 29.0% → 24.3%,全期最大回撤 -41.9% → -35.9%。權重會集中到低波動的股票,月底最大單檔權重中位 17.9%、前 5 檔合計 64.9%;2026-09-30 換股日,中華電(2412)一檔就占 36.3%。從完整策略只拿掉這一項改回等權,全期年化 28.0%、2022 年起月夏普 1.09,但全期最大回撤 -41.6%。

廣度減碼幾乎不改變全期報酬(24.9% → 25.2%),主要作用在研究段:月夏普 1.03 → 1.33、研究段最大回撤 -30.92% → -24.10%。全期最大回撤只從 -35.9% 收到 -35.6%,因為 2022 年兩次最大的單月下跌(6 月 -12.5%、9 月 -12.0%)前的月底都判定滿倉,那一年只有 4 月底減碼一次。

減碼訊號本身的細節:

  • 日頻訊號 2015 年以來轉弱 34 次,其中 13 次在月底前就轉回、完全沒有執行,執行的 21 次從轉弱到第一個換股日中位數隔了 9 個交易日(最長 19 天)。141 個月底有 23 個判定減碼,月底平均曝險 91.8%。
  • 月底讀數有參考價值:判定減碼的月份,不擇時的選股籃下個月平均 +0.51%(中位 -0.1%),判定滿倉的月份平均 +2.48%(中位 1.9%);0050 分別是 -0.56% 與 +2.23%。
  • 同一個月底選股籃改成每天依廣度調整,全期年化反而降到 21.0%、2022 年起月夏普 0.86;不看廣度、每天固定 91.8% 曝險,全期 23.0%、研究段月夏普 1.04;擇時改用 0050 站上 200 日均線,全期 20.8%。
  • 廣度判定減碼的日子,0050 次一交易日的年化波動 26.3%,滿倉日 18.2%。這和 Moreira & Muir (2017) 的發現方向一致:在波動升高時降低曝險,可以改善風險調整後報酬。本文的訊號是上升趨勢廣度,跟他們用的已實現波動不同,只在這個重疊的程度上相呼應。
  • 廣度的母體是流動性宇宙(每天約 228 檔),震盪 > 0 的比例中位 52.3%,10% 與 90% 分位在 22.7% 與 79.0%。

擇時用的宇宙內 aroon 20 日震盪大於 0 比例 14 日平均與策略淨值的雙軸時序圖,2015 年 1 月到 2026 年 9 月

換股日挪一下,結果差很多

同一套規則只改換股日:每月 5、10、15、20、25 日(遇假日取當月在這天以前的最後一個交易日;5 日以前都沒開盤的月份不換股),其餘不動:

換股日 研究段年化 2022 年起年化 全期年化 全期最大回撤 不擇時的研究段年化
每月 5 日 21.6% 24.2% 22.5% -45.3% 21.3%
每月 10 日 9.5% 25.2% 15.5% -46.4% 12.0%
每月 15 日 18.4% 15.5% 17.2% -45.3% 20.6%
每月 20 日 3.7% 24.1% 11.4% -39.1% 2.0%
每月 25 日 25.0% 15.1% 20.8% -38.7% 25.4%
月底(本文) 25.7% 24.7% 25.2% -35.6% 25.5%

aroon 策略換股相位長條圖,每月 5 日到 25 日換股的研究段年化 3.7% 到 25.0%,月底換股 25.7%,另列 2022 年起年化與不擇時的研究段年化

月底換股的全期 25.2% 是六個換股日裡最高的,挪到 20 日只剩 11.4%。拿掉廣度減碼後研究段一樣是 2.0% 到 25.5%,差距主要來自選股,跟擇時關係不大。Hoffstein, Faber & Braun (2020) 把這種只因換股日不同造成的差距稱為 rebalance timing luck,持股越集中、換股越少越明顯;這套策略只抱 10 檔、一個月換一次,正好落在這個範圍。

換股更頻繁也不會比較好:同一個部位改成每週讀取,年換手跳到約 36 次,研究段年化 -3.8%、2022 年起 29.8%、全期 8.6%、全期最大回撤 -48.0%。

參數:選中的組合在 2022 年後站在邊緣

首發版選參數時看的是研究段,網格是 Aroon 週期(18、20、22)× 持股檔數(8、10、12),選股與廣度用同一個週期:

aroon 週期乘以持股檔數三乘三網格的研究段月夏普色溫圖,9 格在 1.02 到 1.45 之間

同一張 aroon 週期乘以持股檔數網格的 2022 年起月夏普色溫圖,只有週期 20 持股 8 與持股 10 兩格在 1.0 以上

研究段 9 格月夏普 1.02 到 1.45,全部在 1.0 以上;2022 年起只剩 0.68 到 1.11,在 1.0 以上的只有週期 20 配持股 8(1.11)與持股 10(1.02)兩格。週期 22 研究段最高(持股 10 是 1.45),2022 年起只有 0.68 到 0.85。

再把每個參數逐格掃一遍(其餘設定同完整策略):

逐格掃描 範圍 研究段月夏普 2022 年起月夏普 2022 年起四捨五入後 ≥ 1.00 的格數
Aroon 週期(選股與廣度同步換) 10~40 日 0.54~1.46 0.41~1.23 4/31
Aroon 週期(只換選股) 10~40 日 0.77~1.45 0.63~1.21 10/31
持股檔數 5~20 檔 1.23~1.43 0.76~1.11 4/16
持續性門檻(20 天內) 10~20 天 1.12~1.64 0.76~1.11 6/11
廣度平滑天數 5~30 日 1.16~1.37 0.79~1.02 8/26
廣度回看天數 60~240 日 1.17~1.33 0.87~1.03 4/19
門檻倍數 0.6~2.0 倍標準差 1.11~1.34 0.86~1.08 5/15
減碼後保留比例 0~1 1.03~1.47 0.95~1.04 8/11

aroon 週期 10 到 40 日逐格掃描的月夏普折線圖,研究段在週期 20 到 24 與 33 到 39 偏高,2022 年起多數格低於 1.0,週期 20 從 19 日的 0.94 跳到 1.33

研究段的月夏普在 Aroon 週期 19 到 20 之間從 0.94 跳到 1.33,週期 20 到 24 是一段高點;同一段在 2022 年起從 1.02 一路降到 0.76。持續性門檻提高到 19、20 天時研究段月夏普 1.52、1.64 最高,2022 年起只有 0.76、0.90。多數參數在 2022 年後都要靠近首發的那一格才站得上 1.0,換一格就掉下來,比較像參數剛好落在研究段的好位置。過擬合的判斷方法可參考回測過擬合機率。

同分怎麼排,也會改變結果

Aroon(20) 震盪只有 41 種取值,141 個換股日裡有 95 個月,第 10 名與第 11 名同分。這種月份的同分組中位數 5 檔,靠代號順序選進來的中位數 2 檔,全期共有 339 檔次因為代號較大而落選。三種同分處理方式的結果:

同分時怎麼排 全期年化 全期最大回撤 2022 年起年化 2022 年起月夏普
代號小者排前面(本文,與首發相同) 25.2% -35.6% 24.7% 1.02
取平均名次(finlab 2.2 起 rank 的預設) 22.8% -37.7% 22.0% 0.94
60 日波動較低者排前面 21.5% -31.9% 19.7% 0.85

取平均名次時,跨過第 10 名的同分組整組入選或整組落選(平均名次 ≤ 10 才入選),每月實際持股 0 到 18 檔,141 個月有 100 個月不是 10 檔;2020 年 11 月底與 2023 年 2 月底池內震盪 100 分的股票太多,整個月一檔都沒選到。代號順序在經濟上沒有意義,換成另外兩種合理的排法,2022 年起月夏普都在 1.0 以下。首發版用的 finlab 2.0.13 排名本身就是代號順序,所以本文沿用並寫明,讀者自己跑的時候記得 method="first"。

2026-06-09 之後:首發後的新資料

首發版資料截至 2026-06-09。延長到 2026-09-30,這 3 個多月策略跌 10.9%,0050 漲 8.9%;同一籃改成每天依廣度調整的對照組跌 15.4%,不擇時的版本跌 16.9%。

月份 策略 每天依廣度調整 不擇時 含息 0050
2026-07 -13.1% -19.4% -24.7% -4.0%
2026-08 +5.9% +7.5% +12.7% +3.3%
2026-09 -3.4% -2.3% -2.3% +5.5%

首發資料截止日 2026-06-09 之後 aroon 策略、廣度每天調整的對照組與含息 0050 的淨值走勢圖,策略 7 月下跌、8 月部分收復、9 月再跌

6 月 30 日換股時,平滑後的廣度 48.0% 跌破門檻 49.1%,策略減碼到五成。7 月持有的 10 檔全部虧損,中位數 -17.6%、最差的 6207 跌 39.8%;不擇時的版本當月 -24.7%,減碼少賠了 11.6 個百分點,是 2015 年以來減碼少賠最多的一個月。同月 0050 從 7 月 1 日高點到 7 月 30 日低點跌了 14.0%,整月 -4.0%。7 月底仍判定減碼(廣度 17.3%、門檻 40.5%),8 月底、9 月底恢復滿倉。策略淨值 2026-06-03 創高後,9 月 15 日最深回落 23.0%,9 月底距高點 -18.5%;2026 年 7 月的 -13.1% 是 2022 年以來最差的一個月。

數字從首發到這次的變化可以拆成兩塊。用首發程式和當時的 finlab 2.0.13 截到 2026-06-09,研究段年化 25.35%、最大回撤 -24.10% 與首發數字逐位相同;2022 年起與全期是 29.77%、26.97%,比首發的 29.57%、26.89% 高 0.2 與 0.1 個百分點,差距來源未查明。改用 finlab 2.2.21、rank 寫明 method="first" 並從 2015-01-30 起算後,同一截止日是研究段 25.69%、2022 年起 30.00%、全期 27.25%(2022 年起月夏普 1.19)。這次的 2022 年起月夏普從 1.19 降到 1.02,來自 6 月以後的新資料。

回測方法與口徑

  • 交易成本:finlab sim(),手續費 0.1425% 打三折、賣出證交稅 0.3%。手續費不打折時全期年化 22.7%、2022 年起月夏普 0.95;手續費加倍且稅率 0.6% 時 20.4%、0.87。
  • 滑價:未額外假設,實際成交衝擊取決於資金規模與成交量,本文未估算容量。
  • 股票池:每天依當時的價量重新篩選流動性前 300 名,下市或停止交易的股票在當時都可能被選入;2015-01-30 有收盤價、到 2026-09-30 已沒有收盤價的 4 碼普通股共 142 檔。
  • 排除類別:ETF(00 開頭)、代號不是剛好 4 碼數字者(權證、特別股、6 碼代號)、金融保險股、處置與全額交割股;KY 股未排除。首發版的代號規則是「前 4 碼為數字」,用首發規則跑同一策略結果完全相同。
  • 前視偏差:Aroon、持續性天數、60 日波動與廣度都只用當天以前的價格;選股與減碼在月底收盤後判定,sim() 以次一交易日起的報酬計算。完全沒有財報或月營收輸入。
  • 未還原價:Aroon 用未還原的最高價、最低價。7 月宇宙內廣度比還原價版本平均低 5.3 個百分點,141 個月底有 3 個減碼判定不同,7 月底的選股籃平均只有 71% 相同。我們在看回測結果之前決定維持未還原(與首發相同);改用還原價時,選股與廣度都改是全期 26.6%、2022 年起月夏普 1.00,只改廣度是 25.8%、1.04。
  • 權重:反波動加權、單檔不設上限;廣度減碼時整籃乘 0.5,其餘現金,不放空、不加槓桿。
  • 周轉率:年換手約 10.0 次。
  • 樣本內外:研究段 2015-01-30~2021-12-31 是首發選參數時看過的區段,2022 年起當作驗證段;首發版的硬門檻也用到了 2022 年後到 2026-06 的數字,所以 2022 年起並非完全沒看過的資料。
  • 教科書與五分位:都扣同樣的成本、月換股,與主策略同一套回測口徑。
  • 績效指標:月夏普 = 月報酬平均 ÷ 標準差 × √12,月索提諾的分母只算下跌月份,兩者都不扣無風險利率;0050 用同一套公式。

不同年度的表現:12 年贏 7 年

年度 策略 含息 0050 勝負
2015(1/30 起) 1.9% -7.9% 勝
2016 17.7% 19.6% 負
2017 25.8% 18.1% 勝
2018 15.8% -4.9% 勝
2019 8.0% 33.5% 負
2020 54.7% 31.1% 勝
2021 66.5% 21.9% 勝
2022 -32.5% -21.4% 負
2023 62.1% 27.5% 勝
2024 35.0% 48.6% 負
2025 48.2% 36.8% 勝
2026(至 9/30) 29.3% 74.3% 負

2020、2021、2023 年大幅領先,2019、2024、2026 年明顯落後。2022 年跌 32.5%,比 0050 的 -21.4% 多跌 11.1 個百分點。

加上月營收 YoY 會更好嗎:研究段較好,2022 年起較差

在宇宙層加一條「最近一期已公布的月營收年增率 > 0 才能入池」(公布日對齊、交易日往後填補,只用已公布的營收),其餘不變:研究段年化 32.5%、月夏普 1.37,比原策略好;2022 年起 20.6%、0.84,比原策略差;全期 27.4%,最大回撤 -44.3% 深了將近 9 個百分點。兩段方向相反,本文主策略維持純技術。基本面與技術面如何分工,可延伸看技術面與基本面選股的差異。

用 aroon 最常踩的四個陷阱

  1. 把交叉當買點:近 20 日剛黃金交叉的股票研究段年化 1.3%,月底當天剛交叉的 -3.3%。
  2. 只看震盪排序:震盪最高 30 檔兩段都輸 0050,2022 年起多空價差只剩每年 2.1%。
  3. 沒處理同分:同一行 rank,新舊版 finlab 會選出不同股票,2022 年起月夏普差 0.08。
  4. 只看月底換股的成績:換到每月 5~25 日,全期年化 11.4%~22.5%,月底的 25.2% 是最高的一組。

三項穩健性驗證:重跑到 2026 年 10 月

這裡驗證本文的完整策略,三項檢查統一採 sim() 預設手續費 0.1425% 與證交稅 0.3%,資料到 2026-10-27。「贏」指日夏普高於同期 0050 含息買進持有(etl:adj_close 還原價、純算術計算、不扣成本),日夏普 = 日報酬平均 ÷ 標準差 × √252,不扣無風險利率。

2026-10-27 的第一版檢查用的是當時的可下載檔(在 finlab 2.2 上同分取平均名次、廣度用 14 日指數平均),我們逐格重現了當時的結果,下表是把程式改成本文規則(同分代號小者排前面、廣度 14 日簡單平均)後同口徑重跑:

檢查 標準 結果
鄰近參數 Aroon 週期(16、20、24)乘上持股檔數(8、10、12),9 組至少 7 組贏 0/9 組贏,不過
前後兩段 2015-01-30 到 2020-12-11、2020-12-14 到 2026-10-27 兩段都贏 前段 0.95 對 0.89 贏,後段 1.15 對 1.24 輸,不過
交易成本 原參數、sim() 預設成本 日夏普 1.05 對 1.08,不過

aroon 震盪選股加廣度減碼策略鄰近參數 9 組日夏普熱圖,0 組高於同期 0050 含息的 1.08,原參數 1.05、週期 20 持股 8 為 1.06,週期 16 那一欄 0.81 到 0.85

9 組參數的日夏普(括號內是年化報酬,粗體是本文參數):

持股檔數 \ Aroon 週期 16 20 24
12 0.82(年化 17.1%) 0.88(年化 17.6%) 0.91(年化 19.4%)
10 0.85(年化 18.1%) 1.05(年化 22.6%) 0.90(年化 19.7%)
8 0.81(年化 17.5%) 1.06(年化 23.7%) 0.93(年化 21.7%)

前後兩段與全期:

期間 策略年化 策略日夏普 0050 含息年化 0050 日夏普
前段 2015-01-30 到 2020-12-11 16.7% 0.95 13.5% 0.89
後段 2020-12-14 到 2026-10-27 28.7% 1.15 28.0% 1.24
全期 2015-01-30 到 2026-10-27 22.6% 1.05 20.5% 1.08

前後兩段是把整段期間從中點對半切。上文的研究段與 2022 年起以 2022 年初為界,照這個切法,2015 到 2021 年日夏普 1.15 對 0050 的 0.96,2022 年起 0.95 對 1.22。上文多用月夏普,跟這裡的日夏普算法不同,數字不能直接比。

交易成本對照(原參數):

成本設定 年化 日夏普 最大回撤
不扣成本 30.1% 1.33 -33.2%
sim() 預設:手續費 0.1425%、證交稅 0.3% 22.6% 1.05 -36.7%
本文設定:手續費打三折 25.1% 1.15 -35.6%
0050 含息買進持有(同期) 20.5% 1.08 -34.0%

修正後三項仍未全數通過,結論與 10-27 相同:9 組鄰近參數全部輸,原參數 1.05 只比 0050 的 1.08 低一點,週期 16 那一欄掉到 0.81 到 0.85;後段 1.15 輸 1.24。10-27 版本裡「重跑到 2026-06-09 只有 24.8%、月夏普 1.07」的落差,主要來自平均名次,指數平均廣度另有小幅影響(以 2026-09-30 的資料各自單改,全期年化分別少 2.4 與 0.4 個百分點);照本文規則跑到同一天是 27.3%、1.19、-35.6%。

策略的限制與取捨

  • 2022 年起落後 0050:2022 年起年化 24.7% 對 30.5%,月夏普 1.02 只高出我們的門檻 0.02;2026 年 6 月到 9 月跌 10.9%,同期 0050 漲 8.9%。
  • 結果依賴換股日與同分規則:換股日挪到每月 5~25 日全期只剩 11.4%~22.5%;同分改用平均名次或低波動優先,2022 年起月夏普 0.94、0.85。
  • 集中度高:只抱 10 檔、反波動加權後有效持股中位數約 8.6 檔,低波動的股票可以拿到三成以上權重;能接受 -35% 等級回撤與高集中度的人才適合。
  • 擇時只在月底:日頻轉弱有 13 次在月底前就轉回而沒執行,執行的中位數晚 9 個交易日;2022 年兩次最大的單月下跌前,月底都判定滿倉。
  • 容量與成本:宇宙限成交額前 300 名、選 10 檔、年換手約 10 次,回測未逐筆估算滑價與容量,大資金部署要另外評估。
  • 參數的位置:逐格掃描顯示 2022 年後多數鄰近參數低於 1.0,2026-06 首發時選參數已看過研究段與部分 2022 年後的資料。
  • 各技術指標的回測比較可參考RSI、MACD、KD 比較、KD 鈍化策略、ADX 趨勢強度指標回測與TA-Lib 158 種技術指標;用大盤訊號降低回撤,也可參考市場濾網如何降低回撤。

自己跑一次

FinLab Skill 可以讓你的 AI 助理一步步帶你安裝、抓台股資料、重現這篇的回測:

裝好之後,下載本文的 strategy.py 與 data.csv,即可在自己的環境重跑、改參數、換因子。strategy.py 會印出本文的主表、逐層建構、換股日比較、逐年報酬與首發後的逐月報酬;data.csv 除了策略與 0050 的淨值,也附上每天的廣度、減碼門檻與滿倉/減碼判定。把 DATA_END 改成 None 就能用最新資料重跑。登入只需在程式裡寫 finlab.login(),套件會在需要資料時引導你完成登入。想延伸成更完整的量化流程,可參考量化交易總覽與程式交易是什麼;想一次看完常用技術指標的台股回測,見技術指標台股回測總覽。策略上線前該留意的陷阱,可看回測的限制與量化交易的風險。

常見問題

Q:aroon 阿隆指標的參數要設多少? 完整策略用 timeperiod 20,這是首發時看研究段選的。逐格掃描 10 到 40 日,研究段月夏普 0.54 到 1.46,2022 年起只有 13、14、16、20 這 4 個週期在 1.0 以上;研究段最高的 23、24、36 日(1.46),2022 年起只有 0.77、0.76、0.91。與其找「最佳」數字,比較實際的做法是確認你用的週期附近幾格都站得住。

Q:AroonUp 上穿 AroonDown 的黃金交叉能不能買? 回測結果不好。近 20 個交易日內剛黃金交叉、月底仍在上方的股票全部持有,研究段年化 1.3%、2022 年起 11.5%;只買月底當天剛交叉的股票,研究段 -3.3%。AroonUp 已經在上方的全部股票反而有 11.9%,問題出在剛交叉的時點。

Q:Aroon 低檔(AroonDown 高)可以拿來抄底嗎? 研究段不行:震盪最低 30 檔年化 0.1%。2022 年起這一籃有 15.4%,跟最高 30 檔的 18.1% 差不多,但兩段都輸 0050,沒有理由專門去買它。

Q:Aroon 震盪要選最高幾檔、多久換一次股? 本文選最高 10 檔、每月最後一個交易日換股,先過持續性濾網(近 20 個交易日內震盪大於 0 至少 15 天)。持股 5 到 20 檔逐格掃描,2022 年起只有 7 到 10 檔四捨五入後在 1.00 以上;改成每週換股,研究段年化 -3.8%、年換手約 36 次;換股日挪到每月 5~25 日,全期年化掉到 11.4% 到 22.5%。

Q:為什麼用同一個 rank 寫法,跑出來的檔數不一樣? Aroon 震盪是 5 的倍數,同分很多。finlab 2.0 的 rank 遇到同分照代號順序給名次,2.2 起改成取平均名次,跨過第 10 名的同分組會整組入選或整組落選。本文程式寫 method="first",同分時代號小者排前面,與首發相同;不寫的話每月會選到 0 到 18 檔,2022 年起月夏普是 0.94。

Q:aroon 和 ADX、DMI 這些趨勢指標差在哪? aroon 量的是距離創新高、新低的天數(趨勢的新鮮度與方向),ADX 量的是趨勢強度(不分多空)。兩者角度互補,ADX 的台股回測可看ADX 趨勢強度指標回測;本文只測了 aroon 單一指標。

Q:這套 aroon 純技術策略適合誰? 適合能接受 -35% 等級回撤、高集中度與年換手約 10 次,想主動選股的人。全期年化 25.2% 勝 0050 的 21.2%,但 2022 年起落後 0050,而且結果明顯受換股日與同分規則影響。偏好低周轉、受不了深回撤的人,直接持有含息 0050 更簡單。


最後更新:2026-10|回測區間:2015-01-30 ~ 2026-09-30|作者:FinLab 量化研究團隊(經量化研究員審閱)

本文僅供量化研究與教學用途,所有回測數字均由 finlab 套件在真實台股資料上產出,過去績效不代表未來表現,不構成投資建議。Aroon 震盪選股加廣度減碼策略全期最大回撤 -35.6%,換股日改到每月 5 到 25 日時全期年化只剩 11.4% 到 22.5%,實際交易前請自行評估風險、滑價與交易容量。

FinLab AI

想建立自己的策略?

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

免費開始

更多技術指標研究

查看全部