模擬盤到實盤:最小可行上線
回測跑出了漂亮的 Sharpe Ratio、停損也設好了,你現在摩拳擦掌想把錢丟進去——等一下。
回測靠的是歷史 OHLCV 資料,假設「你的掛單一定以某個理想價格成交」;Dry-run 連上真實行情但不真的下單;實盤下單後,還要對抗滑點、部分成交、深夜流動性崩塌,以及你自己的情緒。這三個世界之間的數字落差,是新手最常踩進去的坑,而且踩一次往往就傷很深。
這堂課的任務:在你把真錢丟進去之前,先用夠長的 dry-run 看清楚數字怎麼衰減、再用一份最小化上線清單確認你真的準備好了。
這堂學什麼
- 搞清楚回測 / dry-run / 實盤的數字為什麼注定不同,差距從哪裡來
- 設定 freqtrade dry-run 並實際跑一週,附帶每日觀察清單
- 實盤最小化配置:小額、API 權限只給交易(禁提幣)、IP 白名單
- 設定 Telegram 即時監控並測試每種警報類型
- 制定「停機條件」並在情緒高漲時遵守它
- 心理紀律:三個可預期的陷阱與對應方法
觀念一:三個不同的世界
很多人第一次看到 dry-run 和回測的差距時,第一反應是「策略是不是爛了」。未必——差距有一大半來自市場微結構的現實。

回測的假設
freqtrade 回測預設以下一根蠟燭的開盤價成交(open fill mode)。這是相對保守的假設,但它依然假設:
- 你的掛單一定能成交、不會因為流動性不足而掛空
- 成交量無上限:你的 10,000 USDT 單子不會移動市場價格
- 點差固定:
trading_fee永遠是你設定的那個數字 - 沒有網路延遲、沒有 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 階段就該量化的正常現象。
觀念二:上線前的原則清單
在討論技術設定之前,先把這個清單確認一遍——這些是硬性原則,不是建議:
- 只用你輸光了也不影響生活的資金:不是說說而已,是字面意思。建議一個月可支配收入的 5% 以內
- API 金鑰絕對不能有提幣權限:這是唯一的紅線,後面會教怎麼設
- dry-run 至少跑滿兩週再考慮上線:兩週是最短觀察週期,要覆蓋到至少一次明顯的市場波動
- 停機條件要在上線前就寫下來:不是上線後再根據感覺決定,是用白紙黑字定義的觸發數字

手把手實戰
設定 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
key和secret留空就可以跑(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 金鑰本質上是一串可以複製的字串。如果你的伺服器被入侵、.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:
- 到 Telegram 搜尋
@BotFather,傳/newbot,照指示取一個 bot 名稱,拿到 Token(格式像1234567890:ABCdefGHIjkl...) - 先傳一則訊息給你剛建的 bot(任何內容都可以)
- 瀏覽器打開
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 緊急全部平倉——記住這個,關鍵時刻用

/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 才代表真的在實盤。養成習慣:每次啟動後等日誌出現這行才離開終端機。
作業
- 把你第 4 課的策略設定成 dry-run(dry_run_wallet 設成你若要實盤計畫的金額),啟動並確認 Telegram 能收到啟動通知
- 照本課的每日觀察清單跑滿七天,每天記錄一行摘要
- 七天後寫一份 200 字的「dry-run vs 回測差異分析」:開單頻率差了多少?點差差了多少?有沒有你意料之外的行為?
- 在紙上填好「停機觸發條件」那張表,截圖存手機——這張紙的重要性不低於任何策略程式碼
- 選做:如果七天後你覺得數字和心理狀態都準備好了,按照本課的 API 最小化流程到交易所申請一組只有交易權限(禁提幣)的金鑰。不用急著上線,先把金鑰設好放著
下一課預告
走過了真相潑冷水(第 1 課)、資料取得(第 2 課)、策略基礎(第 3 課)、freqtrade 回測(第 4 課)、AI 的正確位置(第 5 課)、風控(第 6 課)、到今天的模擬盤上線(第 7 課)——第 8 課是整個課程的終局。
我們不學新技術,而是把前七課的所有工具組合成一套完整的工作流:從一個交易想法開始,選幣對、取資料、設計策略指標、用 AI 評估訊號品質、跑回測、分析 dry-run 結果、記錄觀察日誌,最後覆盤這整個過程哪裡做對、哪裡值得改進。這是付費課程最後也最值錢的一堂——把前七課的筆記都翻出來,第 8 課你會用到每一堂的東西。