建構 · 2026年6月1日

程式交易自動化——把策略從回測搬到上線

回測賺錢、實盤翻車的真正原因,不是策略不夠好,是回測的乾淨假設在實盤全部失效。這篇拆解滑價、資料管道、部位同步、斷線重連、風控熔斷五大工程關卡,以及 AI 在這條鏈能幫什麼、哪些絕對不能外包。

程式交易自動化——把策略從回測搬到上線

真正的關卡不是你的策略夠不夠好,是回測裡的乾淨假設在實盤全部失效——滑價吃掉 edge、網路延遲亂序信號、斷線後部位對不上、資料髒了卻不知道。 這篇拆解從回測到實盤必須補的那段工程,以及 AI 在這條鏈能幫你什麼、哪些絕對不能外包。


為什麼回測賺錢一上線就變樣?

回測的本質是「有了答案再倒回去問問題」——你用歷史資料驗證策略,但那份歷史資料是清洗過的、連續的、可以暫停倒轉的,和真實市場完全不同。幾個最常被忽略的假設:

完美成交假設。 回測引擎通常把每一筆信號當成「市價立刻完整成交、滑價為零」。現實是你可能只成交一半,剩下一半在下一個 tick 才填,期間價格已經移動。對薄利策略來說,滑價幾個 tick 就足以讓正期望值變負。

資料清洗偏差。 你的歷史 K 線來自資料供應商,已經補齊了除權除息、去掉了錯誤 tick,甚至可能濾掉了流動性異常的日子。實盤 feed 是原始髒訊號——重複 tick、亂序封包、開盤前的假報價,通通都會進來。你的策略有沒有處理這些,回測完全測不到。

倖存者偏誤與前視偏誤。 策略回測如果用「現在這個時點的成分股清單」跑歷史,你已經排除了那些在歷史期間下市或退市的標的,等於只選了贏家。前視偏誤更隱晦:某些技術指標的計算邏輯默默偷看了未來資料,在你察覺之前,回測績效早就被膨脹了。


對照表:回測環境 vs 實盤環境

維度回測環境實盤環境
成交假設信號觸發即市價完整成交,滑價可設為 0掛單不一定成交;部分成交;市價單被 queue 延後
資料品質供應商清洗完的歷史資料,連續無缺口原始行情 feed:重複 tick、亂序封包、開盤前假報價
時間特性可暫停、倒轉、加速;信號計算沒有時間壓力即時不可逆;晚一秒的 order 可能遇到完全不同的市況
連線狀態永不斷線;資料讀取同步完成Broker API 斷線、WebSocket 重連、rate limit 踢出
部位狀態程式自己記錄,和「真相」永遠一致斷線後本地帳本和 broker 帳本可能不一致,需主動對帳
出錯成本發現問題改程式再跑一次,沒有金錢損失Bug 造成重複下單、方向錯、未平倉,損失是真實的

從回測到實盤,差了哪些工程?

這段差距沒有捷徑,只有逐層補起來。

資料管道:從靜態到動態

回測讀的是 CSV 或 DB 裡的靜態資料;實盤要訂閱 WebSocket 行情、處理 heartbeat 失效、判斷資料是否過期、在斷線重連後補回缺口行情。資料管道不穩,後面所有邏輯都是在流沙上蓋房。最小 viable 起點:把 live feed 複製存本地一週,先確認你拿到的格式和你預期的一樣——這一步通常會發現三到五個你從沒想過的髒資料場景。

下單介接:API 不是 Excel 公式

每家 broker 的 API 行為都不一樣:有的送 order 後要輪詢狀態,有的用非同步 callback 或 webhook,有的限制每秒 request 數。你需要工程上處理的事至少包括:

  • 下單後非同步等待成交回報(成交可能幾毫秒、也可能幾分鐘)
  • 部分成交(只成交 60%,剩下 40% 要繼續等、取消、還是改單?)
  • 拒單(帳戶資金不足、超過部位限額、委託格式錯誤)
  • 成交 ID 對帳:你這邊記的「下了一筆單」和 broker 那邊記的是同一筆嗎?

部位狀態管理:本地帳本 vs broker 真相

程式自己維護一個部位帳本很方便,但它只是你的主觀認知,真相在 broker 端。重啟後或斷線後,本地帳本可能和 broker 不一致——策略以為空手,實際還有倉位,或者你以為的開多單其實沒成交。

