iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
AI/ ML & Data

打開就會 AI 與數據分析的投資理財術系列 第 7

Day6:動量策略、均值回歸策略與技術指標策略開發

  • 分享至 

  • xImage
  •  

過去幾天我們分別學習了基本均線指標來交易以及使用 Backtrader來做回測,今天我們將綜合學習動量策略均值回歸策略,以及利用技術指標(如 RSI 和 MACD)開發交易策略,並且會使用 Backtrader 框架進行策略的回測優化。我們將從這些策略的數學基礎開始,逐步完成策略的開發與優化。今日 Colab


一、動量策略開發

1. 動量策略的概念與數學基礎

動量策略基於這樣的假設:價格在一段時間內將會繼續沿著目前的趨勢運行,即 強者恆強,弱者恆弱。在統計學上,這代表資產價格呈現出自相關性。

  • 基本思想:如果過去 N 天資產的價格持續上漲,未來一段時間可能會繼續上漲;反之亦然。
  • 常用指標:N 日動量指標、收益率排序等。

動量公式
https://ithelp.ithome.com.tw/upload/images/20240921/20120549ix0cBsLcH2.png
其中,P_t 是第 t 天的收盤價,P_{t-N}N 天前的收盤價。動量策略根據該值的正負判斷買入或賣出信號。

2. 使用 Backtrader 實現動量策略

import backtrader as bt
import yfinance as yf
import pandas as pd
import numpy as np

# 使用 yfinance 下載 AAPL 的數據
data = yf.download('AAPL', start='2020-01-01', end='2021-01-01')

# 將數據轉換為 backtrader 可以使用的格式
data_bt = bt.feeds.PandasData(dataname=data)

# 建立動量策略類別
class MomentumStrategy(bt.Strategy):
    params = (('period', 10),)

    def __init__(self):
        self.momentum = bt.indicators.Momentum(self.data.close, period=self.params.period)
        self.starting_value = self.broker.getvalue()
        self.daily_values = []  # 用於儲存每日資產價值

    def next(self):
        if not self.position:  # 如果沒有持倉
            if self.momentum[0] > 0:  # 動量指標大於0,表示上升趨勢
                self.buy()
        elif self.momentum[0] <= 0:  # 動量指標小於等於0,表示下降趨勢
            self.sell()

        # 每次更新時記錄當天的資產價值
        self.daily_values.append(self.broker.getvalue())

# 設定回測環境
cerebro = bt.Cerebro()
cerebro.addstrategy(MomentumStrategy)

# 添加數據到 backtrader
cerebro.adddata(data_bt)

# 設定初始資金
cerebro.broker.setcash(100000)

# 執行回測
print(f'初始資金: {cerebro.broker.getvalue():.2f}')
results = cerebro.run()
print(f'回測後的資金: {cerebro.broker.getvalue():.2f}')

# 取得策略結果
strategy = results[0]

# 計算每日收益率
portfolio_values = pd.Series(strategy.daily_values)
returns = portfolio_values.pct_change().dropna()

# 計算年化夏普比率
annual_return = returns.mean() * 252
annual_volatility = returns.std() * np.sqrt(252)
risk_free_rate = 0.01  # 無風險利率設為1%
sharpe_ratio = (annual_return - risk_free_rate) / annual_volatility

# 計算最大回撤
cumulative_returns = (1 + returns).cumprod()
drawdown = cumulative_returns / cumulative_returns.cummax() - 1
max_drawdown = drawdown.min()

print(f'夏普比率: {sharpe_ratio:.2f}')
print(f'最大回撤: {max_drawdown:.2%}')

# 繪製圖表
## 如果在 local machine python terminal 之上:
# cerebro.plot()

## 如果在 Colab 之上:
#https://www.roelpeters.be/how-to-use-backtrader-plots-in-python-notebooks/
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = [15, 12]
plt.rcParams.update({'font.size': 12}) 
img = cerebro.plot(iplot = False)
img[0][0].savefig('backtrader_momentum.png')

可以得到下圖:
https://ithelp.ithome.com.tw/upload/images/20240921/20120549VewP6misQk.png


二、均值回歸策略開發

1. 均值回歸策略的概念與數學基礎

均值回歸策略基於這樣一種假設:價格圍繞某個均值上下波動,當價格偏離均值過多時,具有回歸的趨勢。在統計學上,這意味著價格的時間序列具有均值回歸性質。

  • 基本思想:當價格高於均值時,預期價格將下跌至均值;當價格低於均值時,預期價格將回升至均值。
  • 常用指標:均線乖離率、Z-score 等。

Z-score 公式
https://ithelp.ithome.com.tw/upload/images/20240921/20120549oO95Y5iZUE.png
其中,P_t 是當前價格,\mu_t 是移動平均值,\sigma_t 是移動標準差。當 Z-score 大於某個閾值時,產生賣出信號;當 Z-score 小於某個閾值時,產生買入信號。

2. 使用 Backtrader 實現均值回歸策略

