精華筆記

· @aihub.tw

AI 量化交易

模擬盤到實盤:最小可行上線

模擬盤到實盤:最小可行上線

回測跑出了漂亮的 Sharpe Ratio、停損也設好了,你現在摩拳擦掌想把錢丟進去——等一下。

回測靠的是歷史 OHLCV 資料,假設「你的掛單一定以某個理想價格成交」;Dry-run 連上真實行情但不真的下單;實盤下單後,還要對抗滑點、部分成交、深夜流動性崩塌,以及你自己的情緒。這三個世界之間的數字落差,是新手最常踩進去的坑,而且踩一次往往就傷很深。

這堂課的任務:在你把真錢丟進去之前,先用夠長的 dry-run 看清楚數字怎麼衰減、再用一份最小化上線清單確認你真的準備好了。

風險警語 本堂課所有內容僅供學習與研究用途,不構成任何投資建議。金融交易涉及本金虧損風險,回測與模擬盤結果不代表未來實盤績效。任何策略都可能在實盤中完全失效。請在充分理解風險、並以絕對可以承受虧光的資金進行任何實盤操作。本課程不鼓勵任何人進行實盤交易。
這堂課適合誰 適合:已完成第 4 課(freqtrade 回測)與第 6 課(風控)的學員;本課程屬工程師應用專區。需要基礎:能修改 freqtrade `config.json`、會基礎 Linux 指令。前置課:第 4 課(回測實戰)、第 6 課(風控:活下來比賺錢重要)。

這堂學什麼

  • 搞清楚回測 / dry-run / 實盤的數字為什麼注定不同,差距從哪裡來
  • 設定 freqtrade dry-run 並實際跑一週,附帶每日觀察清單
  • 實盤最小化配置:小額、API 權限只給交易(禁提幣)、IP 白名單
  • 設定 Telegram 即時監控並測試每種警報類型
  • 制定「停機條件」並在情緒高漲時遵守它
  • 心理紀律:三個可預期的陷阱與對應方法

觀念一:三個不同的世界

很多人第一次看到 dry-run 和回測的差距時,第一反應是「策略是不是爛了」。未必——差距有一大半來自市場微結構的現實。

回測 / Dry-run / 實盤三層差距對照

回測的假設

freqtrade 回測預設以下一根蠟燭的開盤價成交(open fill mode)。這是相對保守的假設,但它依然假設:

  1. 你的掛單一定能成交、不會因為流動性不足而掛空
  2. 成交量無上限:你的 10,000 USDT 單子不會移動市場價格
  3. 點差固定:trading_fee 永遠是你設定的那個數字
  4. 沒有網路延遲、沒有 API 超時

這些假設在大型主流幣種、流動性好的時段大致成立。但一旦你交易山寨幣、在深夜低流動性時段進出,誤差就會放大。

Dry-run 接近現實多少

Dry-run 模式下,freqtrade 真的連上交易所 API、抓即時 tick、用真實 bid/ask 計算——但送出的是假單。這讓你能觀察到:

  • 真實點差(bid/ask spread)在不同時間怎麼變化
  • 策略在深夜低流動性時段的開單頻率是否異常
  • Telegram 警報有沒有在正確的時間送到你手機
  • 整個系統(策略 + 網路 + 交易所 API)在連續運行中的穩定性

實盤多出來的代價

真實下單還要再扣掉:

  • 滑點(Slippage):市價單打進去,實際成交比預期差 0.05%~0.5%,波動大時可以到 1% 以上
  • 部分成交:限價單可能只成交一半,剩下那半截繼續掛著佔用資金
  • 情緒成本:帳面浮虧時,你的手指會想去按「全部平倉」——這個成本在回測裡不存在

這三層差距會把回測的 Sharpe Ratio 一層一層往下壓。這不是壞消息,這是你在 dry-run 階段就該量化的正常現象。

觀念二:上線前的原則清單

在討論技術設定之前,先把這個清單確認一遍——這些是硬性原則,不是建議:

  1. 只用你輸光了也不影響生活的資金:不是說說而已,是字面意思。建議一個月可支配收入的 5% 以內
  2. API 金鑰絕對不能有提幣權限:這是唯一的紅線,後面會教怎麼設
  3. dry-run 至少跑滿兩週再考慮上線:兩週是最短觀察週期,要覆蓋到至少一次明顯的市場波動
  4. 停機條件要在上線前就寫下來:不是上線後再根據感覺決定,是用白紙黑字定義的觸發數字

上線前四大原則清單

手把手實戰

設定 freqtrade dry-run 並驗證啟動

打開你在第 4 課建的 config.json,確認(或新增)以下欄位:

