本文目錄
想踏入程式交易,卻不知道從哪裡開始?多數人卡在「策略聽起來很厲害,但寫不出來」,或是「跑出漂亮的回測曲線,上線後卻完全走樣」。這篇文章會用最務實的方式,帶你從零理解一套交易策略的完整開發流程:從資料取得、訊號邏輯、回測驗證到避開常見陷阱。你不需要是數學天才,只要會基礎 Python,就能跟著做完一遍。
H2:量化交易策略入門:先搞懂「策略」到底由哪三塊組成
很多人以為量化交易策略就是「一串買賣條件」,其實一套可運作的策略,至少要包含三個獨立模組,缺一不可:
1. 訊號模組(Signal):決定「什麼時候該進場、什麼時候該出場」。例如均線黃金交叉、RSI 低於 30。
2. 部位管理模組(Position Sizing):決定「這次要下多少資金」。是固定一張?還是資金的 10%?
3. 風控模組(Risk Management):決定「什麼情況下無條件認賠」。例如固定停損 5%、或用 ATR 動態停損。
新手最常犯的錯,就是把全部心力放在訊號模組,卻用「全壓」下單、也沒有停損。結果訊號勝率再高,一次大回檔就把帳戶打回原點。
以台股為例,你還要記得兩個固定成本:券商手續費 0.1425%(電子下單常見折扣另計)、證交稅 0.3%(賣出時收取)。來回一趟的成本大約落在 0.5% 上下,這代表你的策略「每次進出」至少要能覆蓋這個摩擦成本,否則只是幫券商打工。
下面是一個最小可運作的訊號範例,用均線交叉判斷多空:
import pandas as pd
def ma_cross_signal(df: pd.DataFrame, short: int = 20, long: int = 60) -> pd.DataFrame:
"""
傳入含 'close' 欄位的 DataFrame,回傳加上訊號欄位的結果。
訊號:1 代表做多、0 代表空手。
"""
out = df.copy()
out["ma_short"] = out["close"].rolling(short).mean()
out["ma_long"] = out["close"].rolling(long).mean()
# 短均線在長均線之上 -> 持有多單
out["signal"] = (out["ma_short"] > out["ma_long"]).astype(int)
return out
這段程式碼沒有魔法,但它就是多數趨勢策略的骨架。先求「能跑、能看懂」,再談優化。
H2:Python 交易策略範例:用 pandas 寫出可回測的均線策略
有了訊號,下一步是把它接上「回測」。這裡提供一個不含未來函數的簡易回測函式,重點在於:今天的部位,是用昨天收盤後才知道的訊號決定的。
import pandas as pd
import numpy as np
def backtest_ma(df: pd.DataFrame, short: int = 20, long: int = 60,
fee_rate: float = 0.001425, tax_rate: float = 0.003) -> pd.DataFrame:
"""
極簡均線策略回測(僅供教學,未含滑價與融資)。
df 需含 'close' 欄位,index 為日期。
"""
data = df.copy()
data["ma_short"] = data["close"].rolling(short).mean()
data["ma_long"] = data["close"].rolling(long).mean()
# 今日訊號
data["signal"] = (data["ma_short"] > data["ma_long"]).astype(int)
# 關鍵:部位延遲一天,避免未來函數
data["position"] = data["signal"].shift(1).fillna(0)
# 每日報酬
data["ret"] = data["close"].pct_change().fillna(0)
data["strategy_ret"] = data["position"] * data["ret"]
# 交易成本:只在部位變動當天扣一次
data["trade"] = data["position"].diff().abs().fillna(0)
data["cost"] = data["trade"] * (fee_rate + tax_rate)
data["strategy_ret_net"] = data["strategy_ret"] – data["cost"]
# 累積淨值
data["equity"] = (1 + data["strategy_ret_net"]).cumprod()
return data
幾個一定要看懂的重點:
shift(1)是防未來函數的核心。沒有它,你的回測會「偷看」當天收盤價才決定當天要不要進場,績效會漂亮到不真實。trade欄位抓出「部位有變動」的日子,只在那些天扣成本,才符合實際下單行為。- 這份程式碼沒有處理滑價、漲跌停買不到、除權息調整,所以它只是「教學版本」,不是可直接上線的版本。
如果你想用更完整的框架,backtrader、vectorbt 都是常見選擇;但建議先用純 pandas 手刻一次,你才會真正理解每個數字怎麼來的。
H2:交易策略回測:怎麼判斷一個策略「是真的」還是「運氣好」
回測跑完,看到淨值曲線往上,先別高興。你要問的是:這條曲線是策略的功勞,還是市場剛好在那段時間大漲?
三個實用的檢查方法:
1. 跟大盤比(Benchmark)
把你的策略淨值,跟同期「買進持有」的淨值畫在同一張圖。如果策略報酬跟大盤幾乎一樣,那你只是承擔了風險卻沒創造超額報酬。
2. 樣本內外分割(In-Sample / Out-of-Sample)
把資料切成前 70% 當「訓練」,後 30% 當「測試」。用前 70% 調參數,然後只用後 30% 驗證。如果策略只在訓練段有效、測試段崩掉,就是過度擬合。
3. 看最大回撤(Max Drawdown)與交易次數
一條平滑上升的曲線,如果只來自 5 筆交易,那統計上毫無意義。建議至少要有數十筆以上的交易樣本,且最大回撤必須是你「心理上真的能承受」的幅度。
| 檢查項目 | 健康訊號 | 危險訊號 |
|---|---|---|
| 與大盤比較 | 有超額報酬且波動較低 | 走勢與大盤幾乎重疊 |
| 樣本外測試 | 表現與樣本內接近 | 樣本外績效腰斬 |
| 交易筆數 | 樣本充足、分布平均 | 集中在少數幾筆 |
| 最大回撤 | 在可承受範圍內 | 回撤超過 50% |
| 參數敏感度 | 參數微調結果穩定 | 參數差一點就崩盤 |
這裡要特別提醒:表格中的「健康/危險」是判斷原則,不是實測績效數字。 任何具體報酬率都必須用你自己的資料跑出來才算數。
H2:避雷防坑指南:程式交易策略開發最常見的 5 個地雷
這一段是整篇文章最重要的部分。以下每個坑,都是新手(甚至老手)反覆踩的。
地雷 1:未來函數(Look-ahead Bias)
成因:不小心用到「當下還不知道」的資訊。例如用當天收盤價算出訊號,卻假設當天開盤就進場;或用 rolling().mean() 時把當天也算進去,卻當成昨天就能知道的資訊。
防範:所有訊號一律 shift(1) 後才當作部位;檢查每個指標的計算窗口是否包含「未來」的資料點。這是最致命也最隱蔽的錯誤,因為它會讓回測績效「好到不合理」。
地雷 2:忽略交易成本與滑價
成因:回測只算價差,忘了台股手續費 0.1425%、證交稅 0.3%,以及實際成交價可能比預期差(滑價)。高頻進出的策略尤其致命。
防範:在回測中明確扣除來回約 0.5% 的成本,並對滑價做保守假設(例如每次進出多扣 0.1%)。如果策略扣完成本後就由盈轉虧,那它本來就不該上線。
地雷 3:過度最佳化(Overfitting)
成因:不斷微調參數,直到回測曲線最漂亮。結果策略只是「記住了歷史」,對未來毫無預測力。
防範:限制可調參數的數量;用樣本外資料驗證;觀察「參數高原」——好的策略在參數小幅變動時,績效應該平穩,而不是只有某一組參數特別神。
地雷 4:存活者偏差(Survivorship Bias)
成因:用「現在還存在」的股票清單回測,忽略了那些曾經存在、後來下市或倒閉的公司。這會系統性高估報酬。
防範:使用含下市股票的歷史資料庫,或至少理解你的回測結果帶有這個偏誤。
地雷 5:把回測當保證
成因:以為回測賺錢,實盤就會賺錢。實際上還有流動性、漲跌停、心理因素等變數。
防範:先跑紙上交易(Paper Trading)數週,確認下單流程與策略行為一致,再考慮投入真實資金。永遠只用「可承受損失」的資金。
H2:工具選擇:手刻 vs 框架 vs 看盤平台
開發交易策略時,工具沒有絕對好壞,只有適不適合你現在的階段。以下做個比較:
| 工具類型 | 代表工具 | 適合對象 | 優點 | 限制 |
|---|---|---|---|---|
| 純 pandas 手刻 | pandas / numpy | 想徹底理解原理的新手 | 每個環節都自己掌控 | 功能需自行開發 |
| 回測框架 | backtrader、vectorbt | 已有基礎、要快速迭代 | 內建回測、繪圖 | 學習曲線較陡 |
| 看盤/圖表平台 | TradingView | 想視覺化驗證想法 | 圖表直覺、指標豐富 | 複雜邏輯仍需程式 |
如果你還在「驗證想法」的階段,用圖表工具先肉眼確認型態,再進程式碼,效率會高很多。像 TradingView 這類平台可以讓你快速疊加均線、RSI 等指標,把腦中模糊的想法先畫出來,之後再翻成 Python 就輕鬆許多。它的付費方案在指標數量與警報功能上有差異,可以依自己的使用頻率評估。
H2:FAQ 常見問題
Q1:完全不會 Python,可以直接學量化交易策略嗎?
可以,但建議先花 2~4 週打好 Python 基礎,特別是 pandas 的 DataFrame 操作、索引與時間序列處理。這篇的範例都用得到這些觀念,基礎打好後,看懂回測程式碼會快很多。
Q2:回測賺錢的策略,實盤一定會賺嗎?
不一定,而且通常不會完全一樣。回測是「在已知歷史資料上的模擬」,實盤會遇到滑價、流動性不足、漲跌停買不到等狀況。建議先紙上交易一段時間,確認策略行為符合預期,再投入真實資金。
Q3:我需要多少資金才能開始程式交易?
這取決於你的策略與商品。台股一張股票動輒數萬元,若資金有限,可考慮零股或 ETF。重點不是資金多寡,而是部位管理——單筆風險不宜超過總資金的 1~2%,這樣即使連續虧損也不會傷筋動骨。
Q4:台股交易成本到底怎麼算?
買進時付手續費 0.1425%(多數券商有電子下單折扣),賣出時付手續費 0.1425% 加上證交稅 0.3%。來回一趟約 0.5% 上下,實際數字依券商折扣而異,回測時務必納入。
結論:從今天開始,寫出你的第一個交易策略
量化交易策略不是天才的專利,而是一套可以被拆解、被驗證、被修正的流程:先定義訊號,再管好部位與風控,接著用不含未來函數的程式碼回測,最後用樣本外資料與成本檢驗它是不是真的。這篇文章提供的均線範例,就是你可以立刻動手改的第一塊積木。
下一步建議你這樣做:
1. 把上面的 backtest_ma 複製到你的環境,餵進一檔你有興趣的 ETF 歷史資料跑跑看。
2. 試著把 shift(1) 拿掉,觀察績效「變好」多少——你會親眼見識未來函數的威力。
3. 想先視覺化驗證想法,可以到 TradingView 把均線與訊號畫出來,確認邏輯符合直覺後再寫成程式。
記得:本文僅供程式教學與研究,不構成任何個股買賣建議。先求「跑得動、看得懂、扣得掉成本」,你就已經贏過大多數只會紙上談兵的人了。