綜合實戰:從想法到模擬盤完整覆盤
你已經走完七堂課了。回測跑過、AI 訊號接過、風控參數設過、dry-run 也啟動過。但很多學員告訴我,學完每一堂課感覺都還行,一旦坐下來從頭做一個「自己的策略」,卻不知道從哪裡開始——或者做到一半發現前後沒有串起來,數據格式不對、訊號沒有接進策略、風控參數跟回測設定衝突。
這就是這堂課要解決的問題:走一遍完整的流程,從一個具體的交易想法出發,一步一步帶到模擬盤穩定運行。這不是一堂新技術課,這是一次「把所有零件組裝起來,確認機器真的能跑」的完整覆盤。
這堂學什麼
- 完整 walkthrough:從想法具體化 → 資料驗證 → 策略開發 → 嚴格回測 → AI 訊號 → 風控 → dry-run 上線
- 全流程檢查清單:啟動模擬盤前的 20 個確認點
- 台灣法規與稅務提醒:加密貨幣所得、海外券商申報義務
- 最常犯的 8 個坑(含 3 個心理坑)及解法
- 持續精進:課程之後的學習資源與社群
整條流程長什麼樣
先建立一個完整的心智模型。這門課的八堂教的是下圖中的各個區塊,而這堂課要把所有箭頭接起來。

