2026年九月13日 · 執行

回測應加入多少延遲?我們量測了每一毫秒

回測應加入多少延遲?我們量測了每一毫秒

這 4 個數字全都來自我們自己的模擬交易系統,涵蓋 1 個策略、1 分鐘 BTCUSDT 永續合約訊號、31 天和 1,418 筆訂單。從 K 線收盤到交易所確認訂單的中位時間:195 ms。第 99 百分位:2,970 ms。已實現波動率最高的 1% 分鐘,中位數:840 ms。而前 1 年多回測設定檔裡的延遲常數是:0.

195 msK 線收盤 → 訂單確認的中位時間
2,970 ms同一路徑的 p99
840 ms波動率最高的 1% 分鐘中位數

其中 3 個數字都不稀奇。大家都知道 0 不對,遲早會換成某個數字,而那個數字幾乎總是憑感覺挑的。100 ms、250 ms,或是「保守一點,設 500」。真正重要的是 840,因為它代表延遲會隨市場狀態改變;而延遲飆高的市場狀態,正是你的訊號認為自己發現機會的時候。

195 毫秒花在哪裡

以下是完整的延遲預算。我們在每個節點都寫入單調時鐘時間戳,逐階段量測。主機是位於 AWS ap-northeast-1 區域的執行個體,與交易平台端點同區;對一般零售型、未託管於交易所機房的架構來說,這已經相當理想。

階段 p50 p95 p99
K 線收盤 → 收到 WS kline-closed 事件 128 ms 402 ms 1,940 ms
解析 + 特徵狀態更新 3 ms 9 ms 28 ms
決策:模型評估 + 風險檢查 11 ms 22 ms 60 ms
送出訂單 → 交易所確認 47 ms 180 ms 1,100 ms
端到端(實測值,非加總) 195 ms 690 ms 2,970 ms

進入重點前,先留意 2 件事。第一,中位數不能直接相加:128 + 3 + 11 + 47 = 189,而實測的端到端中位數是 195。百分位數不能相加;如果你把各階段的 p99 加起來估算延遲,會得到 3,128 ms,實際 p99 卻是 2,970。這次差距不大,但若各階段的相關性方向相反,結果可能差得非常離譜。請量測完整路徑。

第二,看看最上面那一列。中位延遲預算有 3 分之 2 花在等交易所通知你 K 線已收盤。這不是網路延遲,不是你的程式,也不是訂單路由。交易平台把成交彙整成 kline,判定這分鐘結束後再推送。推送前面有佇列,而這個佇列由同一串流上的所有訂閱者共用。

840 的由來

按照產生訊號那分鐘的已實現波動率,將 1,418 筆訂單逐筆分組,延遲分布就會大不相同。

訊號 K 線波動率分組 訂單數 端到端 p50 端到端 p99
最低四分位 201 141 ms 488 ms
中間 2 個四分位 796 183 ms 1,210 ms
最高四分位 407 312 ms 2,880 ms
所有分鐘中最高的 1% 14 840 ms 4,100 ms

每個階段都會一起變慢,因此延遲會層層累積。交易平台的彙整與廣播佇列會受到撮合引擎負載影響,所以有 11,000 筆成交的分鐘,推送時間會比只有 600 筆成交的分鐘晚。相同時段內,你的程序也得處理更多深度更新和成交資料,因此平常只需 3 ms 的特徵更新會變成 28 ms。REST 訂單路徑還得跟所有人的恐慌下單搶資源,你也會開始遇到偶發的 503 和重試,光這就會多花整整 1 秒。在我們的樣本中,訊號 K 線成交筆數與端到端延遲的相關係數是 0.41。算不上很高,但足以讓固定延遲假設失準。

而通過第一輪篩選的策略,絕大多數都是交易突破、反轉、錯價和清算連鎖效應的策略。它們恰好在延遲最糟的分組裡觸發。只有當該分鐘波動 40 bps 才觸發的動能訊號,從結構上就注定要由系統最慢的狀態來處理。

