iT邦幫忙

2025 iThome 鐵人賽

DAY 22
0
自我挑戰組

金融量化交易系列 第 22

22. 使用Backtrader進行回測

  • 分享至 

  • xImage
  •  

回測是開發有效交易系統的關鍵組成部分。它是透過歷史數據,使用給定策略定義的規則,來重建過去可能發生的交易。Backtrader 函式庫提供了在 Python 中進行此類測試的工具。

  1. 收集數據
  2. 定義我們的回測策略
  3. 提取績效統計數據,以便與基準進行比較和對照

範例 1:移動平均線交叉策略

# 安裝 backtrader 函式庫
! pip install backtrader >Null
import backtrader as bt
import yfinance as yf
import datetime

# 第 2 步:建立一個交易策略
class MovingAverageCrossStrategy(bt.Strategy):
    params = (
        ("short_window", 40),
        ("long_window", 100),
    )

    def __init__(self):
        self.data_close = self.datas[0].close
        self.short_ma = bt.indicators.SimpleMovingAverage(
            self.data_close, period=self.params.short_window
        )
        self.long_ma = bt.indicators.SimpleMovingAverage(
            self.data_close, period=self.params.long_window
        )
        self.crossover = bt.indicators.CrossOver(self.short_ma, self.long_ma)

    def next(self):
        if self.crossover > 0:  # 如果短期均線向上穿越長期均線
            self.buy()
        elif self.crossover < 0:  # 如果短期均線向下穿越長期均線
            self.sell()

# 第 3 步:使用 yfinance 加載歷史數據
data_df = yf.download('AAPL', start='2020-01-01', end='2022-01-01')
data = bt.feeds.PandasData(dataname=data_df)

# 第 4 步:設定回測
cerebro = bt.Cerebro()
cerebro.addstrategy(MovingAverageCrossStrategy)
cerebro.adddata(data)
cerebro.broker.set_cash(100000)  # 例如,以 100,000 現金開始

# 第 5 步:添加額外設定 (可選)
cerebro.addsizer(bt.sizers.FixedSize, stake=1000) # 每次交易固定數量
cerebro.broker.setcommission(commission=0.001)  # 0.1% 的手續費 (範例)