這條流程有幾個重要的方向性原則,先在這裡說清楚:
- 想法永遠要先於資料探索。很多人先看資料,找到一個「好像有規律」的現象就開始做策略——這是資料窺探(Data Snooping)的入口。正確做法是先用語言寫下「我認為 X 發生時 Y 會跟著發生,因為 Z」,然後才去資料裡驗證。
- 流程是單向的:回測不好看時,正確做法是回頭審視想法假設,不是一直調參數到好看為止。「不斷調參數直到曲線好看」就是第 3 課說的過擬合(Overfitting)的標準作案手法。
- 模擬盤不是回測的替代品:模擬盤的目的是發現「回測沒辦法測到的問題」,包括 API 連線穩定性、訊號計算延遲、部位開倉失敗等。別跳過。
手把手實戰:完整走一遍
這次的範例策略:「BTC/USDT 1h,用均線趨勢過濾 + 情緒評分確認,搭配移動停損與熔斷保護」。這是一個把前七堂核心全部連到一起的組合,夠完整、又不複雜到跑不完。
Step 1:把想法寫成可測試的假設
先開一個文字檔,用一段話寫清楚你的假設:
假設:當 BTC 處於多頭 Regime(EMA20 在 EMA50 上方)時,若近期加密貨幣新聞情緒偏正面
(LLM 情緒評分 > 0.3),則在每根 1h K 線收盤後進場做多,持倉直到均線死叉或情緒轉負。
假設的市場邏輯:趨勢行情中,正面消息驅動的買入往往有延續性;逆向情緒則代表短期超賣。
此假設成立的前提:市場 Regime 辨識準確、新聞情緒有足夠的前置訊號性(lead time)。
可以被推翻的條件:如果加入情緒訊號後的 Sharpe Ratio 比不加更低,或正面情緒期間的 Win Rate
低於 50%,假設即被推翻。
這一步很多人跳過,但它是整個系統的靈魂。假設寫不清楚的策略,出了問題沒辦法判斷「是想法錯了還是實作錯了」。
Step 2:下載並驗證資料品質
取得資料,並在進策略之前先做品質檢查:
# 下載 BTC/USDT 兩年資料(確保有足夠的 in-sample + out-of-sample 區間)
freqtrade download-data \
--exchange binance \
--pairs BTC/USDT \
--timeframe 1h \
--days 730
下載完之後,用 Python 做一個快速的品質檢查:
import pandas as pd
import json
from pathlib import Path
def check_data_quality(pair: str = "BTC_USDT", timeframe: str = "1h",
data_dir: str = "user_data/data/binance") -> None:
"""
載入 freqtrade 格式的歷史資料並做品質檢查。
資料格式:JSON 陣列,每筆 [timestamp_ms, open, high, low, close, volume]
"""
filepath = Path(data_dir) / f"{pair}-{timeframe}.feather"
if not filepath.exists():
# 嘗試 JSON 格式
filepath = Path(data_dir) / f"{pair}-{timeframe}.json"
df = pd.read_feather(filepath) if str(filepath).endswith('.feather') else \
pd.DataFrame(
pd.read_json(filepath).values,
columns=["date", "open", "high", "low", "close", "volume"]
)
df["date"] = pd.to_datetime(df["date"], unit="ms", utc=True)
df = df.set_index("date").sort_index()
print(f"資料期間:{df.index[0]} 到 {df.index[-1]}")
print(f"總 K 線數:{len(df)}")
# 檢查 1:缺失時間段
expected_freq = pd.tseries.frequencies.to_offset("1h")
full_range = pd.date_range(df.index[0], df.index[-1], freq=expected_freq, tz="UTC")
missing = full_range.difference(df.index)
print(f"缺失 K 線數:{len(missing)}"
+ (f"(最大連缺:{missing.to_series().diff().max()})" if len(missing) > 0 else " ✓"))
# 檢查 2:異常價格(high < low 或 close <= 0)
bad_rows = df[(df["high"] < df["low"]) | (df["close"] <= 0)]
print(f"異常 K 線:{len(bad_rows)} 筆" + (" ✓" if len(bad_rows) == 0 else " ← 需要處理"))
# 檢查 3:成交量為零(可能是交易所維護期)
zero_vol = df[df["volume"] == 0]
print(f"成交量為 0:{len(zero_vol)} 筆" + (" ✓" if len(zero_vol) == 0 else " ← 注意"))
check_data_quality()
如果缺失 K 線超過 1%,考慮換一個資料來源(例如改用 Bybit 的歷史資料,或用 ccxt 補洞)。少量缺失 freqtrade 在回測時會自動跳過,影響不大。
Step 3:用 AI 輔助寫策略程式碼
這是「策略開發輔助」的正確 LLM 使用方式:你描述邏輯,AI 幫你翻成程式碼,你審查每一行。
把以下 prompt 直接貼給 Claude:
我在用 freqtrade 開發量化策略,請幫我寫一個 Python 策略類別。
條件:
- 繼承 IStrategy
- timeframe = '1h'
- 進場:EMA20 > EMA50(多頭 Regime)且有一個外部整數訊號 sentiment_score > 30
sentiment_score 會從 dataframe 的一個欄位讀取(預設值 0)
- 出場:EMA20 < EMA50(死叉)或 sentiment_score < -30
- 停損:stoploss = -0.05,啟用 trailing_stop
- minimal_roi:{"0": 0.10, "60": 0.05, "240": 0.02}
- can_short = False
- 加上完整的 populate_indicators、populate_entry_trend、populate_exit_trend
請完整輸出策略檔案,包括所有必要的 import,並在每個重要邏輯段落加上繁體中文註解。
Claude 會輸出一個完整的策略檔案。把它存成 user_data/strategies/CapstoneStrategy.py,然後逐行讀一遍。重點確認:
populate_indicators的指標計算只用了shift(1)之前的資料(無前視偏差)- 進出場訊號確實對應你的假設邏輯
sentiment_score欄位有預設值(避免找不到欄位時策略崩潰)
如果有不確定的行,繼續問 Claude:「這行 dataframe['ema_cross'] = qtpylib.crossed_above(...) 的邏輯是什麼,會不會有前視偏差?」
Step 4:嚴格回測——扣費、Walk-Forward 驗證
嚴格回測分兩個步驟:先用 in-sample 資料調整策略參數,再用 out-of-sample 資料驗證。兩段資料不得重疊。
# 以兩年資料為例:前 18 個月 in-sample,後 6 個月 out-of-sample
# 步驟 A:in-sample 回測(調整參數用)
freqtrade backtesting \
--config config.json \
--strategy CapstoneStrategy \
--timerange 20240101-20250630 \
--fees 0.001 \
--breakdown month
# 步驟 B:out-of-sample 驗證(這段資料在調參時絕對不能看)
freqtrade backtesting \
--config config.json \
--strategy CapstoneStrategy \
--timerange 20250701-20251231 \
--fees 0.001 \
--breakdown month
評估標準(只有 out-of-sample 的結果才算數):
評估項目 及格線 你的結果
─────────────────────────────────────────────
Sharpe Ratio > 0.8 ____
Max Drawdown < -15% ____
Win Rate > 48% ____
Profit Factor > 1.2 ____
vs Buy & Hold 不遜於太多 ____
Out/In-sample 報酬差距 < 50% ____
最後一行「out-of-sample 報酬差距 < 50%」是過擬合的關鍵指標。如果 in-sample 年化 30%、out-of-sample 年化 2%,代表嚴重過擬合,不能上。

