關閉選單

未來函數是什麼?同一個策略四種寫法,年化從 -24.0% 到 +33.4%

10 秒看懂
未來函數是你的規則用到了那一刻還拿不到的數字。它多半不是公式寫錯,是時間軸接錯。同一個 20 日均線策略,標普 500 ETF 二十二年:正確寫法年化 +4.54%,把成交挪到同一天開盤變成 +33.36%,買在當天最低、賣在當天最高變成 +24.73%,均線改成置中平均則是 -23.96%。18 檔標的的方向全部一樣。最好認的特徵是,正確寫法通常很平庸,甚至輸給買進持有。
下面直接回答這幾題
  1. 未來函數是什麼
  2. BOS 回測:同一個策略,四種寫法
  3. 前兩種錯法各自偷到了什麼
  4. 把訊號換成擲銅板
  5. 置中均線把訊號變成反的
  6. 換標的也一樣
  7. 怎麼自己抓出未來函數
  8. 這次回測要先講清楚的事
  9. 常見問題

未來函數是什麼

未來函數在英文文獻裡叫前視偏誤,台灣的程式交易圈習慣講未來函數。它們指的是同一件事:你的規則在第 t 天做決定的時候,用到了第 t 天還拿不到的數字。

它最常見的形式不是「偷看明天的股價」這種明顯的作弊,多數人不會那樣寫,而是藏在一兩行看起來很無辜的程式裡,像是成交價取錯欄位、指標算法用了前後對稱的窗口、或者門檻其實是拿整段歷史算出來再回頭套用的。

那要怎麼判斷一段規則有沒有這個問題?方法只有一句話。把你的規則想像成當天收盤前的自己,問這個數字那個時候拿得到嗎。拿不到,就是未來函數。

BOS 回測:同一個策略,四種寫法

同一個 20 日均線策略四種寫法的年化報酬對照

標普 500 ETF,2004 到 2026 年,成本一律設 0。

我們拿一條很常見的規則當載體:收盤價在 20 日均線之上就持有,跌破就空手。標的是標普 500 ETF,期間從 2004 年 1 月一路到 2026 年 9 月共 22.7 年,中間總共進出場 324 次,平均有 66.0% 的日子是在場內的。

同一條規則,四種寫法:

A 正確寫法:第 t 天收盤算出訊號,第 t+1 天開盤成交。年化 +4.54%。
B 早一步成交:一樣用第 t 天的收盤價算訊號,卻在第 t 天的開盤成交。年化 +33.36%。
C 買最低賣最高:訊號跟 A 一樣,可是買在當天的最低價、賣在當天的最高價。年化 +24.73%。
D 置中均線:均線從「過去 20 天」改成「前後各 10 天」的置中平均。年化 -23.96%。

這裡有一件事要先講明白。A 是你實際做得到的版本,它的 +4.54% 還輸給買進持有的 +10.86%。這篇沒有要評價這條均線規則,它只是載體,重點是同一條規則在四種寫法下的距離。

前兩種錯法各自偷到了什麼

B 跟 C 的年化都很漂亮,可是它們各自偷到了什麼?答案完全不一樣,而這一點後面會變成整篇最有用的部分。

B 偷的是訊號日當天的漲幅。訊號的條件是收盤價站上均線,能滿足這個條件的日子,當天本來就偏強。資料上,訊號成立那天的開盤到收盤平均 +0.149%,訊號不成立的日子是 -0.249%,全部日子平均只有 +0.014%。你用收盤價決定要不要買,卻讓自己在開盤就買到,等於每一個在場的日子先把這一段領走。

C 偷的是當天的價格區間。進場日的最高價到最低價平均相差 1.169%,出場日是 1.320%,而假設你每一趟都剛好買在最低、賣在最高,等於每一次來回都白拿這兩段的一部分,324 次累積起來就是那 20.18 個百分點的差距。

把訊號換成擲銅板

用隨機訊號重跑三種寫法的年化報酬

在場比例維持 66.0%,跑 200 次取中位數。

要分辨一個漂亮的回測是策略本身厲害、還是寫法在作弊,最乾脆的方法是把策略整個拿掉,所以我們把均線訊號換成擲銅板,在場比例一樣維持 66.0%,其他條件全部不動,跑了 200 次。

