進階課程 · Lesson 3
若策略在時間 t 決策,只能使用 available_at <= t 的資訊。資料表至少要區分:
event_time:經濟事件真正發生的時間;published_at:來源首次發布時間;available_at:你的系統實際可取得時間;revised_at:資料後續修訂時間;ingested_at:進入研究資料庫時間。回測的 join 應優先按 available_at 向後匹配,而不是按「財報屬於哪一季」或「事件日期」直接合併。pandas.merge_asof(..., direction="backward") 可表達「只取決策時間以前最近一筆」,但仍要先確認欄位語意與排序。
錯誤做法:以今天仍在 S&P 500 的公司名單回測 2010 年策略。這會排除破產、下市、被併購或退出指數的公司,也把後來成功入選的公司提前放回過去。
正確做法:
effective_from/effective_to;倖存者偏誤不只發生在股票:加密貨幣交易對、基金、交易所、策略排行榜都會把失敗者從資料中消失。
常見來源:
shift(-1)、未限制窗口的全樣本 mean();最簡單的人工測試是「截斷資料」:只保留到某日,重新計算該日以前的 features。若過去數值因加入未來資料而改變,就有洩漏風險。Freqtrade 官方亦提供 lookahead-analysis,用基準回測與切片回測比較指標及訊號差異。
測試 500 個規則後只展示 Sharpe 最高者,表面上只有一個回測,實際上做了 500 次選擇。即使每個規則本身沒有程式錯誤,最佳結果仍會被幸運噪音抬高。必須記錄所有研究嘗試,而不是只保存最後版本。
Stock split(股票分割)會按比例降低每股價格並增加股數,持有人總市值不因分割本身改變。若直接用 raw close 計算報酬,分割日可能看起來像巨大崩跌。
但「一律使用 adjusted close」也不夠:
研究資料應同時保存 raw OHLCV、adjustment factor 與 corporate-action event table,並明確記錄用途。
「09:30」必須附時區。美股使用 America/New_York,不能用固定 UTC offset 代替,因 daylight saving time(夏令時間)會改變 UTC 對應。
還要確認 vendor 的 bar timestamp 表示:
若 09:30 標記的是 09:30–09:31 的完成 bar,其 high/low/close 最早在 09:31 才完整可知。把它當成 09:30 即時資訊會提前一分鐘。
OHLC 基本條件:
high >= max(open, close, low)
low <= min(open, close, high)
volume >= 0
timestamp unique and increasing
每個資料集至少記錄:
vendor/endpoint:
symbol definition:
timezone:
bar timestamp semantics:
frequency:
session calendar:
raw or adjusted:
corporate-action method:
revision policy:
known missing intervals:
retrieval timestamp:
checksum/version:
沒有 data contract,就很難重現同一個回測。
執行:
python .\code\data_quality_audit.py
範例會故意放入重複 timestamp、OHLC 不一致與負 volume,確認稽核器能抓出錯誤。再將錯誤修正,應得到零項 issue。
面對任何 feature,逐欄問:
七題說不清楚,先停止策略優化,回頭修資料。