Step 5:接入 AI 訊號層
第 5 課已經寫過情緒評分的 script。這裡重點是把它「接正確」——確保訊號格式和策略吃進來的格式一致。
首先確認情緒評分 script 輸出到正確位置:
# scripts/generate_sentiment.py — 每 1 小時跑一次(用 cron 或 systemd timer)
import anthropic
import json
import sqlite3
from datetime import datetime, timezone
NEWS_HEADLINES = [
# 實際上這裡要從 CryptoPanic API 或 RSS 抓最近 2 小時的新聞標題
# 示範用硬編碼
"Bitcoin ETF sees record inflows as institutional demand surges",
"Fed holds rates steady, risk assets rally",
]
def score_sentiment(headlines: list[str]) -> int:
"""
呼叫 Claude 評分新聞情緒,回傳 -100 到 100 的整數。
使用 claude-haiku-4-5(速度快、成本低,適合定期批次呼叫)。
"""
client = anthropic.Anthropic()
prompt = f"""以下是加密貨幣市場的近期新聞標題清單。
請評估這批標題對 BTC 短期(1-4 小時)價格的市場情緒影響。
新聞標題:
{chr(10).join(f"- {h}" for h in headlines)}
請只回傳一個整數,範圍 -100(極度負面)到 100(極度正面),0 代表中性。
只回傳數字,不要有任何其他文字。"""
message = client.messages.create(
model="claude-haiku-4-5",
max_tokens=10,
messages=[{"role": "user", "content": prompt}]
)
try:
score = int(message.content[0].text.strip())
return max(-100, min(100, score)) # 確保在範圍內
except ValueError:
return 0 # 解析失敗時回傳中性
def save_score(score: int, db_path: str = "user_data/sentiment.db") -> None:
conn = sqlite3.connect(db_path)
conn.execute("""
CREATE TABLE IF NOT EXISTS sentiment
(timestamp TEXT PRIMARY KEY, score INTEGER)
""")
ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:00")
conn.execute("INSERT OR REPLACE INTO sentiment VALUES (?, ?)", (ts, score))
conn.commit()
conn.close()
print(f"[{ts}] Sentiment score: {score}")
if __name__ == "__main__":
score = score_sentiment(NEWS_HEADLINES)
save_score(score)
然後在策略的 populate_indicators 裡讀取這個分數:
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# ── 技術指標 ──
dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20)
dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
# ── 讀取情緒分數(從 SQLite) ──
import sqlite3
import pandas as _pd
try:
conn = sqlite3.connect("user_data/sentiment.db")
sentiment_df = _pd.read_sql(
"SELECT timestamp, score FROM sentiment ORDER BY timestamp",
conn, parse_dates=["timestamp"]
)
conn.close()
sentiment_df = sentiment_df.set_index("timestamp")
# 對齊到策略 dataframe 的時間軸,用前一個已知分數填補
dataframe = dataframe.join(
sentiment_df.rename(columns={"score": "sentiment_score"}),
how="left"
)
dataframe["sentiment_score"] = dataframe["sentiment_score"].ffill().fillna(0)
except Exception:
dataframe["sentiment_score"] = 0 # 資料庫不存在時用中性值
return dataframe
重要:回測時 sentiment.db 不會有歷史資料,所以回測中情緒欄位會全部是 0——這意味著你的 in-sample/out-of-sample 回測是「無 AI 訊號版本」的基準線。加入情緒訊號的效果要等模擬盤階段才能觀察。這是正確的——你不應該用「事後重建的情緒分數」來美化回測。
Step 6:套入風控,確認參數一致
這一步最常犯的錯:回測的 config.json 和 dry-run 的 config.json 參數不一致,導致模擬盤行為和你預期的不同。
建立一份「生產用」的 config,確保以下參數全部對齊:
{
"dry_run": true,
"dry_run_wallet": 1000,
"stake_currency": "USDT",
"stake_amount": "unlimited",
"tradable_balance_ratio": 0.3,
"max_open_trades": 3,
"amend_last_stake_amount": true,
"stoploss": -0.05,
"trailing_stop": true,
"trailing_stop_positive": 0.02,
"trailing_stop_positive_offset": 0.04,
"trailing_only_offset_is_reached": true,
"protections": [
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 2,
"stop_duration_candles": 24,
"max_allowed_drawdown": 0.10
},
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 3,
"stop_duration_candles": 12,
"only_per_pair": false
}
],
"exchange": {
"name": "binance",
"key": "",
"secret": ""
},
"telegram": {
"enabled": true,
"token": "YOUR_TELEGRAM_BOT_TOKEN",
"chat_id": "YOUR_CHAT_ID"
},
"api_server": {
"enabled": true,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "error",
"enable_openapi": false,
"jwt_secret_key": "YOUR_RANDOM_SECRET",
"username": "your_username",
"password": "your_password"
}
}
注意:key 和 secret 欄位是空字串——dry-run 模式下不需要 API 金鑰。等第 7 課的內容確認完觀察期後,再決定要不要填入只讀金鑰測試 WebSocket 連線。
Step 7:啟動 dry-run,設定觀察框架
啟動前,先做一次「起跑前檢查」(下一節的完整清單):
# 確認策略語法沒問題
freqtrade check-exchange --config config.json --strategy CapstoneStrategy
# 跑一次最近 7 天的快速回測,確認策略在最新的市場環境還能運作
freqtrade backtesting \
--config config.json \
--strategy CapstoneStrategy \
--timerange 20260621-20260704 \
--fees 0.001
# 確認沒問題,啟動 dry-run
freqtrade trade \
--config config.json \
--strategy CapstoneStrategy \
--logfile user_data/logs/capstone.log
模擬盤跑起來之後,建立你的觀察框架。推薦用一個簡單的 Notion 或 Google Sheets,每週紀錄:
週次 | 模擬盤報酬 | 進場次數 | 勝率 | 最大回撤 | 情緒訊號有效次數 | 備註
────────────────────────────────────────────────────────────────────────────
Week 1 | | | | | |
Week 2 | | | | | |
...
觀察期建議至少 4–8 週,涵蓋不同的市場狀態(最好能看到一次明顯的行情回調)。不要在第一週就下結論——無論是「模擬盤賺了就上實盤」,還是「模擬盤虧了就改策略」,都太倉促了。

