close

【backtesting】Python輕量回測工具-1:backtesting基礎教學  Python回測股票比特幣的好幫手

一、前言

腦中有想法想要回測你的交易策略嗎?尤其是股票跟比特幣,這邊介紹你一個輕巧好用的工具,三兩下把你的邏輯量化回測!讓我為你介紹backtesting!不只可以把回測的資料視覺化,還可以最佳化等真的很方便。而且這圖看著看著整個人就專業了起來呢!

第一篇基礎教學讓我來告訴你他有多方便,想知道更多細節用法不要忘記留言給我!

(完整程式碼在最下面,想一步一步學可以從頭開始看唷!)

image

 

 

二、backtesting基本用法

(0) 安裝

pip install backtesting

這部份應該不用我多說了吧!如果遇到問題可以留言給我唷!像是無法存取之類的!

 

(1) 使用套件

import pandas, numpy
import datetime
from backtesting import Backtest, Strategy
from backtesting import set_bokeh_output
set_bokeh_output(notebook=False) # 在spyder下要使用此指令才能顯示喔

把可能用到的套件匯入,這邊要注意如果你是用spyder的話要set_bokeh_output(notebook=False)。

 

(2) 取得資料、資料處理及計算指標

import investpy


# 下載股價資料
df = investpy.get_stock_historical_data(stock='2330',
                           country='Taiwan',
                           from_date='01/01/2010',
                           to_date='10/07/2021',)

# 資料預處理
df.index = pandas.to_datetime(df.index)

# 指標計算
df['sma5'] = df['Close'].rolling(5).mean()
df['sma20'] = df['Close'].rolling(20).mean()

這邊下載台積電股價資料,而後把index改成時間格式,再來計算我們常用的均線。

這邊我的習慣是在外面就先把指標計算好,當然等等在backtesting裡面也可以計算,但在外面真的比較方便也好記。(相信我)

還不會用investing的小夥伴可以看:【Python量化資料】用Python抓取Yahoo Finance、investing.com股價資料 python抓取資料最輕鬆的兩大方法

 

(3) 定義框架

# 建立模組指標函數
def I_Singal(value): # 使外部指標可以方便在init裡面套用 
    return value


class STRATEGY(Strategy):   

    def init(self):
        super().init()
        # 顯示指標
        self.sma5 = self.I(I_Singal, self.data.sma5) # 為了顯示指標
        self.sma20 = self.I(I_Singal, self.data.sma20)

        
    def next(self):
        super().next()
        
        if not self.position and (self.data.sma5 > self.data.sma20):
            self.buy(size=1000) # 買1000單位 不填表示用金額去買
            
            
        elif self.position.is_long and (self.data.sma5 < self.data.sma20):
            self.position.close()

整個套件最重要的部份,這邊要定義我的們策略。你可以看到class後面可以取記字的策略名稱而後繼承backtesting中的Strategy物件。

這邊一定要注意,你的資料也就是前面定義的df一定要有Open High Low Close Volume。

而整個策略架構會分成兩部份:

1.init(self)主要用來初始化一些東西,把你的指標畫上去啊,定義訊號等等。self.I(I_Singal, self.data.sma5)等等把均線畫在圖上。

2.next(self)這邊用來寫你的交易邏輯,這邊我們可以看到not self.position也就是手上沒部位的時候and同時self.data.sma5(我們一開始df定義的5日均線) >self.data.sma20(20日均線)我們就買進1000單位,不然self.position.is_long有部位的時候同時and (self.data.sma5 < self.data.sma20)平倉self.position.close()(這邊指用隔日開盤價平倉)。

self.buy(size=1000) 買進1000單位 backtesting支援很多種寫法,像是目前資產的多少比例去買等等。(有興趣留言給我再寫一篇拉!)

ps:這邊的self.data.sma5還是self.data.等等就是我們df裡面的欄位資料。

 

(4) 建立策略及輸出策略

# 建立策略模組
bt = Backtest(df, STRATEGY, cash=1000000)

# 輸出策略
output = bt.run()

df為我們策略要使用的資料,STRATEGY放上你剛剛定義的策略物件,cash為初始金額。

 

(5) 視覺化策略

# 繪圖
# =============================================================================
# relative_equity 權益及報酬 True百分比表示 False金額表示
# plot_equity 顯示權益曲線
# plot_return 顯示報酬率
# plot_volume 顯示量
# superimpose 顯示月k在背景
# =============================================================================
bt.plot(relative_equity=False, plot_equity=True, plot_return=True, plot_volume=False, superimpose=True)

# relative_equity 權益及報酬 True百分比表示 False金額表示

# plot_equity 顯示權益曲線

# plot_return 顯示報酬率

# plot_volume 顯示量

# superimpose 顯示月k在背景

使用bt.plot(relative_equity=False, plot_equity=True, plot_return=True, plot_volume=False, superimpose=True)去執行,執行後如下圖,很美吧!

 

image

 

(6) 取得進出場及損益資料

# 查看模組權益曲線及進出場時間
equity = output['_equity_curve']
trades = output['_trades']

在equity可以看到權益的變化

在trades可以看到每次進出的時間點及價位天數等

 

三、完整程式碼

# pip install backtesting
import pandas, numpy
import datetime
from backtesting import Backtest, Strategy
from backtesting.lib import SignalStrategy
from backtesting import set_bokeh_output
set_bokeh_output(notebook=False)
import investpy


# 下載股價資料
df = investpy.get_stock_historical_data(stock='2330',
                                        country='Taiwan',
                                        from_date='01/01/2010',
                                        to_date='10/07/2021',)

# 資料預處理
df.index = pandas.to_datetime(df.index)

# 指標計算
df['sma5'] = df['Close'].rolling(5).mean()
df['sma20'] = df['Close'].rolling(20).mean() 

# 建立模組指標函數
def I_Singal(value): # 使外部指標可以方便在init裡面套用 
    return value


class STRATEGY(Strategy):   

    def init(self):
        super().init()
        # 顯示指標
        self.sma5 = self.I(I_Singal, self.data.sma5) # 為了顯示指標
        self.sma20 = self.I(I_Singal, self.data.sma20)

        
    def next(self):
        super().next()
        
        if not self.position and (self.data.sma5 > self.data.sma20):
            self.buy(size=1000) # 買1000單位 不填表示用金額去買
            
            
        elif self.position.is_long and (self.data.sma5 < self.data.sma20):
            self.position.close()



# 建立策略模組
bt = Backtest(df, STRATEGY, cash=1000000)

# 輸出策略
output = bt.run()

# 繪圖
# =============================================================================
# relative_equity 權益及報酬 True百分比表示 False金額表示
# plot_equity 顯示權益曲線
# plot_return 顯示報酬率
# plot_volume 顯示量
# superimpose 顯示月k在背景
# =============================================================================
bt.plot(relative_equity=False, plot_equity=True, plot_return=True, plot_volume=False, superimpose=True)

# 查看模組權益曲線及進出場時間
equity = output['_equity_curve']
trades = output['_trades']

 

四、後記

是不是看起來酷酷的呢!之後想看更多backtesting教學或是各種用法可以留言給我唷!

 

arrow
arrow

    恩哥Python 發表在 痞客邦 留言(0) 人氣()