# 第 6 步:運行回測
print('起始投資組合價值: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('結束投資組合價值: %.2f' % cerebro.broker.getvalue())

# 第 7 步:將結果視覺化
cerebro.plot()

解讀圖表

Backtrader 產生的圖表提供了交易策略在回測期間表現的視覺化呈現。以下是如何解讀圖表的主要組成部分:

  1. 價格圖
    • K線/OHLC 圖:代表每個週期的開盤價、最高價、最低價和收盤價。
    • 移動平均線:如果您的策略中使用,移動平均線將會繪製在價格圖上。
    • 買/賣標記:箭頭或標記指示策略執行買入或賣出訂單的位置。
  2. 投資組合價值
    • 現金:水平線代表經紀帳戶中的可用現金。
    • 投資組合價值:線圖顯示總投資組合價值隨時間的變化,包括現金和未平倉部位的價值。
  3. 交易
    • 已平倉交易:根據您的繪圖設定,點或標記可能指示交易被平倉的位置。
  4. 指標
    • 如果您使用了額外的指標(如 MACD、RSI 等),它們可能會被繪製在單獨的面板中,顯示它們隨時間變化的值。
  5. 縮放與平移
    • 您可以縮放和平移圖表,以詳細檢查特定的時間範圍。

如何分析:

  • 獲利能力:觀察投資組合價值線,以評估策略隨時間的獲利能力。
  • 回撤:尋找投資組合價值下降的時期,這表示回撤。
  • 交易執行:確保交易(買/賣標記)根據策略邏輯在預期的位置執行。
  • 指標行為:如果使用技術指標,觀察其行為並確保它們按預期計算。
  • 過擬合:對過擬合要保持警惕。如果策略在回測中表現得異常好,它可能是對過去數據過度擬合,可能在即時交易中表現不佳。

額外提示:

  • 風險管理:確保策略遵守健全的風險管理原則,如設定停損水平,並且在單一交易中只冒險投資組合的一小部分。
  • 敏感度:測試策略對參數變化(如移動平均線週期)的敏感度,並確保其穩健,而不是過度優化於測試期間。
  • 樣本外測試:在樣本外數據上驗證策略,以確認其在未見數據上的表現。

Backtrader 是一個靈活的 Python 函式庫,允許您通過定義自訂邏輯來創建自己的交易策略。它本身不帶有預定義的交易策略,但它提供了一個強大的框架和內建指標,使您能夠定義各種各樣的策略。

以下是您可以使用 Backtrader 實現的一些策略類型:

策略 簡短描述
移動平均線交叉 當短期移動平均線穿越長期移動平均線時買入/賣出。
均值回歸 基於資產價格與其均值或其他相關基準的偏離進行交易。
動能策略 基於資產價格的加速度進行買入/賣出。
布林通道 使用位於移動平均線上方和下方的波動帶識別超買/超賣條件。
MACD 利用兩條移動平均線之間的收斂/發散來產生交易訊號。
RSI 使用相對強弱指標識別超買/超賣條件。
配對交易 對兩種相關資產的價格比率進行交易。
套利 利用相關資產或市場之間的價格差異。
基於機器學習 使用預測模型生成交易訊號。
期權策略 實施使用期權的策略,例如跨式、勒式、價差交易。
定期定額 無論價格如何,定期投資固定金額的資金。
投資組合再平衡 重新平衡投資組合以維持期望的資產配置。
季節性 基於市場的季節性模式或週期進行交易。
統計套利 使用統計方法產生回報,如共整合。
趨勢追蹤 識別並沿著主流趨勢的方向進行交易。
波動率突破 基於波動率的突然增加進行交易。
停損/止盈 實施使用停損或止盈水平來管理交易的策略。
網格交易 在預定義的間隔(網格水平)買入/賣出,無需預測價格方向。
背離交易 識別價格與振盪指標之間的背離並據此交易。
對沖 實施旨在減少交易中潛在損失的策略。
多時間框架策略 使用多個時間框架做出交易決策。
多資產策略 交易涉及多個可能相關的資產的策略。
... ...
VWAP 實施旨在接近成交量加權平均價進行交易的策略。
TWAP 實施旨在接近時間加權平均價進行交易的策略。
風險平價 根據風險分配資本,通常使用波動率作為代理。
智能貝塔 實施使用替代指數構建規則的策略。
利差交易 實施旨在從不同證券之間的收益率差異中獲利的策略。
備兌看漲期權 實施在持有的股票上賣出看漲期權的策略。
保護性看跌期權 實施購買看跌期權作為對持有股票下跌的保險的策略。
牛市看漲價差 實施買入和賣出具有相同到期日但不同行使價的看漲期權的策略。
熊市看跌價差 實施買入和賣出具有相同到期日但不同行使價的看跌期權的策略。
跨式組合 實施買入或賣出具有相同行使價和到期日的看漲和看跌期權的策略。
勒式組合 實施買入或賣出具有相同到期日但不同行使價的看漲和看跌期權的策略。

範例 2:布林通道與相對強弱指標 (RSI)

讓我們使用 Backtrader 創建一個更複雜的策略,結合布林通道 (Bollinger Bands)相對強弱指標 (RSI)。此策略將:

  • 當價格收盤低於布林通道下軌且 RSI 低於 30(表示超賣狀況)時買入
  • 當價格收盤高於布林通道上軌且 RSI 高於 70(表示超買狀況)時賣出

注意:

  • 請務必使用不同的數據和在各種情境下驗證策略,以確保其穩健性。
  • 請記住,過去的表現不代表未來的結果,回測應該是開發交易策略時使用的眾多工具之一。
  • 在開發交易策略時,始終遵守健全的風險管理原則。
import backtrader as bt
import yfinance as yf
import datetime

# 建立一個策略
class BollingerRSIStrategy(bt.Strategy):
    params = (
        ("bband_period", 20),
        ("rsi_period", 14),
        ("overbought", 70),
        ("oversold", 30),
        ("stddev", 2),
    )

    def __init__(self):
        self.bband = bt.indicators.BollingerBands(
            self.data.close, period=self.params.bband_period, devfactor=self.params.stddev
        )
        self.rsi = bt.indicators.RelativeStrengthIndex(
            period=self.params.rsi_period
        )

    def next(self):
        if self.data.close < self.bband.lines.bot and self.rsi < self.params.oversold:
            # 當收盤價低於布林下軌且RSI為超賣時
            self.buy()
        elif self.data.close > self.bband.lines.top and self.rsi > self.params.overbought:
            # 當收盤價高於布林上軌且RSI為超買時
            self.sell()

# 下載歷史數據
data_df = yf.download('AAPL', start='2020-01-01', end='2022-01-01')
data = bt.feeds.PandasData(dataname=data_df)

# 創建 Cerebro 實例
cerebro = bt.Cerebro(stdstats=False)

# 添加策略
cerebro.addstrategy(BollingerRSIStrategy)

# 將數據源添加到 Cerebro
cerebro.adddata(data)

# 設定我們的初始現金
cerebro.broker.set_cash(100000.0)

# 根據 stake 添加一個 FixedSize 的 sizer
cerebro.addsizer(bt.sizers.FixedSize, stake=1000)

# 設定手續費
cerebro.broker.setcommission(commission=0.001)

# 打印初始條件
print('起始投資組合價值: %.2f' % cerebro.broker.getvalue())

# 運行所有流程
cerebro.run()

# 打印最終結果
print('結束投資組合價值: %.2f' % cerebro.broker.getvalue())

# 繪製結果圖
cerebro.plot(iplot=True)

上一篇
21. 回測工具的類型
下一篇
23. 理解交易中績效與風險
系列文
金融量化交易23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言