全流程檢查清單
在正式啟動模擬盤之前,把以下 20 個項目逐一打勾。沒打完不能跑。
【資料層】
□ 1. 資料下載期間足夠(至少 1.5 年,最好 2 年以上)
□ 2. 資料品質檢查通過(缺失 K 線 < 1%,無異常價格)
□ 3. 資料時區確認為 UTC
【策略層】
□ 4. 策略假設已用文字清楚描述(假設 + 推翻條件)
□ 5. 指標計算無前視偏差(全部使用 shift(1) 前的資料)
□ 6. `freqtrade check-exchange` 無錯誤
□ 7. 策略 Python 語法無 warning
【回測層】
□ 8. 回測有扣手續費(--fees 0.001 以上)
□ 9. in-sample 和 out-of-sample 回測都跑過
□ 10. out-of-sample Sharpe Ratio > 0.8(否則不上)
□ 11. out-of-sample Max Drawdown < -15%(否則不上)
□ 12. 策略績效已與同期 Buy & Hold 比較
【風控層】
□ 13. stoploss 設定基於 ATR 分析,不是拍腦袋
□ 14. max_open_trades 和 tradable_balance_ratio 對應倉位不超過帳戶 15%
□ 15. protections 區塊已設定(MaxDrawdown + StoplossGuard 至少各一)
□ 16. dry_run: true 確認無誤(不是 false!)
【AI 訊號層】
□ 17. 情緒評分 script 可獨立跑,輸出格式正確
□ 18. 策略在 sentiment_score = 0 時仍能正常運作(fallback 處理)
□ 19. LLM API 金鑰存在 .env,已加入 .gitignore
【監控層】
□ 20. Telegram bot 設定完成,能收到進出場通知

