回測資料品質:缺 K 棒、壞價、時區與轉倉
缺 K 棒、異常成交價、時間戳位移與接合不當的轉倉,都會改變回測做了哪些交易、以什麼價格成交。請在匯入資料前,而不是研究完之後,檢查 K 棒數量、價格尖峰、交易時段時間與轉倉日期。
作者 Soren Huang · 發佈 · 更新於 · 編輯原則
目錄
歷史 K 棒資料可能出什麼問題?
歷史 K 棒資料主要有四種毛病:缺 K 棒、異常成交價、時間戳位移,以及接合不當的合約轉倉。每一種都會改變回測做了哪些交易、以什麼價格成交。策略搜尋往往會獎勵那些讓結果變好看的錯誤。請在匯入資料前,先檢查 K 棒數量、價格尖峰、交易時段時間與轉倉日期。
價格 K 棒是一列資料,記錄某個市場在固定期間(例如五分鐘或一天)內的開盤、最高、最低、收盤與成交量。回測會逐列讀取這些資料,並在每根 K 棒上決定是否交易。如果某一列缺漏、錯誤或位置不對,回測就是在一個從未存在過的市場裡交易。
想像你拿一張缺了幾條路、又在不存在的地方畫了一座橋的地圖來規劃行車路線。路線規劃工具分不出那座橋是假的,只因為它是最短路徑就走了上去。策略搜尋對待假價格的方式也一樣。
| 問題 | 資料中看到的現象 | 對回測的影響 |
|---|---|---|
| 缺 K 棒 | K 棒數量少於該交易時段應有的數量 | 指標涵蓋的實際時間比參數設定所暗示的更長,交易時段出場位置移動,並出現假跳空 |
| 異常成交價 | 某一根 K 棒的最高或最低價遠離其他 K 棒 | 出現不可能成交的委託成交,並使波動度讀數膨脹 |
| 時區位移 | 某些日期的開盤時間差了一小時 | 以時間為條件的規則會交易到交易時段中不同的時段 |
| 轉倉接合 | 換月當天價格出現跳動 | 出現沒有任何交易者賺到的損益,以及錯誤訊號 |
缺 K 棒與假日如何改變回測?
缺 K 棒會讓指標涵蓋更長的實際時間,並移動以交易時段為基準的出場,使回測不再符合你實際會交易的市場。缺 K 棒指的是資料中本應有一根 K 棒、卻沒有的期間。
並非每個缺口都是錯誤。檔案中有三種缺口看起來很像:
- 交易所假日與縮短的交易時段。市場休市或提早收市。這些缺口是正確的,應該保留。
- 交投清淡市場的安靜期間。有些資料來源在沒有成交時就不產生 K 棒。市場有開,只是沒有成交。
- 資料中斷。市場有成交,但資料來源或你自己的記錄漏掉了。這類缺口才是錯誤。
資料中斷會從三方面改變結果。橫跨中斷的 20 根 K 棒移動平均,涵蓋的時數比其參數設定所暗示的更多。在交易時段最後一根 K 棒出場的規則,若最後幾根 K 棒缺漏,就會提早出場。而當中斷後 K 棒恢復時,價格的跳動看起來像真正的跳空,於是以跳空為基礎的策略就會去交易它。
要找出資料中斷,先算出完整交易時段應有多少根 K 棒,再逐日計算 K 棒數量。例如,台指期日盤從台灣時間 08:45 到 13:45。若每根 K 棒都涵蓋完整的五分鐘,就是 60 根五分鐘 K 棒。列出所有低於預期數量的日期,再與交易所假日行事曆比對。剩下的就是你的資料中斷清單。回測中的市場假日一文說明了假日缺口與重新開市如何影響訊號。
異常成交價與尖峰對結果有什麼影響?
一筆異常成交價就可能造成一筆根本不可能成交的交易,而策略搜尋常會把這筆交易排在很前面。異常成交價是指記錄下來的成交價,遠離市場真正成交的位置。常見原因是行情源錯誤、交易所事後取消的成交,或來源檔案中的失誤。
在 K 棒圖上,異常成交價通常表現為一條很長的影線。影線是 K 棒實體上方或下方的細線,標示最高價或最低價。限價單與停損單最容易受影響,因為只要 K 棒的最高價或最低價碰到委託價格,回測就會讓它成交。
假設範例
某指數期貨在 18,000 點附近交易。一個均值回歸策略在低於市價 150 點的 17,850 掛出買進限價單。有一根五分鐘 K 棒出現 17,600 的異常成交價作為最低價,而該 K 棒中所有真實成交都在 17,990 到 18,010 之間。回測在 17,850 讓買單成交。該 K 棒收在 18,000,策略在下一根 K 棒於 18,000 附近出場。回測記錄了 150 點的獲利,但沒有任何期貨商能讓這筆單成交。如果該策略總共只有 40 筆交易,這一筆假交易就可能占整體結果的很大一部分。
異常成交價也會扭曲指標。平均真實波幅(ATR)由每根 K 棒的最高價與最低價計算而來,所以一個尖峰會讓它在之後很多根 K 棒都偏高。這會改變任何以 ATR 為基礎的停損或部位大小。使用某期間最高價或最低價的通道規則,在整個回看期間內都會保留那個錯誤的值。
三種掃描可以找出大多數異常成交價:
- 波幅掃描。標記最高到最低的波幅是周圍 K 棒平均波幅數倍的 K 棒。五倍是合理的起點;請依各市場調整。
- 跳離又回歸掃描。標記收盤價從前一收盤價大幅跳離、而下一根 K 棒又回到原水準的 K 棒。真實的快速行情也可能這樣,所以請把這些 K 棒當成要檢查的對象,而不是要刪除的對象。
- 一致性掃描。最高價必須不低於開盤價與收盤價,最低價必須不高於兩者。價格為零就是錯誤。
確認某筆成交價是異常後,用乾淨的成交重建該 K 棒。如果你只有 K 棒資料,就把它的最高價與最低價設為開盤價與收盤價中較高與較低的那個。把每一項更動都記下來,才能復原。真實的快速行情請保持原樣;那是策略需要的資訊。
時區與夏令時間如何讓 K 棒位移?
如果你的時間戳依據的是錯的時鐘,任何與一天中時間綁定的規則,在某些日期就會交易到交易時段中不同的時段。時區是時間戳所用的時鐘,例如交易所當地時間、UTC 或你自己的當地時間。
夏令時間每年讓時鐘調整一小時兩次,各地區切換的日期不同。美國在三月第二個星期日與十一月第一個星期日切換。歐盟在三月最後一個星期日與十月最後一個星期日切換。台灣不實施夏令時間。因此台北與紐約之間的時差在一年中會相差一小時。
舉一個具體例子:美國股市在紐約時間 09:30 開盤。換算成台灣時間,從三月第二個星期日到十一月第一個星期日之間是 21:30,其餘時間則是 22:30。一條寫成「只在台灣時間 21:30 到 22:30 之間交易」的規則,一年中有一部分時間涵蓋的是美股開盤後第一小時,其餘時間涵蓋的則是開盤前一小時。
另外還有兩個常見的時間戳問題:
- K 棒標籤。有些來源以起始時間標記 K 棒,有些以結束時間標記。標為 10:00 的 K 棒,可能是 09:55 到 10:00,也可能是 10:00 到 10:05。如果你合併兩個標記方式不同的序列,其中一個就會看到未來一根 K 棒。
- 重複轉換。原本已經是當地時間的檔案,在匯入時又被轉換一次,每根 K 棒都會位移整個時區差。
快速檢查的方法:畫出每個時間點的平均成交量,每個月一條線。以交易所當地時間來看,主要開盤的成交量高峰在全年都停在同一個時鐘時間。如果高峰在三月與十一月跳了一小時,就表示時間戳不是交易所時間。關於交易時段的選擇如何改變 K 棒,請見期貨回測中的夜盤。
連續月期貨合約該如何轉倉與調整?
請有意識地選擇轉倉規則與調整方法,因為每一種都會改變你的回測所顯示的價格或損益。連續月合約是把一口接一口的期貨合約,在各自接近到期時接合起來所形成的長價格序列。轉倉指序列從即將到期的合約切換到下一個合約的那一點。
合約依固定時程到期。ES 與 NQ 有季月合約,在三月、六月、九月與十二月到期。台指期有月合約,在交割月份的第三個星期三結算。資料來源通常在到期前固定天數轉倉,或在成交量移到下一個合約時轉倉。台指期回測檢查清單涵蓋了該市場其他特有的設定。
在轉倉當天,兩個合約通常以不同的價格交易。序列如何處理這個差額,就是調整方法:
| 方法 | 做法 | 什麼保持正確 | 什麼會改變 | 適合的規則 |
|---|---|---|---|---|
| 未調整 | 以實際成交價格直接接合 | 真實的價格水準 | 每次轉倉都有一個跳動,帶來沒有人賺到的損益 | 使用固定價格水準,並在每次轉倉前平倉 |
| 後向調整 | 把所有較舊的價格以轉倉價差(點數)平移 | 點數波動與以點數計的損益 | 較舊的價格水準;很長的歷史甚至可能跌到零以下 | 以點數或跳動點設定停損與停利 |
| 比例調整 | 把所有較舊的價格乘以同一個係數 | 百分比波動 | 較舊資料中的點數距離 | 使用以百分比計的波動 |
比例方法只用到一個數字:係數 = Pnew ÷ Pold。Pnew 是轉倉時新合約的價格,Pold 是同一時刻即將到期合約的價格。轉倉前的每個價格都要乘上這個係數。
假設範例
轉倉時,即將到期的合約價格為 18,000,新合約為 18,100,相差 100 點。未調整的情況下,跨越轉倉持有的多單會顯示 100 點的獲利,但沒有任何交易者賺到這筆錢,突破規則也可能看到一個新高。後向調整時,之前每個價格都加上 100 點,所以一年前 15,000 的收盤價變成 15,100。比例調整時,之前每個價格都乘上 18,100 ÷ 18,000,約 1.0056,所以同樣的 15,000 變成約 15,083。
在實單交易中,轉倉意味著賣出一口合約並買進下一口,兩筆交易都有手續費與滑價。連續月序列把這兩筆交易藏起來了。對於持倉數週的策略,請把轉倉交易算進你的成本估計。
為什麼要在策略搜尋之前修正資料?
策略搜尋找出資料錯誤的速度比你快,因為剛好在壞價格上成交的變體會升到排名最前面。當你測試許多規則與參數組合時,其中一些會因巧合而與某個尖峰、某次轉倉跳動或某段缺漏的時間對上。它們的結果看起來很強,原因卻永遠不會重演。這是過度最佳化的一種形式。過度最佳化是指策略的規則擬合了過去資料中的雜訊,而不是會重複出現的規律。策略生成中的過度最佳化一文對此有深入說明。
有兩個跡象指向資料錯誤而非真正的優勢。第一,單一一筆交易占了總獲利的很大比例。第二,最好的交易集中在少數幾個日期。如果看到任何一個跡象,請先去原始資料檢查那些日期。
匯入資料前應該檢查什麼?
每個資料檔案都依照下列順序檢查一次,並簡短記錄你發現與更動的內容。
- 時鐘與標籤。確認時間戳的時區,以及每根 K 棒是以起始時間還是結束時間標記。
- K 棒數量。計算每個交易時段的 K 棒數量,列出較短的日子,並與交易所假日行事曆比對。其餘的就是資料中斷。
- 重複與順序。找出重複的時間戳與時間順序錯亂的列,這些常在合併檔案後出現。
- 價格一致性。確認每個最高價與最低價都涵蓋開盤價與收盤價,且沒有價格為零。
- 尖峰。執行波幅掃描與跳離又回歸掃描,再檢查每一根被標記的 K 棒。
- 轉倉。列出最大的 K 棒間跳動。在未調整資料中,它們應該與轉倉日期對得上。弄清楚該序列使用哪種轉倉規則與哪種調整方法。
- 第二來源。把一個樣本(例如每年某一週的日收盤價)與第二個資料來源比較。
- 版本記錄。記下檔案名稱、來源、日期範圍與每一項更動,讓之後任何結果都能追溯到它的資料。
接著讓回測設定與你檢查過的資料一致:相同的交易時段時間與相同的 K 棒週期。在 AlphaPrime(Valynox)中,GPU 回測的研究範圍可讓你設定資料解析度與交易時段,讓研究在你驗證過的交易時段上進行。
如果你使用 AlphaPrime,這代表:匯入前先對你的 K 棒資料跑一遍檢查清單,並把交易時段設定成與你驗證過的一致。如果之後修正了資料,請把每個資料版本的結果分開放在不同批次,並對保留下來的策略重新檢驗,讓每次比較都使用相同的資料。
常見問題
期貨歷史資料中的壞價(bad tick)是什麼?
壞價是指記錄下來的成交價遠離市場真正成交的位置,原因可能是行情源錯誤、被取消的成交或檔案失誤。它在 K 棒圖上通常表現為一條長影線。在回測中,它可能讓限價單或停損單在真實價格從未到達的位置成交,因此造成不可能發生的交易。
連續月合約資料該用後向調整還是比例調整?
當你的規則以點數或跳動點衡量波動時,使用後向調整資料,因為它能保持點數差距正確。當你的規則以百分比衡量波動時,使用比例調整資料,因為它能保持百分比變化正確。與固定價格水準比較的規則則使用未調整資料,並在每次轉倉前平倉。
如何找出歷史資料中缺少的 K 棒?
先算出在你的 K 棒週期下,完整交易時段應包含多少根 K 棒,再逐日計算 K 棒數量。列出低於預期數量的日子,並排除交易所假日與已知的縮短交易時段。剩下的日子很可能是資料中斷,需要用第二個來源補上,或在你的記錄中標註。
夏令時間會影響期貨回測嗎?
當時間戳所用的時鐘與交易所切換日期不同,或規則使用固定的時鐘時間時,就會受影響。例如紐約時間 09:30 的美股開盤,夏季是台灣時間 21:30,冬季是 22:30,因為台灣不實施夏令時間。把資料存成交易所當地時間,可以讓交易時段的開盤在全年都維持在同一個時鐘時間。
AlphaPrime 在這裡能幫上什麼
AlphaPrime 的 GPU 回測會在你匯入的 K 棒資料上執行研究,並在研究範圍中設定資料解析度、下一根 K 棒成交、手續費與滑價,以及交易時段。策略資料庫透過搜尋與排序、分類、批次管理與重新檢驗,讓結果井然有序,使策略能在資料修正後重新檢查。