{
  "dry_run": true,
  "dry_run_wallet": 500,
  "stake_currency": "USDT",
  "stake_amount": 50,
  "max_open_trades": 5,
  "exchange": {
    "name": "binance",
    "key": "",
    "secret": ""
  },
  "stoploss": -0.05,
  "trailing_stop": false
}

幾個要點:

  • "dry_run": true:模擬模式,不真的下單。這個欄位往後不要輕易改
  • "dry_run_wallet": 500:設成你若要實盤計畫用的金額,讓模擬條件貼近現實
  • stake_amount 設 50,每筆不超過模擬資金的 10%,符合第 6 課的倉位管理原則
  • 在 dry-run 模式下,API keysecret 留空就可以跑(freqtrade 用公開端點抓行情)

啟動:

freqtrade trade \
  --config config.json \
  --strategy YourStrategy \
  --logfile logs/dry-run.log

啟動後立刻確認日誌裡有這一行——有這行才代表你真的在模擬模式:

2026-07-04 10:00:00 - freqtrade - INFO - Dry run is enabled. Using DRY_RUN_WALLET: 500

如果你看到的是 Running in LIVE mode,代表 "dry_run" 沒生效,立刻停機檢查設定檔。

跑滿一週:每日觀察清單

Dry-run 跑起來後,不是「放著等結果」。每天花 10 分鐘看這些數字,把觀察記錄在一個文字檔:

每日觀察清單 (dry-run 期間)

【Day 1】
□ freqtrade 有沒有順利連上交易所 API?
□ 第一筆模擬交易有沒有出現在 Telegram 通知?
□ Telegram 訊息格式是否包含:幣對、進場方向、模擬成交價、倉位大小

【Day 2–5 每日重複】
□ 今日最大回撤是多少?在回測預期範圍內嗎?
□ 今日開單頻率 vs 回測平均頻率:差距超過 50% 就要調查原因
□ 有沒有在深夜低流動性時段開了異常大的單?
□ freqtrade 程序有沒有崩潰過?看日誌的 ERROR / WARNING 行數

【Day 6–7 週末總結】
□ 跑 show-trades 撈出完整交易紀錄:
□ 計算:模擬成交點差 vs config 設定的 trading_fee——差多少?
□ 計算:實際開單數量是否符合 max_open_trades 限制?
□ 計算:模擬 win rate 和回測 win rate 的差距
□ 主觀評估:如果是真錢,你有沒有在某個時間點想手動平倉?

查看完整交易紀錄:

freqtrade show-trades \
  --config config.json \
  --db-url sqlite:///tradesv3.dryrun.sqlite \
  --print-json | python3 -m json.tool | head -100

一個殘酷的現實:七天的 dry-run 樣本太小,你看到的正報酬可能只是運氣。量化交易最小統計樣本通常要 100 筆以上交易。兩週才是最短的正式觀察週期。

如果決定實盤:最小化 API 權限

這是整堂課最重要的一步。到交易所建立一組專屬的 API 金鑰,不要複用你平常登入用的主帳號 API。

以 Binance 為例,API 管理頁面(登入後 → 帳戶 → API 管理):

API 權限設定(建議值):

✓  讀取資訊        開啟  ← 讓 bot 查帳戶餘額、行情
✓  現貨與槓桿交易   開啟  ← 讓 bot 下單
✗  合約交易        視策略,新手建議關閉
✗  提幣            絕對關閉  ← 紅線,任何情況下都不開
✗  萬用金鑰        絕對關閉
   IP 白名單       填入你的伺服器/VPS IP ← 強烈建議

API 金鑰最小化權限設定

為什麼提幣權限這麼危險?API 金鑰本質上是一串可以複製的字串。如果你的伺服器被入侵、.env 外洩、或 git 歷史裡有殘留,攻擊者拿到有提幣權限的金鑰可以直接把幣轉走——交易所通常不賠。沒有提幣權限,攻擊者頂多能亂下單,但不能把本金帶走。

把取得的金鑰填進設定——金鑰絕對不進 git,用環境變數管理:

# 在 .env 檔案裡:
FREQTRADE__EXCHANGE__KEY=你的API金鑰
FREQTRADE__EXCHANGE__SECRET=你的API密鑰
// config.json 把 key/secret 留空:
{
  "dry_run": false,
  "exchange": {
    "name": "binance",
    "key": "",
    "secret": "",
    "ccxt_config": {
      "defaultType": "spot"
    }
  }
}

啟動時 freqtrade 會自動從環境變數讀取——詳細設定參考 freqtrade 官方文件的「Security」章節。

設定 Telegram 即時監控

freqtrade 內建 Telegram 整合,是目前最省事的監控方案。

