天天看點

Python量化交易學習筆記(22)——自定義Indicator

想要将深度學習算法應用于回測過程中,通過查閱資料,發現需要實作自定義技術名額(Indicator)。本文先實作一個簡單的自定義名額,為後續深度學習的應用做個鋪墊。

本文示例政策的買入條件為均線(選取10日線)向上,收陰線,且收盤價在均線上方。賣出條件為筆記(二十)中闡述的保護點賣出政策。

回測初始資金100000元,單筆操作機關1000股,傭金千分之一,回測時間自2018年1月1日至2020年3月20日。

自定義名額代碼如下:

class NegativeIndicator(bt.Indicator):
    lines = ('buy_sig',)
    params = (('ma_period', 10), ('up_period', 3))
    def __init__(self):
        self.addminperiod(self.p.ma_period)
        ma = bt.ind.SMA(period = self.p.ma_period, plot = True)
        # 買入條件
        # 收陰線
        self.l.buy_sig = bt.And(self.data.close < self.data.open,
        # 收在均線上方
        self.data.close > ma,
        # 均線向上
        ma == bt.ind.Highest(ma, period = self.p.up_period)
        )
           

這裡的自定義名額繼承于backtrader的Indicator類,類内包含一個名為buy_sig的lines對象。參數ma_period用于控制選擇哪條均線,up_period用于控制判斷均線向上的周期。

要注意的是在__init__方法裡所用到的名額都是lines對象,是一系列數值的組合。如果名額的計算挪到next方法裡,那麼要在名額後加上下标[0]來計算,這是由于next方法裡的名額應為單個的數值。

政策類也相對簡單,主要是在__init__方法中引入自定義的名額:

def __init__(self):
        # 買入條件
        self.buy_sig = NegativeIndicator().buy_sig
        # 為了在最後圖表中顯示均線
        bt.ind.SMA(period = NegativeIndicator().p.ma_period)
        self.order = None
           

回測000001後的最終資産為101893.73元。

Python量化交易學習筆記(22)——自定義Indicator

回測000002後的最終資産為98094.33元。

Python量化交易學習筆記(22)——自定義Indicator

回測601318後的最終資産為87259.10元。

Python量化交易學習筆記(22)——自定義Indicator

友情提示:本系列學習筆記隻做資料分析,記錄個人學習過程,不作為交易依據,盈虧自負。

自定義Indicator代碼:

from __future__ import (absolute_import, division, print_function, unicode_literals)
import datetime  # 用于datetime對象操作
import os.path  # 用于管理路徑
import sys  # 用于在argvTo[0]中找到腳本名稱
import backtrader as bt # 引入backtrader架構

# 自定義名額
class NegativeIndicator(bt.Indicator):
    lines = ('buy_sig',)
    params = (('ma_period', 10), ('up_period', 3))
    def __init__(self):
        self.addminperiod(self.p.ma_period)
        ma = bt.ind.SMA(period = self.p.ma_period, plot = True)
        # 買入條件
        # 收陰線
        self.l.buy_sig = bt.And(self.data.close < self.data.open,
        # 收在均線上方
        self.data.close > ma,
        # 均線向上
        ma == bt.ind.Highest(ma, period = self.p.up_period)
        )

# 建立政策
class St(bt.Strategy):
    params = dict(
        stoptype=bt.Order.StopTrail,
        trailamount=0.0,
        trailpercent=0.05,
    )
    def __init__(self):
        # 買入條件
        self.buy_sig = NegativeIndicator().buy_sig
        # 為了在最後圖表中顯示均線
        bt.ind.SMA(period = NegativeIndicator().p.ma_period)
        self.order = None
    def notify_order(self, order):
        if order.status in [order.Completed, order.Expired]:
            self.order = None
    def next(self):
        # 無場内資産
        if not self.position:
            # 未送出買單
            if None == self.order:
                # 到達了買入條件
                if self.buy_sig:
                    self.order = self.buy()
        elif self.order is None:
            # 送出stoptrail訂單
            self.order = self.sell(exectype=self.p.stoptype,
                                   trailamount=self.p.trailamount,
                                   trailpercent=self.p.trailpercent)

cerebro = bt.Cerebro()  # 建立cerebro
# 先找到腳本的位置,然後根據腳本與資料的相對路徑關系找到資料位置
# 這樣腳本從任意地方被調用,都可以正确地通路到資料
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
datapath = os.path.join(modpath, '../TQDat/day/stk/000001.csv')
# 建立價格資料
data = bt.feeds.GenericCSVData(
        dataname = datapath,
        fromdate = datetime.datetime(2018, 1, 1),
        todate = datetime.datetime(2020, 3, 31),
        nullvalue = 0.0,
        dtformat = ('%Y-%m-%d'),
        datetime = 0,
        open = 1,
        high = 2,
        low = 3,
        close = 4,
        volume = 5,
        openinterest = -1
        )
# 在Cerebro中添加價格資料
cerebro.adddata(data)
# 設定啟動資金
cerebro.broker.setcash(100000.0)
# 設定交易機關大小
cerebro.addsizer(bt.sizers.FixedSize, stake = 1000)
# 設定傭金為千分之一
cerebro.broker.setcommission(commission=0.001)
cerebro.addstrategy(St)  # 添加政策
cerebro.run()  # 周遊所有資料
# 列印最後結果
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.plot(style = 'candlestick')  # 繪圖
           

為了便于互相交流學習,建立了微信群,感興趣的讀者請加微信。

Python量化交易學習筆記(22)——自定義Indicator