4個設計都未通過。下方兩欄摘要可同時比較報酬與最大跌幅,完整參數圖可點開原尺寸。
W底突破買進、M頭跌破賣出的四個台股設計,在本次固定條件下都沒有通過驗證。本文以反面教材為主。個股與0050的訊號數相差很大:同一個形狀規則放在分散持股的ETF上,可能多年只出現少數買點。將等待時間及交易成本一起算進來,結果和事後圈出幾個漂亮的W很不同。
W底、雙重底與M頭怎麼畫
W底與M頭描述兩次試探相近價格後反轉的型態。W底先跌、反彈、再跌,兩個低點構成雙底;中間反彈高點就是本次的水平頸線。收盤由下往上穿越它才買。M頭則是漲、回檔、再漲,跌破中間低點才賣出持股。
| 名稱 | 轉折序列 | 完成條件 | 本次操作 |
|---|---|---|---|
| W底、雙重底 | 低、高、低 | 第二低點確認後突破中間高點 | 建立多頭持股 |
| M頭、雙重頂 | 高、低、高 | 第二高點確認後跌破中間低點 | 賣出既有持股 |
| 尚未突破的雙底 | 低、高、低 | 價格仍低於頸線 | 保持原狀,不提前買 |
| 突破後再跌回 | 曾完成W底 | 本次仍等對應賣訊或60日 | 不事後剔除失敗案例 |
兩個底必須相隔至少22個交易日、最多120日,相對高度差不超過設定容差;中間反彈至少比第一個低點高3%。M頭採鏡像條件。第二個低點可以略高或略低,但低到變成另一段下跌,就可能不符合容差。名稱只提供形狀,不能替代可重複的數值定義。
Lo、Mamaysky與Wang(2000)提出用平滑價格與極值位置辨識型態。本文將雙底改成連續三個已確認轉折,加入頸線穿越與持有期限,屬於自訂的可交易實驗,沒有宣稱完整重現原論文的雙底搜尋演算法。
正向與避開訊號的結果
報酬與最大跌幅
斜線前是年化報酬,後是從高點最多跌多少。
| 設計 | 年化/最大跌幅 |
|---|---|
| 個股買進 | 2.2% / -49.3% |
| 個股避開 | 20.9% / -57.6% |
| 0050買進 | 3.2% / -8.4% |
| 0050避開 | 18.6% / -34.0% |
| 0050含息 | 22.8% / -34.0% |
下方完整比較表可左右滑動,查看夏普、參數勝出數與平均持股權重。
完整比較
| 設計 | 年化報酬 | 日夏普 | 最大回撤 | 前/後半段日夏普 | 參數贏基準 | 平均在場權重 |
|---|---|---|---|---|---|---|
| 台股個股・W/M・正向 | 2.2% | 0.21 | -49.3% | 0.57/-0.08 | 0/9 | 83.5% |
| 台股個股・W/M・避開 | 20.9% | 0.74 | -57.6% | 0.58/0.87 | 0/9 | 100.0% |
| 0050・W/M・正向 | 3.2% | 0.73 | -8.4% | 1.14/0.24 | 0/9 | 7.5% |
| 0050・W/M・避開 | 18.6% | 0.98 | -34.0% | 0.80/1.13 | 0/9 | 92.5% |
| 0050含息持有 | 22.8% | 1.13 | -34.0% | 1.14/1.16 | — | 100.0% |
本文提供研究結果,沒有推薦這些買賣規則。想自行重跑,可先 設定 FinLab 環境,再 下載研究程式(.py);其他檔案見 研究下載區。
個股正向版有不少時間持股,表現卻沒有超過0050。0050正向版的在場權重很低,較小回撤主要伴隨長時間現金,不能單憑跌得少便認定擇時有效。所有結果都用完整日曆,現金日的報酬記為零,沒有把它們移除後重算夏普。
淨值圖同時放個股與0050的正向、避開版本,再加0050含息持有。每條線在2017年1月3日從1開始。避開版是從股票池中排除正向持有狀態,再依相同流動性規則選股;它沒有拿M頭去放空,也沒有測跌幅加倍或反向ETF。
雙底最容易偷看未來的位置
候選低點要比前後各三天的平滑價格都低,所以當天看不到「後三天」的比較結果。本文等到第三天結束,才把該低點加入辨識序列。確認完成後,還要求一次新的頸線突破;如果股價早在等待期間就跳過頸線,不回填成較便宜的進場價。這也是前視偏差會藏在畫圖工具裡的地方。
平滑採24日單邊Gaussian權重,頻寬2、3、4日;兩底或兩頂容差用2%、3%、4%,全組合共九組。中央設定是3日與3%。最後一個轉折後最多等20日,超過便放棄該次突破。持股遇M頭跌破就出場,或滿60個交易日退出,沒有因為尚未回到成本就延長持有。
相同類型的極值連續出現時,只保留當下較極端的一點,歷史持倉不改。程式另做截斷測試:把資料結束日提前,再補上後面行情,前面的所有訊號都必須相同。這能檢查實作是否回寫,不能保證原始資料永遠不被資料商修訂。
九格參數和兩段時間都要成立
熱圖顏色是策略日夏普減0050日夏普,零是分界。每個設計至少要七格為正,中央設定也要在前後半段各自領先。台股切點為2021年11月25日與11月26日,持倉連續保留,不在切點重新挑一組比較好看的股票。
本次前後半段是同一段歷史的穩健性檢查,沒有獨立樣本外,也沒有發表後測試。Bailey等人(2015)討論回測過擬合風險;反覆嘗試交易規則,再只留下最好的一個,可能讓歷史勝出失去解釋力。這次沒有因為某一格接近基準,就改動雙底間隔或容差再試到過關。
股票池與實際換股
個股股票池每日取60日平均原價成交額前300名,股價至少10元、成交額至少2千萬元、有252日價格。代碼限首碼1至9的四位數個股,ETF另測0050。金融、KY沒有另排除,全額交割未另辨識;未用今天名單回頭挑股票,資料來源缺少的下市標的仍可能造成存活偏差。
當股票先前252日有至少50%單日異動,從隔日起排除;這個限制只根據當時已發生的資料,不預知未來的拆併股或異常。訊號出現後取流動性最高的最多10檔,每檔上限10%,沒有名額的訊號仍計入符合資格買訊。當日收盤決策、次一交易日收盤成交,每日排序會產生額外換股。
表格日夏普不扣無風險利率;互動報告預設扣2%,讀數因此不同。台股使用FinLab sim()預設每邊0.1425%手續費與賣出0.3%證交稅,未再加滑價;0050含息基準直接由還原價連乘,不扣交易成本。股票少於10檔時剩餘現金不分配給其他持股。這個設定避免只找到一個W底時,就假設全部資金集中在那一檔,但也讓選股數和現金比重成為績效的一部分。風險管理指南有更多關於集中持股與回撤的解釋。
| 設計 | 符合資格買訊 | 實際選入次數 | 平均個股權重固定組夏普 | 年周轉 | 單月最高周轉 |
|---|---|---|---|---|---|
| 台股個股・W/M・正向 | 375 | 654 | 1.18 | 6.80 | 1.40 |
| 台股個股・W/M・避開 | 375 | 346 | 1.41 | 3.53 | 0.90 |
| 0050・W/M・正向 | 3 | 3 | 1.13 | 0.32 | 0.50 |
| 0050・W/M・避開 | 3 | 4 | 1.13 | 0.32 | 0.50 |
買訊是原始正向進場事件,避開版因此使用相同計數;實際選入次數反映了排名及重新選入,不能視為同一個指標。年周轉用每日目標權重變動絕對值的一半再乘252,單月最高則逐月加總;這是資金換手強度,與交易勝率無關。
為分辨「訊號好」和「只是現金多」,另算0050乘平均總權重的固定曝險組,以及各股票整段平均權重的固定持有診斷組。後者用了事後平均,只供分解績效,不能直接部署;缺價格的部分視為現金。也把中央設定報酬最高的一年移除,完整數字存入下載檔。四個設計都已在必要檢查失敗,沒有選擇性改用回撤指標宣稱通過。
W底與其他轉折研究怎麼分
雙底只需要三個轉折,頭肩頂與頭肩底需要五個,兩肩之間還有更突出的頭。型態越嚴,訊號可能越稀疏,兩者不能共用訊號數。若使用的是更高高點與更高低點,則接近道氏理論;以均線走平或回測為進場條件,另見葛蘭碧法則。
學習技術分析時,圖形定義、確認時點、執行規則應分開記錄。把W底當作標記行情的語言,可以有助討論;要用它決定資金進出,還需要比較同視窗基準和成本。程式交易完整指南整理把文字規則變成回測的流程,選股研究指南則說明股票池與排名怎麼影響結果。
常見問題
W底第二個低點一定要更低嗎?
本次只要求兩底在容差內,不強制第二個低點更低。加入洗盤、量縮等條件會形成新設計,不能拿本次結果代替。
W底突破後要追價嗎?
回測在訊號日之後的下一交易日收盤成交,沒有保證以頸線價買到。跳空越大,畫圖時想像的進場價與可成交價格可能越遠。
M頭出現就要放空嗎?
本文M頭只用於賣出已持有的股票。放空還涉及借券與回補限制,沒有包含在這組成本與績效中。
為什麼0050訊號那麼少?
相同的間隔、反彈深度與確認規則,套在ETF上未必頻繁成立。這是規則的可用範圍,不能刪掉空手年份來改善指標。
W底和三重底可以合併計算嗎?
不能直接合併。本文只取連續三個轉折,多一個底會改變狀態與觸發時點,應另外固定定義後檢驗。
未通過是否表示技術分析沒用?
只能支持本文的四個設計沒有通過這段資料的驗證。其他交易規則、風險承擔與樣本期間,需要各自研究,不能擴大成所有技術分析的結論。
下載與重跑
可下載逐日淨值 data.csv、完整參數與版本 metrics.json、單一設計 strategy.py,以及整批研究 research.py。整批研究需要把共用 strategy.py放在同一個資料夾;執行 python research.py,會輸出全部參數、各中央設定的回測報告與逐日資料。單篇的程式預設重跑該篇主題;這些規則尚未通過驗證,沒有對應的上架策略。
顯示程式碼
from strategy import load_prices, make_position
from finlab.backtest import sim
prices = load_prices("tw")
position, entries = make_position(prices, family="wm")
report = sim(position, position_limit=0.1, upload=False,
end_date="2026-11-10")
report.to_html("report.html")範例需先下載同資料夾的程式。環境使用 FinLab 2.3.8、pandas 3.1.1,另需 NumPy、SciPy、Numba、Plotly、Kaleido 與 python-dotenv。資料截至2026年11月10日,重跑日為11月11日;資料日與執行日分開記錄,日後上游修訂可能讓同視窗數值不同。安裝步驟見FinLab設定指南,名詞可查量化交易詞彙。
FinLab量化研究團隊以資料與可重跑規則研究投資方法。本文尚未做發表後的前瞻驗證,也未估算資金容量。
投資有風險,過去績效不代表未來表現。本內容僅供教學參考,不構成投資建議,請依個人風險承受度審慎評估。
最後更新:2026-11|回測區間:2017-01-03至2026-11-10|作者:FinLab量化研究團隊
FinLab AI
想建立自己的策略?
用自然語言描述你的選股想法,AI 自動驗證、回測、給你答案
免費開始





