週一,我們的 AI 研究代理找到一套加密貨幣期貨策略,Sharpe ratio 達 4.1。到了週四,在我們統計實驗次數,並停止讓代理對著同一段驗證期間調參後,結果降到 0.8。策略沒有改變,改變的是我們對搜尋成果的估計。
我們把這次研究記錄成一份簡短日誌,因為「謹慎最佳化」說來容易;但當代理能寫程式、啟動回測、查看分數,幾分鐘後又再試一次時,要把這句話落實並不容易。以下依序記下出了哪些問題。
週一:給代理一個範圍明確的問題
我們請代理在流動性高的永續期貨市場測試一個簡單的每小時趨勢構想:短期移動平均線向上穿越長期移動平均線時進場,依固定波動率目標設定部位大小,反向訊號出現時平倉。我們指定了交易標的、日期、手續費表、資金費率歷史、執行假設,以及可探索的參數範圍。
歷史樣本涵蓋 2021 至 2025 年。我們將 2021–2023 年指定為開發期、2024 年指定為驗證期,並將 2025 年封存為最終保留測試集。這項切分寫進了工作設定,因此代理可以讀取開發期結果和驗證分數,卻無法取得保留測試集的報酬資料。
我們犯的第一個錯誤,是在單一工作中允許測試 300 組參數組合,卻沒有把搜尋預算記錄為研究結果。代理回報了表現最佳的設定:9 小時快速均線、73 小時慢速均線,以及 0.8% 波動率目標。驗證期 Sharpe 值為 4.1。我們知道代理試過很多設定,卻還沒把這件事記錄到不可能被忽略。
週二:重新執行後,冠軍設定變了
我們在乾淨的環境中重新執行相同工作。表現最佳的設定變了,Sharpe 值也降到 2.7。第一次執行時,市場資料快取提供了更新過的資金費率序列;重新執行時則使用了固定版本的快照。兩次工作都聲稱使用相同日期範圍,只有其中一次使用了可重現的資料版本。
我們不再比較分數,改為記錄完整實驗資訊:程式碼版本、資料快照、手續費、資金費率、執行設定、參數值,以及代理啟動的每一次試驗。這讓我們看清楚,4.1 並非神祕的市場優勢,而是在同一個驗證年度、搜尋 300 次後,其中一組設定的結果。
週三:開啟保留測試集前,先凍結搜尋
我們使用固定資料快照重新執行實驗,並改用較小且事先訂好的網格:24 組參數組合。代理可以依據 2021–2023 年開發期為它們排序。我們只讓它查看一次 2024 年資料,用於選擇,接著鎖定選定的設定和程式碼。
選出的策略在驗證期 Sharpe 值為 0.8。在封存的 2025 年保留測試集上,計入 taker 手續費和資金費率,並套用整個研究期間一致的 1 根 K 棒執行延遲後,Sharpe 值為 0.3。這個答案很有參考價值,但不足以證明策略在實盤帳戶中會賺錢。
補充這週的一件事:我們花在取得「一次試驗」定義共識上的時間,比寫移動平均線程式還多。我們把參數組合變更算作一次試驗,也把訊號或部位大小規則變更後的執行列入計算。新的資料快照或執行假設則另建一筆執行紀錄,因為它們同樣可能改變排序。
週四:下次我們會省略什麼
我們會省略一開始那個沒有明確範圍的工作。研究代理需要搜尋預算,也需要記錄嘗試過的項目,尤其是它會根據每次結果決定接下來要試什麼。保留測試集也需要避免非正式地偷看:一旦有人看過結果又修改策略,它就成了另一個驗證集。
小規模搜尋可以用簡單明確的實驗紀錄表:
| 記錄項目 | 重要性 |
|---|---|
| 程式碼與資料版本 | 確保重新執行時使用相同的輸入與邏輯 |
| 每一個嘗試過的變體 | 讓我們能結合搜尋過程理解勝出者 |
| 開發期、驗證期與保留測試集的用途 | 避免最終分數在不知不覺中被拿來調參 |
| 手續費、資金費率與執行假設 | 確保報告的結果來自可供檢驗的模擬 |
開啟保留測試集後,帶著新的研究問題回到開發階段,並將舊結果保留為歷史證據。別再針對策略已經看過的期間,不斷修修補補。
代理完成了它的工作:快速搜尋,找到值得深入檢視的設定。我們的工作則是讓搜尋過程清楚可見、保留未曾碰觸的測試集,並將分數視為有其來歷的測量結果。真正有意思的結果不是 4.1 或 0.3,而是看清楚第一個數字究竟是怎麼得來的。
← 所有文章


