在台灣的程式交易社群與量化團隊合作中,時常發生這樣的窘境:朋友或同事分享了一套號稱『近十年夏普值 1.8、最大回撤不到 8%、勝率超過六成』的台指期策略程式碼。
當你興沖沖把腳本匯入自己的 MultiCharts 或 Python 環境執行,跑出來的報表卻令人大失所望——夏普值不到 0.6,回撤甚至直接翻倍。對方往往只能含糊解釋:『可能你用的報價源換月除權息算法不同,或者套件版本有些微差異吧。』
在科學實證的範疇裡,一個無法被獨立第三方完整重現的實驗結果,會立刻被視為偽科學;在金融交易中,一個無法複現的回測(Irreproducible Backtest)同樣危險——它通常掩蓋了嚴重的過度最佳化、隨機數未固定、前視偏差或粗糙的環境依賴。本文為你完整解析達成 100% 可複現回測的六大核心工程準則。
回測的可複現性(Reproducibility)是指任何一位獨立審查者(或是數年後換了全新工作站的你自己),只要取得相同的原始腳本與設定,便能在任何時間、任何設備上完全精確地產出毫釐不差的交易明細與績效數據。這必須嚴格落實 6 大工程支柱:(1) 固定不變的資料集版本與雜湊校驗碼、(2) 排除未固定隨機種子的確定性演算法、(3) 集中管理且外部化的參數設定檔、(4) 清楚透明的手續費與滑價摩擦模型、(5) 嚴密定義的起訖日期與標的母體、(6) 透過版控徹底鎖定的程式環境依賴(如 requirements.txt 或 lockfile)。
| 工程支柱名稱 | 若未落實造成的經典複現落差 | 量化實務上的達標技術規範 |
|---|---|---|
| 1. 資料版本與雜湊校驗 | 報價商事後追溯修正點數,導致重新執行時歷史曲線變形 | 原始資料封存為唯讀檔案,附上明確的 SHA-256 數位指紋 |
| 2. 確定性執行邏輯 | 同分數平局未定義或隨機演算法導致每次訊號略有不同 | 硬編碼固定隨機種子 (`seed=42`),多條件排序定義次要排序規則 |
| 3. 參數外部化設定檔 | 關鍵停損停利閾值散落在各個檔案中,換人執行容易漏設 | 所有策略參數統整於獨立的 `config.yaml` 或 `settings.json` |
| 4. 具體摩擦成本模型 | 不同測試者漏設期交稅或給予過度樂觀的零滑價成交 | 明確標註單筆手續費、稅金計算方式與進出場強制滑價點數 |
| 5. 明確標的池與區間 | 拿目前台灣 50 成分股直接回測 10 年前資料引入生存者偏差 | 精準鎖定各歷史年份當下的成分股名單與明確的日曆日區間 |
| 6. 鎖定運算環境相依性 | 第三方函式庫升級導致特定技術指標計算公式底層微調 | Git Commit 標籤明確搭配 `requirements.txt` 或虛擬環境配置 |
- 乾淨新設備一鍵跑通測試:將 Git 專案複製到一台全新未設定過的電腦上,是否能透過標準化指令直接重現完全相同的權益曲線?
- 全流程杜絕手工 Excel 介入:從原始資料讀取、策略指標運算、進出場訊號產生到報表產出,是否全程 100% 透過程式自動化完成?
- 固定所有隨機性函式:若策略採用蒙地卡羅模擬(Monte Carlo)或隨機拆分回測折數,是否已在入口處統一定義了固定的隨機種子?
- 策略訊號與撮合引擎解耦:將買賣決策邏輯與回測下單撮合架構分離,避免因回測工具升級而不知不覺改變了策略訊號。
常見問題
本課探討的『可複現性』與第 33 課的『如何回測』有何不同?
第 33 課聚焦於『如何建立回測流程與指標解讀』(解決策略在歷史上是否具備正期望值);而第 45 課聚焦於『策略研究的同行評審與科學信度』(確保他人能完全重現你的數據,杜絕過度擬合造假)。
為什麼別人在 MultiCharts 跑我的指標,得出的最大回撤比我大很多?
最常見的原因是『歷史資料長度與換月價差處理不一致』,或是雙方在圖表交易設定裡的『委託單滑價點數(Slippage)』設定不同,導致高頻進出的累積磨損大幅分歧。
個人程式交易者如何以最簡單的方式鎖定 Python 環境?
在專屬虛擬環境建立完成後,執行 `pip freeze > requirements.txt` 並提交至 Git;若採用現代套件管理工具(如 `poetry` 或 `uv`),則直接將產生的 `lockfile` 納入版控,即能確保跨設備環境完全一致。



