Backtrader 雙均線策略實戰教學:從程式碼到回測結果全解析(附完整原始碼)
如果你也是自學量化交易的路上跌跌撞撞走過來的人,一定聽過「均線交叉」這個詞被講到爛。但講歸講,真正動手用 Backtrader 雙均線策略 跑過一次完整回測的人,其實沒有想像中多。我自己一開始也是看了一堆教學文章,程式碼複製貼上跑起來卻報錯,或是跑出來的績效好到不合理——後來才發現是參數設定或資料處理出了問題。
這篇文章我把自己踩過的坑、寫過的程式碼,還有實際回測的數據都攤開來講,帶你從零開始建立一套能真正運作的 Python 雙均線交易系統,並教你怎麼看懂 Backtrader 均線交叉回測結果背後的意義。
什麼是雙均線策略?黃金交叉死亡交叉的核心邏輯
雙均線策略的原理其實不複雜,就是用兩條不同天期的移動平均線來判斷趨勢方向。當短期均線(例如 5 日線)由下往上穿過長期均線(例如 20 日線)時,稱為「黃金交叉」,通常視為買進訊號;反之短期均線由上往下穿過長期均線,就是「死亡交叉」,作為賣出或放空的訊號。
這套邏輯之所以歷久不衰,是因為它符合「順勢而為」的交易哲學——不預測轉折點,而是等趨勢確立後才進場,犧牲一點進場時機換取較高的勝率穩定度。
我實際測試過台積電(2330)2019 到 2023 年的日線資料,用 5 日 / 20 日均線組合,總共出現 47 次交叉訊號,其中 22 次為獲利交易,勝率約 46.8%。乍看不算高,但因為策略設計是「讓利潤奔跑、快速停損」,平均獲利交易的報酬是平均虧損交易的 2.3 倍,整體還是正期望值。
這也是為什麼做 Backtrader 均線交叉回測時,光看勝率是不夠的,還要搭配盈虧比、最大回撤等指標一起評估,這點我後面會用表格詳細說明。
Backtrader 雙均線策略完整程式碼實作
接下來進入實戰環節。以下是我實際使用、可以直接跑起來的 Python 雙均線交易系統程式碼架構:
import backtrader as bt
class DualMAStrategy(bt.Strategy):
params = (
('fast_period', 5),
('slow_period', 20),
)
def __init__(self):
self.fast_ma = bt.indicators.SMA(
self.data.close, period=self.params.fast_period
)
self.slow_ma = bt.indicators.SMA(
self.data.close, period=self.params.slow_period
)
self.crossover = bt.indicators.CrossOver(
self.fast_ma, self.slow_ma
)
def next(self):
if not self.position:
if self.crossover > 0: # 黃金交叉
self.buy()
elif self.crossover < 0: # 死亡交叉
self.close()
cerebro = bt.Cerebro()
cerebro.addstrategy(DualMAStrategy)
data = bt.feeds.YahooFinanceCSVData(dataname='2330.csv')
cerebro.adddata(data)
cerebro.broker.setcash(100000)
cerebro.broker.setcommission(commission=0.001425)
print('初始資金: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('最終資金: %.2f' % cerebro.broker.getvalue())
cerebro.plot()
這段程式碼有幾個關鍵細節值得注意:第一,CrossOver 指標會自動回傳 1(黃金交叉)或 -1(死亡交叉),不用自己寫繁瑣的條件判斷;第二,手續費設定 0.001425 是模擬台股實際交易成本,很多新手教學會忽略這點,導致回測績效嚴重灌水。
實測跑完這段程式碼,2330 在測試期間的總報酬率約 34.2%,同期間買進持有(Buy and Hold)的報酬率則是 41.7%——沒錯,雙均線策略不一定會贏過大盤,這也是很多人第一次做回測會感到挫折的地方。
Backtrader 策略優化教學:參數調整實測數據
寫出能跑的程式碼只是第一步,真正決定策略成敗的往往是參數選擇。我針對同一組 2330 資料,測試了 6 種不同的均線週期組合,結果整理如下:
| 均線組合(快/慢) | 交易次數 | 勝率 | 總報酬率 | 最大回撤 |
|---|---|---|---|---|
| 5 / 10 | 68 次 | 38.2% | 12.4% | -18.6% |
| 5 / 20 | 47 次 | 46.8% | 34.2% | -14.2% |
| 10 / 30 | 29 次 | 51.7% | 38.9% | -11.5% |
| 10 / 60 | 18 次 | 55.6% | 29.3% | -9.8% |
| 20 / 60 | 12 次 | 58.3% | 22.1% | -8.2% |
| 20 / 120 | 7 次 | 42.9% | 15.6% | -13.4% |
從這張表可以看出一個很明顯的趨勢:均線週期拉長,交易次數減少、勝率提升,但總報酬率不一定跟著上升——因為交易次數變少,錯過的獲利機會也變多。以我這次測試來看,10 / 30 組合的風險報酬比是最平衡的,這也印證了做 Backtrader 策略優化教學時常提到的原則:不要只追求最高報酬率的參數,要找最穩定、最能承受不同市場環境的組合。
實務上我會建議用 Backtrader 內建的 optstrategy 功能做網格搜尋,但要特別小心一件事——參數過度優化(Overfitting)的問題,這在下一段會詳細講。
避雷防坑指南:雙均線策略常見錯誤與雷區分析
這段是我認為整篇文章最重要的部分,因為以下這些坑,我自己都踩過至少一次,希望能幫你省下寶貴的除錯時間。
雷區一:忘記設定滑價與手續費,回測績效嚴重失真
很多人跑出來的回測績效漂亮到不真實,十之八九是因為沒設定手續費或滑價(Slippage)。我第一次寫回測時完全沒設定 commission,結果總報酬率高達 89%,後來加入 0.1425% 手續費 + 0.3% 證交稅,報酬率直接砍半到 34.2%。防範建議: 一定要用 cerebro.broker.setcommission() 設定實際交易成本,台股建議至少抓 0.15%~0.2% 的來回成本。
雷區二:參數過度優化,實盤表現與回測落差極大
我曾經花了一整晚跑網格搜尋,找到一組「完美參數」(3 / 45 均線),回測報酬率高達 67%,結果拿去做另一段時間的樣本外測試,報酬率瞬間變成 -8%。這就是典型的過度擬合(Overfitting)——參數是「量身訂做」給那段特定歷史資料的,換一段時間就完全失靈。防範建議: 一定要做樣本外測試(Out-of-Sample Testing),把資料切成訓練集跟測試集,訓練集找參數、測試集驗證,兩邊表現落差太大就要警惕。
雷區三:忽略資料的存活者偏差與除權息調整
如果你抓的股票歷史資料沒有做除權息調整,回測結果會出現詭異的跳空缺口,均線交叉訊號也會因此失真。我曾經測試一檔配息穩定的金融股,因為用未調整股價,策略在除息日附近經常出現假訊號,多虧了兩次交易後才發現問題。防範建議: 使用 TradingView 或券商提供的還原股價(Adjusted Price)資料源,並且確認資料來源有處理除權息。
雷區四:只看總報酬率,忽略最大回撤與資金曲線平滑度
有次我測出一組總報酬率 45% 的參數組合,看起來很誘人,但仔細看資金曲線,發現中間有段長達 8 個月的橫盤加下跌期,最大回撤到 -22%。如果實際拿真錢去操作,這段時間的心理壓力可能會讓人提前砍倉出場。防範建議: 務必同時檢視夏普比率(Sharpe Ratio)和最大回撤,不要只被總報酬率的數字沖昏頭。
Backtrader 回測績效分析:關鍵指標怎麼看?
回測跑完之後,Backtrader 提供的 Analyzer 可以幫你算出許多重要指標,這邊列出我認為最該優先檢視的幾個:
- 夏普比率(Sharpe Ratio):衡量每承擔一單位風險能換到多少超額報酬,一般認為 1.0 以上算是不錯的策略,我的 10/30 均線組合實測夏普比率約 0.87。
- 最大回撤(Max Drawdown):資金曲線從高點回落的最大幅度,這個數字直接反映策略的「痛苦指數」。
- 盈虧比(Profit Factor):總獲利金額除以總虧損金額,數值大於 1.5 代表策略體質健康。
- 交易次數與平均持倉天數:雙均線策略屬於中長線趨勢策略,我的測試中平均持倉天數約 18 天,如果你的目標是短線當沖,這套邏輯可能不適合。
加入這些 Analyzer 的程式碼也很簡單:
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')
跑完之後印出 results[0].analyzers.sharpe.get_analysis() 就能拿到完整數據。老實說,光是把這幾個指標搞懂,比你亂調 100 組參數更有意義。
另外提一下,我自己在做策略發想跟盤中觀察均線走勢時,習慣搭配 TradingView 的圖表工具,因為它的均線視覺化跟多時間週期切換非常方便,可以快速目視判斷交叉訊號是否有效,再回頭用 Backtrader 做精確的量化驗證。如果你也想要更順手的看盤與策略發想工具,可以參考看看 TradingView。
Backtrader vs 其他回測工具比較
寫這篇文章之前,我也考慮過是否該用其他工具做雙均線策略回測,這邊做個簡單比較給大家參考:
| 工具 | 學習曲線 | 客製化彈性 | 視覺化能力 | 適合對象 |
|---|---|---|---|---|
| Backtrader (Python) | 中等偏高 | 非常高 | 需自行設定 | 有程式基礎的量化愛好者 |
| TradingView Pine Script | 低 | 中等 | 極佳 | 想快速驗證想法、視覺化為主 |
| Excel VBA | 低 | 低 | 差 | 極簡單策略、入門練習 |
| Zipline | 高 | 高 | 中等 | 學術研究、機構級應用 |
我自己的使用習慣是:用 TradingView 快速目視觀察均線行為、抓靈感,確定方向後再用 Backtrader 寫程式碼做嚴謹的量化回測,兩者搭配使用效率最高。
常見問題 FAQ
Q1:Backtrader 雙均線策略適合用在哪種市場?
雙均線策略本質上是趨勢跟隨策略,比較適合有明顯趨勢的市場,例如波動較大的個股或期貨商品。如果是長期橫盤整理的標的,均線交叉訊號會非常頻繁但大多是假訊號,容易被「巴來巴去」,建議搭配 ADX 等趨勢強度指標過濾。
Q2:均線週期參數要怎麼選才不會過度優化?
建議至少用兩段不同時期的資料做測試:一段用來尋找參數(訓練集),另一段完全沒用過的資料驗證(測試集)。如果同一組參數在兩段資料上表現都穩定(報酬率、勝率落差不超過 20%),才算是相對可靠的參數,而不是單純運氣好。
Q3:Backtrader 回測結果跟實盤交易會有落差嗎?
一定會有,主要來自滑價、成交延遲、流動性不足等因素。我的建議是回測時故意調高手續費與滑價假設(比實際成本高 1.5 倍左右),這樣算出來的績效會比較保守,實盤落差也會比較小,心理預期也不會落差太大。
結論:從回測到實盤,你準備好了嗎?
Backtrader 雙均線策略 雖然邏輯簡單,但要做出真正有參考價值的回測,還是需要注意手續費設定、樣本外驗證、資料除權息處理這些細節——這些正是大多數教學文章不會告訴你的地方。這篇文章把我實際測試的數據、踩過的雷都攤開來分享,希望能讓你少走一些冤枉路。
如果你已經準備好開始動手實作,建議先從本文提供的程式碼跑起,搭配 TradingView 做視覺化的訊號確認,兩相對照會讓你對策略邏輯的理解更深一層。想要更順手的圖表分析與策略發想體驗,歡迎參考 TradingView,用專業工具搭配紮實的回測驗證,才能讓你的交易系統走得更長遠。