台灣法規與稅務提醒
這段是很多量化教學課程不會講、但你遲早會碰到的現實。本課程不提供稅務建議,以下資訊以 2026 年 7 月現況為準,請以財政部最新公告及專業會計師建議為準。
加密貨幣所得
台灣財政部自 2024 年起明確對虛擬資產交易所得課稅。以下是基本架構:
- 境內平台:若你使用台灣註冊的虛擬資產服務業者(VASP),平台依法可能有申報義務
- 境外平台所得:Binance、Bybit、OKX 等境外交易所的交易所得屬「海外所得」,每年海外所得超過新台幣 100 萬元,需計入「基本所得額」申報最低稅負制(AMT,稅率 20%),扣除 670 萬元基本所得免稅額後課徵
- 資本利得計算:加密貨幣的成本基礎如何計算(FIFO 或加權平均法)目前仍有討論空間,強烈建議保存完整的交易紀錄(交易所匯出的 CSV 至少保留 5 年)
- DeFi 與質押收益:性質較複雜,需個案判斷,請諮詢熟悉虛擬資產的會計師
海外券商(台股以外)
若你的量化系統操作台灣以外的海外股票或期貨(例如透過 Interactive Brokers、Alpaca 等):
- 海外所得超過門檻同樣適用 AMT 申報
- 海外期貨盈虧計算方式與現貨不同,期貨損失是否可以扣抵所得,需確認你的申報方式
- 部分海外券商會對台灣用戶做 FATCA(美國外國帳戶稅收合規法)申報,資產和所得資訊可能被交換
本課程的立場
本課程全程使用模擬盤,不涉及真實資金操作。一旦你考慮從模擬盤走向實盤,建議在投入任何資金之前:
- 確認你使用的交易所在台灣的合法性(金管會 VASP 登記狀態)
- 諮詢具有虛擬資產稅務經驗的會計師(不是一般的財務顧問)
- 建立完整的交易紀錄系統(所有進出場、日期、金額、幣種)
最常犯的 8 個坑
坑 1:回測沒有 out-of-sample 驗證就上模擬盤
症狀:在 in-sample 期間把參數調到「Sharpe 2.0、最大回撤 5%」,興奮地啟動模擬盤,第一週就開始虧損。
問題:你看到的好看數字只是策略「記住了過去」的結果。out-of-sample 是唯一能稍微測試策略是否有真實預測力的方式。
# 檢查你有沒有做 out-of-sample:看回測的 timerange 範圍
# 如果你只跑了一段時間,全都用來「調參數」,那就是問題所在
freqtrade backtesting --config config.json --strategy YourStrategy \
--timerange 20250101-20250630 --fees 0.001
# ← 如果這段時間你根本沒看過(完全保留給驗證),才算 out-of-sample
坑 2:sentiment_score 欄位格式錯誤導致策略無法進場
症狀:啟動 dry-run 後,策略一直沒有進場訊號,日誌顯示:
WARNING - CapstoneStrategy: Column 'sentiment_score' is of type object, expected numeric.
Skipping entry signal generation.
原因:從 SQLite 讀取的分數被解析為字串而不是整數。
解法:在 populate_indicators 裡加明確的型別轉換:
dataframe["sentiment_score"] = pd.to_numeric(
dataframe["sentiment_score"], errors="coerce"
).fillna(0).astype(int)
坑 3:dry_run 誤設為 false,不小心動到真實帳戶
症狀:你以為在跑模擬,結果看到交易所帳戶出現不認識的訂單。
這個坑第 1 課就提過,這裡再說一次:啟動前每次都要:
grep "dry_run" config.json
# 預期輸出:
# "dry_run": true,
看到 false 就停手,改回 true,確認無誤再啟動。沒有例外。
坑 4:Telegram 通知設定錯誤,無法接到警報
症狀:策略跑了三天,完全沒收到任何 Telegram 訊息,後來發現帳戶已經觸發熔斷、停了很久。
解法:啟動後立即測試通知:
# 用 freqtrade 的 Telegram 測試功能
freqtrade trade --config config.json --strategy CapstoneStrategy &
# 然後在 Telegram 對 bot 發送 /status
# 若 bot 有回應,代表通知鏈路正常
如果 bot 沒有回應,檢查:Token 有無拼錯、chat_id 是個人 ID 還是群組 ID(群組 ID 有負號)、bot 有沒有被加進你的聊天。
坑 5:只看總報酬,忽略 Profit Factor 和盈虧比
症狀:回測顯示總報酬 +15%,感覺不錯。但實盤發現幾次大虧把所有小贏全部抹掉。
診斷:把 freqtrade 的回測結果裡找 Profit Factor 這個數字:
freqtrade backtesting --config config.json --strategy CapstoneStrategy \
--timerange 20250101-20250630 --fees 0.001 --export trades \
--export-filename user_data/backtest_results/capstone.json
# 然後用這個指令看詳細統計
freqtrade backtesting-show --export-filename user_data/backtest_results/capstone.json
Profit Factor = 總獲利 / 總虧損。低於 1.2 代表盈虧比太差,策略靠「多次小贏」撐起績效,遇到幾次大虧就撐不住。
坑 6:Cron 排程跑到一半掛掉,情緒評分停止更新
症狀:模擬盤跑了一週後,發現 sentiment_score 欄位全部是 0——情緒評分 script 的 Cron 任務在某個時間點靜悄悄地失敗了。
解法:讓情緒評分 script 寫入執行狀態,並在 freqtrade 策略裡加過時檢查:
def is_sentiment_fresh(db_path: str = "user_data/sentiment.db",
max_age_hours: int = 3) -> bool:
"""回傳情緒分數是否在 max_age_hours 小時內更新過。"""
import sqlite3
from datetime import datetime, timezone, timedelta
try:
conn = sqlite3.connect(db_path)
row = conn.execute(
"SELECT timestamp FROM sentiment ORDER BY timestamp DESC LIMIT 1"
).fetchone()
conn.close()
if not row:
return False
last_ts = datetime.fromisoformat(row[0]).replace(tzinfo=timezone.utc)
return datetime.now(timezone.utc) - last_ts < timedelta(hours=max_age_hours)
except Exception:
return False
# 在策略 populate_indicators 中:
if not is_sentiment_fresh():
# 情緒資料過時,用中性值,同時記入日誌
self.dp.send_msg("⚠ 情緒評分資料過時超過 3 小時,已切換為中性訊號")
dataframe["sentiment_score"] = 0
坑 7(心理坑):模擬盤剛賺就以為策略成熟了
症狀:模擬盤第一週賺了 3%,馬上把 dry_run: false,投入幾萬元。結果第二、三週連跌,因為第一週剛好碰上有利市場 Regime。
根本問題:4 週以內的模擬盤樣本量太小,無論盈虧都不代表統計意義。一個好策略也可能連輸好幾週;一個爛策略也可能碰上順風局賺一波。
正確做法:設定一個你在啟動模擬盤之前就寫下來的「上實盤條件」(例如「連續 8 週正報酬且最大回撤未超過 12%」),然後嚴格執行。決策規則必須在觀察之前就寫好,不是觀察之後才定。
坑 8(心理坑):策略虧損時不斷手動干預,破壞系統紀律
症狀:模擬盤連跌兩週,開始「幫策略做決定」——手動取消幾筆進場訂單、手動提早平倉、修改 config 的 stoploss。結果變成「人工+程式混合決策」,既沒有程式的紀律,也沒有人工的判斷力。
量化交易系統的核心價值就是「消除情緒干預」。一旦你在市場不利時手動介入,你就失去了這個系統的最大優勢。
正確做法:如果你覺得策略「需要調整」,先停機(不要在跑的時候改設定),做一次重新回測確認想法,然後從頭部署。永遠不要「邊跑邊改」。