取得 Bot Token 和 Chat ID:

  1. 到 Telegram 搜尋 @BotFather,傳 /newbot,照指示取一個 bot 名稱,拿到 Token(格式像 1234567890:ABCdefGHIjkl...)
  2. 先傳一則訊息給你剛建的 bot(任何內容都可以)
  3. 瀏覽器打開 https://api.telegram.org/bot你的Token/getUpdates,在回應的 JSON 裡找 "chat":{"id":XXXXXXXX},那個數字就是你的 Chat ID

把設定填進 config.json:

{
  "telegram": {
    "enabled": true,
    "token": "1234567890:ABCdefGHIjkl...",
    "chat_id": "12345678",
    "notification_settings": {
      "status": "on",
      "warning": "on",
      "startup": "on",
      "buy": "on",
      "sell": {
        "*": "on"
      },
      "buy_cancel": "on",
      "sell_cancel": "on",
      "protection_trigger": "on",
      "protection_trigger_global": "on"
    }
  }
}

重啟 freqtrade 後,手機應該會收到 Status: running 的訊息。測試一下常用的控制指令:

/status          查看當前持倉與浮動損益
/profit          顯示累計損益統計
/balance         查看帳戶各幣種餘額
/count           目前持倉數 / 最大持倉數
/logs 20         查看最近 20 行日誌(排查問題時很好用)
/forcesell all   緊急全部平倉——記住這個,關鍵時刻用

Telegram 監控指令流程圖

/forcesell all 是你的緊急煞車,務必先在 dry-run 測試過一次,確認它真的會觸發模擬平倉通知。

制定停機條件,並且提前寫下來

這是心理紀律的核心。停機條件要在上線之前定義,不是等到帳戶虧損時再根據情緒決定。

把下面這張表填好,截圖存到手機:

我的停機觸發條件 (上線前填寫)

帳戶總虧損超過 ____%,立刻停機,等七天再評估   (建議: 20%)
單日最大虧損超過 ____%,當日停機,次日重新評估  (建議: 5%)
策略連續虧損 ____ 筆,暫停並手動檢查策略邏輯   (建議: 10 筆)
交易所 API 斷線且未自動重連超過 ____ 分鐘,發警報 (建議: 15 分鐘)
程式崩潰且未重啟超過 ____ 分鐘,手動介入      (建議: 10 分鐘)

freqtrade 的 Protection 機制可以自動執行部分條件,在 config.json 加入:

{
  "protections": [
    {
      "method": "MaxDrawdown",
      "lookback_period_candles": 48,
      "trade_limit": 20,
      "stop_duration_candles": 4,
      "max_allowed_drawdown": 0.10
    },
    {
      "method": "StoplossGuard",
      "lookback_period_candles": 24,
      "trade_limit": 4,
      "stop_duration_candles": 2,
      "only_per_pair": false
    }
  ]
}

MaxDrawdown 的意思:最近 48 根蠟燭內,如果最大回撤超過 10%,自動停止開新單 4 根蠟燭。StoplossGuard 的意思:24 根蠟燭內觸發停損 4 次,暫停開單 2 根蠟燭。這是你的自動守衛,即使你在睡覺也會執行。

兩個重要原則:停機條件觸發後,不要在停機期間修改策略。先停下來觀察市場狀況,分清楚是策略失效還是市場 regime 改變,再決定下一步。

心理紀律:三個可預期的陷阱

實盤開始後,你會遇到幾個幾乎每個人都會踩的陷阱,提前知道它們,才有機會避開:

陷阱一:帳面盈利時想加碼

策略連贏三天,你開始想「把 stake_amount 從 50 改到 200」。這是最常見的翻車場景——短期連勝往往接近均值回歸點。加碼規則要在上線前就寫進設定,不能在情緒亢奮時手動調整。你的策略是一個統計系統,系統需要穩定的輸入條件才能讓統計結論成立。

陷阱二:帳面虧損時想手動平倉

持倉浮虧 3%,你的手在滑 /forcesell all。但這 3% 可能在你回測的正常波動範圍內。手動介入的問題是:你介入一次,就打破了策略的統計假設,之後的績效數字不再有意義——你不知道結果是策略好還是你的介入好。除非觸發了你事先定義的停機條件,否則讓 bot 跑。

陷阱三:把短期結果過度解讀

三週盈利不代表策略有效,三週虧損不代表策略失敗。量化交易的最小統計樣本通常要 100 筆以上的交易。在樣本不足時做決策,是在拋硬幣,只是換了一個看起來「有根據」的包裝。

實盤心理陷阱時間軸

常見坑

坑 1:API 請求超過限制,freqtrade 被交易所限速

症狀:日誌出現:

ccxt.base.errors.RateLimitExceeded: binance {"code":-1003,"msg":"Too many requests; current limit is 1200 requests per minute."}