正確做法:每次啟動先查詢 broker 現有部位,以 broker 為準重建本地狀態,再開始跑信號。這個步驟跳掉,第一個信號就可能重複開倉或反向操作。

斷線重連:連線就是基礎建設

市場最不穩定的時段——開盤、重大事件、漲跌停熔斷——往往也是 API 最容易斷的時段。你的系統需要:

  1. 偵測斷線(heartbeat timeout,而不是等到 error 才知道)
  2. 指數退避重連(避免在 broker 壓力最大的時候一秒打十次)
  3. 重連後同步缺口行情(斷線那段時間的 tick 怎麼補?)
  4. 判斷斷線期間有沒有信號應發出但沒發

風控熔斷層:最後一道防線

這是無論如何不能省的部分。最小風控清單:

  • 最大單筆虧損上限:超過即自動停止下單、等人工確認
  • 每日最大虧損熔斷:觸發後需人工解鎖才能繼續
  • 部位方向和大小上限:防止邏輯 bug 瘋狂累積倉位
  • 異常下單偵測:同方向在 N 秒內下超過 M 筆,自動暫停並告警

AI 在這條鏈能幫與不能幫?

在協助自動化交易系統的案子裡,AI 工具能省非常多重複工作,但也踩過幾個明顯的邊界。

AI 幫得上的

策略骨架。 給 AI 策略邏輯的自然語言描述,它能快速產出可以跑的 Python 骨架或回測框架接口,省去查文件的時間。初版通常需要調整,但起點比從零寫快很多。

Broker API 串接。 查 API endpoint、整理 webhook payload 格式、處理分頁和 rate limit——這些 AI 非常擅長,且每次都正確。這塊原本可能需要花一兩天翻文件,現在幾小時就完成。

測試案例生成。 告訴 AI 你的部位狀態機有哪些狀態,它能幫你系統列出完整測試矩陣(斷線 × 未成交 × 部分成交 × 滿倉 × 風控觸發),你直接轉成 unit test,覆蓋度比手工想的全很多。

邏輯 debug。 把錯誤 log 和相關程式碼貼給 AI,找 off-by-one、條件判斷遺漏,效率比自己盯高很多——尤其在凌晨兩點排查隔天開盤前的 bug。

AI 幫不上的(不能外包給 AI)

成交對帳驗證。 AI 只能看程式碼,看不到你帳戶裡實際發生的事。成交 ID 對帳、本地帳本 vs broker 帳本差異,必須人工確認。

風控參數設定。「停損設多少」「熔斷閾值多少」取決於你的資金規模、策略特性和風險承受度,不應該讓 AI 替你決定。

真正意外的 bug。 你第一次真實下單,才會遇到那些 mock 測試覆蓋不到的邊界行為——API 在特定委託量下的奇異回應、行情極端條件下的資料格式異常。這些場景 AI 沒看過,而且真實損失不等人調試。

最終下單確認。 至少在上線初期,每筆信號觸發後要有人工確認機制,不要讓系統在無人監控下全自動交易。


上線後最容易爆哪幾個地方?

第一筆真實成交就炸

在協助一位自動化操盤客戶上線的案子裡,這件事我踩得比「忘了等回報」更深一層。當時系統的單元測試有一百七十幾個、全綠,mock 環境連跑數月零問題。真正接上券商、第一次吃到一筆加碼成交的瞬間,系統卻整個卡死,三十秒後自動進入降級停機。

根因是一個 mock 永遠測不到的再進入死結(re-entrancy deadlock):券商的成交回報走 WebSocket 非同步推送,我在「收到成交」的回呼裡,又同步發出一個同樣走 WebSocket 的查詢去確認部位——但負責「收訊息」的那條 loop,正卡在這個回呼裡等我做完,於是我等的那個回應永遠不會被收到。自己等自己,鎖死。

這個 bug 的可怕之處在於:它不是邏輯錯,是並發結構錯。 一百七十幾個 mock 測試之所以全部測不到,正因為它們繞過了真實的「單一讀取迴圈」——mock 直接把回應塞回來,根本沒有那條會被自己阻塞的 loop。我是真的接上券商、真的成交一筆,才把它逼出來。修法是把成交回報改走獨立的 consumer queue、和讀取迴圈徹底解耦(讀只有一條 task、寫可以多條)。教訓很簡單:涉及並發、回呼、外部 I/O 的交易系統,「測試全綠」不等於「上線安全」——你必須讓它在真實環境真的成交一次,那條 mock 照不到的路徑才會現形。

開盤亂流