有一次,我們花了整整 1 天追查一個每晚大約同一時間出現的 3.6 秒離群值。原因是 logrotate 在同一個 EBS 磁碟區上,對著程序正在寫入的 2 GB 檔案執行複製後截斷,導致事件迴圈停頓。市場是無辜的。先量測,再怪微觀結構。

這對成交有什麼影響

等待期間,價格會漂移。隨機挑選一分鐘,以我們 195 ms 的中位延遲來看,平均不利變動約為逆著訊號方向 1.1 bps。最高四分位分鐘的延遲為 312 ms,不利變動為 5.8 bps。最高 1% 分鐘的延遲為 840 ms,訂單甚至還沒送到委託簿,就已經出現約 14 bps 的不利漂移。

在 BTC 永續合約上,價差幾乎不構成影響:84,000 報價上的 1 個 tick 只有 0.012 bps,因此損失來自不利漂移,而非跨價成交成本。把同一策略移到中市值永續合約,另一項成本就會浮現——我們樣本中的最優買賣價差,從平靜分鐘的 1.4 bps 擴大到最高四分位的 6.2 bps,而該檔位的深度也減少了一半以上。你會同時承受價格漂移、更寬的價差和更差的深度,因為這些現象都源自同一個原因。

我們用每根 K 線的條件式延遲,而非固定 200 ms,重播同樣的 31 天後,回測的平均進場價格變差了 3.1 bps,而且幾乎都集中在 9% 的交易中。回測與模擬交易的進場價格差距,從 4.2 bps 降到 0.9 bps。該策略的樣本內 Sharpe 從 1.7 降到 1.1;這才是誠實的數字,而且它一直都是如此。

那設定檔裡究竟該填什麼

不要填單一數值。我們現在這樣做:

  1. 取樣,不要定值。根據該 K 線本身的活躍程度,從實證分布中抽取每筆模擬訂單的延遲;成交筆數和絕對報酬就足夠了,而且兩者都已包含在標準 kline 中。按交易平台和訂單類型各自擬合,每月重新擬合一次。
  2. 保留尾端。不要擬合對數常態分布就以為大功告成;p99 來自重試風暴和 GC 暫停,平滑分布無法重現。我們使用實證分位數,並對 p95 以上的尾端進行重抽樣。
  3. 撤單也要套用延遲。停損單替換或避險撤單同樣會遇到延遲;在快速變動的市場中,你的撤單還得跟成交賽跑。如果模擬器能立即撤單,你的風險模型就是假的。
  4. 加入資料過時保護,並模擬它。如果訊號抵達時,其 K 線已經超過 1.5 秒,我們就會捨棄。這是會產生成本的真實行為——它會悄悄移除交易,回測也必須移除相同的交易。
  5. 用模擬交易重新校準。模擬交易能提供真實基準。記錄每筆訂單在 4 個節點的時間戳,每週比較實際分布與模擬器的假設。

其他資產類別也有同樣問題。美股:整合行情帶會在券商延遲之外再增加彙整延遲,訊息速率承受壓力時也會因同樣的結構性原因而變慢。預測市場:多數平台只提供 REST 下單;我們量測到平時中位延遲不到 100 ms,但遇到結算事件、所有人同時湧入時,延遲會升到數秒。加密貨幣選擇權:標的價格恰好變動的那分鐘,你用來定價的報價可能已經過時 2 秒。

這類錯誤的根本形式,是把執行參數當成獨立常數,儘管它其實取決於驅動訊號的同一個狀態變數。手續費穩定,資金費率也穩定,延遲則不然。如果你只打算記住這裡的一個數字,就記住這個比率:我們的 p99 是中位數的 15 倍,而且訊號抵達時間不成比例地集中在接近 p99 的區間。

把 4 個節點都加上監測吧。只要 1 個下午就能完成,而且它帶給你的策略資訊,會比再花 1 週搜尋參數更多。

延遲回測模擬交易執行加密貨幣期貨
← 所有文章