作業
- 完整走一遍這堂課的 Step 1–7:從寫下你的交易假設開始,到模擬盤跑起來、Telegram 收到第一條通知為止。不需要策略完美,重點是完整跑過一遍整條流程,找出你在哪個環節卡住。
- 打完全流程清單的 20 個勾:把本堂的檢查清單列印或抄到你的筆記,逐條確認。有任何一項還沒搞定的,就是下一步的功課清單。
- 寫下你的「上實盤條件」:不管你現在有沒有打算上實盤,先把條件寫下來。格式:「當模擬盤連續 ___ 週,報酬 ___,Max Drawdown < ___,我才考慮最小部位實盤。」把這張紙放在顯眼的地方。
- 選做:壓力測試你的策略:把 timerange 設成 2022 年全年(歷史上的主要熊市),跑一次回測,看看你的風控有沒有辦法撐過那段環境。這是最能讓你了解自己策略下行風險的方式。
持續精進的資源
這門課教到這裡,你有了一個完整的出發點。但量化交易是一個需要持續學習的領域,以下是有實際價值的方向:
社群與討論:
- freqtrade Discord 官方伺服器(搜尋「freqtrade discord」)——遇到技術問題,這裡比 Stack Overflow 快得多
- QuantConnect 論壇——雖然平台不同,但策略設計的討論品質很高
- Twitter/X 上的 #freqtrade 標籤——可以看到其他人在做什麼
書籍(比課程更深):
- Ernest Chan《Algorithmic Trading》:策略設計和統計驗證的標準讀物,偏學術但扎實
- Marcos López de Prado《Advances in Financial Machine Learning》:如果你想在 ML 方向深入,這是業界公認的參考書
免費資源:
- freqtrade 官方文件(freqtrade.io)——所有設定參數的最終權威,每次升版都要看 changelog
- Quantopian 留下的免費教學(已在 Zipline 遷移後繼續運作)
重要的心理準備:量化交易沒有「學完就能賺錢」的終點。市場在變、策略會失效、新工具會出現。把這當成一個長期的研究項目,而不是一個你學完就能自動產出報酬的機器——這個心態調整,比任何技術更重要。
寫在最後
你在這八堂課裡學了量化交易的全流程,從第 1 課的「先潑冷水」,到這堂的「把所有零件接起來」。這不是一門讓你複製貼上一個策略、放著跑就能賺錢的課——如果你期待那種課,可以去找,但它大機率會讓你在不理解風險的情況下虧損。
這門課的目標是讓你理解你在做什麼:資料從哪裡來、策略的假設是什麼、回測數字代表什麼意思、AI 在哪裡有用、風控在保護你什麼。理解了這些,你才能在出問題的時候知道問題在哪,在策略失效的時候知道該怎麼辦。
量化交易能做到的,是把你的交易邏輯系統化、紀律化、可量測化——這已經比大多數散戶多了很大的優勢。但市場永遠比任何一個模型複雜。保持謙遜,保持學習,把資金管理當成比策略本身更重要的事。