#均值回歸策略
class MeanReversionStrategy(bt.Strategy):
    params = (('period', 20), ('zscore_entry', 1), ('zscore_exit', 0))

    def __init__(self):
        self.moving_avg = bt.indicators.SimpleMovingAverage(self.data.close, period=self.params.period)
        self.stddev = bt.indicators.StandardDeviation(self.data.close, period=self.params.period)
        self.zscore = (self.data.close - self.moving_avg) / self.stddev
        self.daily_values = []  # 用於儲存每日資產價值

    def next(self):
        if self.zscore[0] < -self.params.zscore_entry and not self.position:
            self.buy()
        elif self.zscore[0] > self.params.zscore_exit and self.position:
            self.sell()

        # 每次更新時記錄當天的資產價值
        self.daily_values.append(self.broker.getvalue())

# 設定回測環境
cerebro = bt.Cerebro()
cerebro.addstrategy(MeanReversionStrategy)

請將上述 Startegy 改至程式中,或者直接執行 Colab 相關章節可以得到下面圖形:
https://ithelp.ithome.com.tw/upload/images/20240921/20120549FsWYY8gbWK.png


三、技術指標策略開發

1. RSI 策略

RSI 的數學基礎

相對強弱指標(RSI)衡量價格變動的速度和幅度,計算公式為:
https://ithelp.ithome.com.tw/upload/images/20240921/20120549lvMAjA0xvg.png
其中,( RS ) 為平均上漲收益與平均下跌收益之比。通常,RSI 超過 70 表示超買,低於 30 表示超賣。

使用 Backtrader 實現 RSI 策略
RSI 因為算是常用指標所以可以直接使用 bt.indicators.RelativeStrengthIndex 得到

#RSI策略
class RSIStrategy(bt.Strategy):
    params = (('rsi_period', 14), ('rsi_overbought', 70), ('rsi_oversold', 30))

    def __init__(self):
        self.rsi = bt.indicators.RelativeStrengthIndex(self.data.close, period=self.params.rsi_period)
        self.daily_values = []  # 用於儲存每日資產價值

    def next(self):
        if self.rsi < self.params.rsi_oversold and not self.position:
            self.buy()
        elif self.rsi > self.params.rsi_overbought and self.position:
            self.sell()

        # 每次更新時記錄當天的資產價值
        self.daily_values.append(self.broker.getvalue())

cerebro = bt.Cerebro()
cerebro.addstrategy(RSIStrategy)

請將上述 Startegy 改至程式中,或者直接執行 Colab 相關章節可以得到下面圖形:
https://ithelp.ithome.com.tw/upload/images/20240921/20120549R6YTy5XY8t.png

2. MACD 策略

MACD 的數學基礎

MACD 是利用兩條不同周期的指數移動平均線(EMA)的差值來衡量價格動量,計算公式為:
https://ithelp.ithome.com.tw/upload/images/20240921/20120549yaSiQzOU4u.png
xy 分別為不同長度的時間。其中,例如常見的訊號線為 MACD 的 9 日 EMA。當 MACD 上穿訊號線(Signal)時,產生買入信號;下穿時,產生賣出信號。
使用 Backtrader 實現 MACD 策略
MACD一樣為常見訊號, 可以透過 bt.indicators.MACD 去取得 MACD 以及 signal 訊號

#MACD策略
class MACDStrategy(bt.Strategy):
    def __init__(self):
        self.macd = bt.indicators.MACD(self.data.close)
        self.signal = self.macd.signal
        self.daily_values = []  # 用於儲存每日資產價值

    def next(self):
        if self.macd.macd[0] > self.signal[0] and not self.position:
            self.buy()
        elif self.macd.macd[0] < self.signal[0] and self.position:
            self.sell()

        # 每次更新時記錄當天的資產價值
        self.daily_values.append(self.broker.getvalue())

cerebro = bt.Cerebro()
cerebro.addstrategy(MACDStrategy)

請將上述 Startegy 改至程式中,或者直接執行 Colab 相關章節可以得到下面圖形:
https://ithelp.ithome.com.tw/upload/images/20240921/20120549YiUuknn0LB.png


四、策略優化與參數調整

使用 Backtrader 可以對策略參數進行優化,以找到最佳的參數組合,而我們就需要用到 cerebro.optstrategy。例如,可以對 RSI 策略進行優化,尋找最適合的 RSI 週期和超買、超賣閾值。

對 RSI 策略進行參數優化
將程式中對應的地方的修改如下即可:

cerebro = bt.Cerebro()
cerebro.addstrategy(RSIStrategy)
cerebro.optstrategy(RSIStrategy, rsi_period=range(10, 21), rsi_overbought=range(65, 76), rsi_oversold=range(25, 36))
cerebro.adddata(data)
cerebro.broker.setcash(100000)
cerebro.run()

總結

  • 動量策略:捕捉價格延續性,適用於趨勢市場。
  • 均值回歸策略:利用價格回歸均值的特性,適用於震盪市場。
  • RSI & MACD 技術指標策略:通過技術指標信號,產生買入和賣出操作。

第6天任務

  1. 實踐:使用 Backtrader 實現並優化自己的策略。
  2. 比較:將不同策略的表現進行比較,尋找最適合的策略。
  3. 策略優化:嘗試對參數進行調整,觀察策略表現的變化。

上一篇
Day5:回測框架介紹
下一篇
Day7:利用 Backtrader 進行策略參數優化夏普率細談
系列文
打開就會 AI 與數據分析的投資理財術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言