C 的結果是年化 +112.38%。訊號完全沒有資訊,報酬還是比原本那個「真」策略更誇張。這證明它的報酬完全來自成交價,跟你選什麼訊號一點關係都沒有。

B 的結果只有 +7.00%,跟正確寫法的 +7.07% 一模一樣。這個對照比上面那個更有意思。它說明 B 並不是「提早一天成交就會賺」,它會賺,是因為那個訊號本身偷看了當天的收盤價。訊號一旦不再偷看,同樣的程式碼就什麼都變不出來。

兩個對照的結論不同,所以自己檢查的時候兩種都要做,只做一種會把機制認錯。

置中均線把訊號變成反的

置中均線與一般均線之上之下,之後十天的平均漲跌對照

置中均線之上的日子,之後十天平均是往下的。

D 最反直覺。它同樣用到了未來的資料,結果卻是年化 -23.96%,比正確寫法還差了 28.50 個百分點。用到未來資料為什麼反而變差?

因為置中均線的意思是「今天跟前後各 10 天比」。今天的價格高於那個平均,代表後面 10 天多半比今天低。所以「收盤高於置中均線」這個條件,其實是在挑「接下來會跌」的日子,卻被拿來當買進訊號。

資料完全對得上。置中均線之上的日子,之後 10 天平均 -0.622%,之下的日子是 +1.837%。換成一般的均線(只看過去 20 天),之上是 +0.369%、之下是 +0.638%,兩邊幾乎沒有差別。

這裡要記住的重點是:未來函數不一定讓數字變好看,它讓數字變成假的。所以看到一個結果差到離譜的回測,也值得回頭檢查一次時間軸有沒有接錯,不要太快認定那個想法本身沒用,畢竟被接錯的時間軸能把一條普通的規則拉高,也能把它壓到地板下面去。

換標的也一樣

18 檔標的在四種寫法下的年化報酬分布

每一個點是一檔標的。四群之間沒有重疊。

一檔標的可能是巧合,所以我們把同樣四種寫法跑在 18 檔美股與 ETF 上。

結果是一面倒:B 比 A 高 18/18,C 比 A 高 18/18,D 比 A 低 18/18。中位數分別是買進持有 +10.48%、正確寫法 +4.50%、早一步成交 +57.88%、買最低賣最高 +42.14%、置中均線 -37.52%。

更清楚的是兩群連碰都沒碰到。正確寫法裡表現最好的一檔是 +28.77%,而早一步成交裡表現最差的一檔是 +33.36%,用錯寫法的最爛結果比用對寫法的最好結果還要漂亮,而兩邊用的是同一份資料、同一條規則。

把期間切成兩半也是同一個樣子。2004 到 2014 年是 +3.42% 對 +35.07%,2015 到 2026 年是 +6.05% 對 +32.02%,正確版與早一步的距離都在三十個百分點上下。

怎麼自己抓出未來函數

那平常自己要怎麼抓?下面三個檢查不用會寫程式也做得到。

第一,把成交往後推一天,看結果掉多少。正確的策略推一天會掉一點,掉的幅度應該跟你原本的預期差不多。掉到面目全非,那個報酬多半本來就是時間差變出來的。

第二,把訊號換成擲銅板再跑一次。擲銅板應該賺不到什麼。如果擲銅板也能跑出漂亮的年化,那就代表問題出在成交價的假設上,跟你的訊號沒關係。

第三,看指標會不會重畫。在看盤軟體上把圖往回捲,如果過去某一天的訊號位置後來變了,那條指標就是用到了後面的資料。置中均線正是最典型的一種,它畫出來特別平滑好看,代價是每一根新的 K 棒出現之後都會回頭改寫前面那幾根的值,你在圖上看到的漂亮訊號當天其實並不存在。

想再往下一層,站上有兩篇可以接著看。回測賺翻了實盤卻不行整理了另外四個陷阱,過度擬合那篇量的是「參數是用事後的資料挑出來的」,跟這篇講的時間軸問題是不同的兩種病。

這次回測要先講清楚的事