台股、美股的開盤前後,行情 feed 可能在幾秒內湧入大量 tick,且其中部分是集合競價報價(不代表真實成交價)。策略如果沒有過濾這段,可能在開盤第一秒就發出不應發的信號。這類問題在盤中回測完全不會出現。

斷線後部位錯位

連線中斷兩分鐘,可能錯過一個止損信號,也可能 broker 端已成交你的委託但本地帳本沒收到。重連後沒有對帳直接繼續跑,後面所有部位計算都是錯的——而且通常要等到倉位異常才發現,那時候損失已經在了。


第一步該做什麼?

如果你現在有一個回測表現不錯的策略,想開始往實盤推進,最務實的順序:

1. 接真實 feed,先只看不下單。 把策略邏輯接上 live 資料,只記錄「如果下單的話會下什麼」,不真的送 order。跑至少兩週,確認信號邏輯在 live 資料上行為正常,沒有被髒資料或開盤亂流觸發異常。

2. 建對帳機制,先於策略邏輯。 部位帳本、成交 log、每日對帳腳本,這些基礎建設要比策略更早完成。沒有對帳機制,你根本不知道系統運作對不對。

3. 用最小倉位真實下單。 第一次真實下單用你能接受完全損失的金額,目的是跑通整條鏈(下單 → 成交回報 → 帳本更新 → 風控偵測),不是獲利。

4. 設硬性人工確認點。 上線前三個月,每日結束前手動對帳一次,任何異常當天解決,不帶著問題進下一個交易日。

如果你在這個過程裡需要系統架構評估或工程方向建議,路澄 LUCE 有提供程式交易自動化諮詢,可以從你的具體策略和目標出發討論。


常見問題

需要很強的程式力才能做程式交易自動化嗎?

基礎 Python 足夠入門,但「能跑」和「可靠上線」之間有很長一段路。回測框架(Backtrader、vectorbt 等)入門門檻不高;真正困難的是連線穩定性、成交對帳、異常處理。如果你的策略邏輯清楚,AI 工具能幫你省掉很多樣板程式碼,但工程判斷還是需要人做——尤其是「這個 bug 會不會造成真實損失」這種判斷。

回測績效能當作實盤的預期嗎?

不能,而且差距通常比你想的大。有一份分析了 888 個交易策略、各自都有至少半年真實實盤資料的研究發現:策略的回測 Sharpe ratio 對於預測它的實盤表現,幾乎沒有預測力(R² < 0.025);而且一個策略被回測、最佳化得越多,它的回測與實盤落差反而越大(Wiecki et al., 2016,The Journal of Investing)。差距主要來自三個原因:過度擬合(策略參數是對過去資料最佳化的結果,對未來不適用);前視偏誤(部分指標計算偷看了未來資料,回測看起來好但實盤做不到);倖存者偏誤(回測樣本排除了已下市標的,系統性高估績效)。回測是驗證邏輯合理性的工具,而不是報酬預測——能通過回測的策略很多,能在實盤穩定跑的策略很少。

最常見「上線才爆」的坑是什麼?

依我看到的頻率:第一是部位狀態失同步(斷線後沒有主動對帳,以為空手實際有倉);第二是成交假設太樂觀(尤其在流動性差的時段,延遲和部分成交會打亂策略邏輯);第三是資料髒了沒偵測(live feed 出現異常 tick,策略以為是真實信號而觸發)。這三個問題在 mock 環境幾乎測不出來,一定要接真實 feed 或真實下單才會遇到。

用 AI 寫交易程式,哪些能交給它、哪些要自己把關?

可以交給 AI 的:API 串接骨架、資料處理邏輯、測試案例矩陣、debug 特定 log、查官方 API 文件細節。要自己把關的:風控參數(損失上限、熔斷閾值)、成交對帳結果確認、上線前的整合測試、每日人工盤後核查。AI 能大幅降低程式撰寫成本,但對「這筆單有沒有照預期成交」的最終確認,還是需要人在場。從 demo 順到實盤需要跨越的那段工程落差,可以延伸參考為什麼 AI PoC 過了、上線就翻車——程式交易和 AI 系統上線面對的是同一類問題。


本文為工程方法論分享,不構成任何投資建議,不對任何特定策略的報酬或虧損負責。程式交易涉及實質資金風險,請在充分了解風險後自行判斷。

把這種文章直接寄到你信箱

不定期一封,談真正能 ship 的 AI 工作流。沒有 hype。