原因:同一台機器同時跑了多個 freqtrade 實例、或其他腳本也在呼叫同一組 API 金鑰。一旦被限速,所有行情資料都進不來,策略無法正常開單。

解法:一組 API 金鑰只給一個 freqtrade 實例使用;在 exchange 設定裡加上主動降速:

{
  "exchange": {
    "ccxt_config": {
      "rateLimit": 300
    },
    "ccxt_async_config": {
      "rateLimit": 300
    }
  }
}

坑 2:Dry-run 績效亮眼、跑三天就上線,第一週立刻觸發停損

症狀:Dry-run 三天報酬遠超回測預期,興奮把 "dry_run": false 改掉上線,隨後碰上一次市場波動,第一週就把停損打掉。

原因:三天太短,剛好撞上有利的市場條件,不代表策略穩定。三天的樣本在統計上沒有意義。

解法:dry-run 至少跑兩週,必須覆蓋到至少一次明顯的價格回調。上線前看 dry-run 的最大回撤是否和回測預測的接近——如果 dry-run 的最大回撤比回測小很多,很可能只是還沒遇到考驗。

坑 3:Telegram bot 完全收不到通知,持倉在外面跑好幾個小時不知道

症狀:freqtrade 日誌顯示正常運行,但手機完全沒有任何訊息。

逐步排查:

# 1. 確認 token 有效,應該回傳你 bot 的資訊
curl "https://api.telegram.org/bot你的TOKEN/getMe"

# 2. 確認你有傳過訊息給 bot,然後查 chat_id
curl "https://api.telegram.org/bot你的TOKEN/getUpdates"
# 在回傳 JSON 裡找 "chat":{"id":XXXXXXXX}

# 3. 看 freqtrade 日誌有沒有 Telegram 相關錯誤
grep -i telegram logs/dry-run.log | tail -30

最常見原因有兩個:chat_id 填錯(要填純數字 ID,不是 @bot名稱),或 bot 從來沒被你主動傳過訊息(Telegram 規定 bot 無法主動聯絡沒有對話過的用戶)。解法:先手動傳一則訊息給你的 bot,再重啟 freqtrade。

坑 4:以為改了 config.json,實際上 freqtrade 在用另一個設定檔

症狀:明明把 "dry_run": true 改成 false 並存檔,但帳戶餘額完全沒變動,成交紀錄也不出現在交易所。

原因:freqtrade 支援多個設定檔、也可以從指令列覆蓋參數。如果你的啟動指令用了 --config config_dry.json,改 config.json 完全沒用。

驗證方法:每次切換模式後,檢查啟動日誌的第一行:

# 實盤:
INFO - Running in LIVE mode

# 模擬:
INFO - Dry run is enabled. Using DRY_RUN_WALLET: 500

看到 LIVE mode 才代表真的在實盤。養成習慣:每次啟動後等日誌出現這行才離開終端機。

作業

  1. 把你第 4 課的策略設定成 dry-run(dry_run_wallet 設成你若要實盤計畫的金額),啟動並確認 Telegram 能收到啟動通知
  2. 照本課的每日觀察清單跑滿七天,每天記錄一行摘要
  3. 七天後寫一份 200 字的「dry-run vs 回測差異分析」:開單頻率差了多少?點差差了多少?有沒有你意料之外的行為?
  4. 在紙上填好「停機觸發條件」那張表,截圖存手機——這張紙的重要性不低於任何策略程式碼
  5. 選做:如果七天後你覺得數字和心理狀態都準備好了,按照本課的 API 最小化流程到交易所申請一組只有交易權限(禁提幣)的金鑰。不用急著上線,先把金鑰設好放著
再次提醒 把真錢放進去之前,你需要的不只是技術準備——你需要對「這筆錢可能會全部消失」感到真正的平靜,而不是「我覺得策略夠好所以不會輸」。這是兩種完全不同的心理狀態。如果分不清楚,繼續跑 dry-run。

下一課預告

走過了真相潑冷水(第 1 課)、資料取得(第 2 課)、策略基礎(第 3 課)、freqtrade 回測(第 4 課)、AI 的正確位置(第 5 課)、風控(第 6 課)、到今天的模擬盤上線(第 7 課)——第 8 課是整個課程的終局

我們不學新技術,而是把前七課的所有工具組合成一套完整的工作流:從一個交易想法開始,選幣對、取資料、設計策略指標、用 AI 評估訊號品質、跑回測、分析 dry-run 結果、記錄觀察日誌,最後覆盤這整個過程哪裡做對、哪裡值得改進。這是付費課程最後也最值錢的一堂——把前七課的筆記都翻出來,第 8 課你會用到每一堂的東西。

#AI 量化交易#freqtrade#paper trading#dry-run#實盤#API 安全

← 回所有文章