第一,成本一律設 0。這次要量的是「用到看不到的資料會多出多少」,加上手續費與滑價會讓四條線一起往下移,彼此的距離不受影響。實際操作當然要算成本,而且交易越頻繁扣得越多。

第二,20 日均線只是載體。挑它的理由是夠常見、夠好解釋,不是因為它好用。正確寫法的 +4.54% 輸給買進持有的 +10.86%,這件事在文章一開始就寫出來了,請不要把這條規則當成可以照做的策略。

第三,這 18 檔是舉例,不是選股清單。挑的標準是大家認得出來、而且 2004 年就已經上市,裡面刻意放了花旗、奇異、福特這種這段期間表現很差的,所以誰的數字好看都沒有推薦的意思。

第四,我們只示範了三種寫法錯誤。回測會失真的原因還有很多,例如成分股用了今天的名單、財報用了期間結束日而不是公布日、或是參數在事後挑過。這篇只處理「時間軸接錯」這一類,其他的沒有量。

常見問題

未來函數和前視偏誤是同一件事嗎?

是。前視偏誤是學術文獻的講法,未來函數是台灣程式交易圈的習慣說法,指的都是規則用到了當下還拿不到的資料。台灣的用語比較貼近實作,因為它直接點名問題出在「函數吃進了未來的值」。

用收盤價當訊號、也用收盤價成交,算不算未來函數?

看你幾點下單。收盤前最後幾分鐘用接近收盤的價格成交,實務上做得到,所以這個寫法不算明顯作弊,不過它假設你每天都能抓到那個價位。我們這次的正確版保守一點,訊號算出來之後隔天開盤才成交。會出事的是上面那個 B,它用收盤價當訊號,卻在同一天的開盤就成交了。

為什麼用到未來資料,結果反而會變差?

因為未來資料不一定站在你這邊。置中均線就是例子,它的「收盤高於均線」等於在挑後面十天會下跌的日子,拿來當買進訊號自然很慘。資料上這些日子之後十天平均 -0.622%,一般均線之上則是 +0.369%。所以看到一個差到離譜的回測,也該檢查時間軸,不要直接認定那個想法沒用。

我不會寫程式,怎麼知道看盤軟體上的指標有沒有問題?

把圖往回捲,找一個過去出過訊號的位置記下來,然後切換週期或重新整理再看一次。位置有變、或是訊號消失了,那條指標就會重畫,也就是用到了後面的資料。畫出來特別平滑、幾乎沒有雜訊的線,值得多看兩眼。

把訊號換成擲銅板這招,為什麼兩種錯法的結果不一樣?

因為它們偷的東西不同。買最低賣最高的報酬來自成交價,跟訊號無關,所以擲銅板照樣跑出 +112.38%。早一步成交則是靠訊號偷看當天收盤,訊號一旦換成擲銅板就失效,只剩 +7.00%,跟正確版的 +7.07% 一樣。兩種檢查都要做,只做一種會把病因認錯。

這條 20 日均線策略可以用嗎?

這篇沒有回答那個問題,它只是拿來示範的載體。不過可以告訴你的是,正確寫法的年化 +4.54% 輸給同期買進持有的 +10.86%,而且我們還沒有扣手續費與滑價。要評價一條規則好不好,需要的是另一套做法,不是這篇的四種對照。

這次回測有什麼限制?

有四個。成本一律設 0,實際操作會更低。20 日均線只是載體,不是推薦的策略。這 18 檔是舉例不是選股清單。最後,我們只示範了三種「時間軸接錯」的寫法,其他讓回測失真的原因,例如成分股用今天的名單、財報用期間結束日、參數事後挑過,這篇都沒有量。

林修禾 Joshua Lin

本文作者|林修禾 Joshua Lin

投資與教學資歷都超過二十年。教學橫跨三個階段:從兒童理財教育起步,到成人的價值投資,再到近年的量化交易。曾創立三間公司,並以價值投資建立起財務上的獨立與自信,也擔任過台積電的理財培訓師,是價值投資的國際級講師。他始終相信,理財是為了把生活過得更好,而看懂財報、獨立思考,遠比追逐明牌或現成的答案更重要。

延伸閱讀