未來函數是你的規則用到了那一刻還拿不到的數字。它多半不是公式寫錯,是時間軸接錯。同一個 20 日均線策略,標普 500 ETF 二十二年:正確寫法年化 +4.54%,把成交挪到同一天開盤變成 +33.36%,買在當天最低、賣在當天最高變成 +24.73%,均線改成置中平均則是 -23.96%。18 檔標的的方向全部一樣。最好認的特徵是,正確寫法通常很平庸,甚至輸給買進持有。
下面直接回答這幾題
未來函數是什麼
未來函數在英文文獻裡叫前視偏誤,台灣的程式交易圈習慣講未來函數。它們指的是同一件事:你的規則在第 t 天做決定的時候,用到了第 t 天還拿不到的數字。
它最常見的形式不是「偷看明天的股價」這種明顯的作弊,多數人不會那樣寫,而是藏在一兩行看起來很無辜的程式裡,像是成交價取錯欄位、指標算法用了前後對稱的窗口、或者門檻其實是拿整段歷史算出來再回頭套用的。
那要怎麼判斷一段規則有沒有這個問題?方法只有一句話。把你的規則想像成當天收盤前的自己,問這個數字那個時候拿得到嗎。拿不到,就是未來函數。
BOS 回測:同一個策略,四種寫法
我們拿一條很常見的規則當載體:收盤價在 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 次。
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 檔美股與 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 檔是舉例不是選股清單。最後,我們只示範了三種「時間軸接錯」的寫法,其他讓回測失真的原因,例如成分股用今天的名單、財報用期間結束日、參數事後挑過,這篇都沒有量。
延伸閱讀

量化交易是什麼?
台灣散戶技術指標實測報告
勝率高就會賺錢嗎?


