本文主要來自于官方文檔的翻譯,添加一些筆者在實踐中的了解,來記錄backtrader中的一些基本概念。
Data Feeds
backtrader(以下簡稱bt)進行回測或者交易需要有曆史或者實時的資料源,這些資料源包括典型的開盤價、最高價、最低價、收盤價、成交量等等,也可以是使用者自定義的名額、買賣信号等。Data Feeds就扮演着這個資料源的角色,需要使用者提供給bt。使用者通過以下方式将Data Feeds添加到bt内:
cerebro = bt.Cerebro() # 定義cerebro
...
data = btfeeds.MyFeed(...) # 定義Data Feeds
cerebro.adddata(data) # 添加Data Feeds
...
cerebro.addstrategy(MyStrategy, period=30) # 添加Strategy,在Strategy就可以通路Data Feeds
...
bt中主要靠Strategy來完成回測和交易,當Data Feeds通過上面代碼的方式被添加到bt後,就可以在Strategy中通路這些資料了,示例如下:
class MyStrategy(bt.Strategy):
params = dict(period=20)
def __init__(self):
sma = btind.SimpleMovingAverage(self.datas[0], period=self.params.period)
...
其中,self.datas就是對Data Feeds的通路。在Strategy中,Data Feeds被指派給self.datas這一成員變量,并以數組array的形式存在,數組中的每個元素代表1組資料,例如self.datas[0]表示第1隻股票的資料,self.datas[1]表示第2隻股票的資料,依次類推。
此外,Data Feeds會按照添加bt的順序做順序存儲。
Data Feeds的快捷通路方式
self.datas數組有以下快捷通路的方式:
- self.data對應self.datas[0]
- self.dataX對應self.datas[X],其中X是0,1, 2,3 。。。
使用快捷方式self.data通路第1個 Data Feeds的示例如下:
class MyStrategy(bt.Strategy):
params = dict(period=20)
def __init__(self):
sma = btind.SimpleMovingAverage(self.data, period=self.params.period)
...
示例中,使用第1個Data Feeds來計算均線值。
省略Data Feeds
上面的代碼示例可以做進一步簡化:
class MyStrategy(bt.Strategy):
params = dict(period=20)
def __init__(self):
sma = btind.SimpleMovingAverage(period=self.params.period)
...
這裡在調用SimpleMovingAverage計算均線值時,把參數self.data也省略了。在這種情況下,預設會使用第1個Data Feeds(即self.data,self.datas0,self.datas[0])來計算名額資料。
其他可以被當作Data Feeds的對象
在Strategy中,名額(Indicators)和運算符(Operations)計算結果都可以像Data Feeds一樣,被用來當作data計算名額資料(如上面計算SimpleMovingAverage的例子),示例如下(解釋請見代碼中的注釋):
class MyStrategy(bt.Strategy):
params = dict(period1=20, period2=25, period3=10, period4)
def __init__(self):
# 在計算SimpleMovingAverage時,使用self.datas[0]作為data
sma1 = btind.SimpleMovingAverage(self.datas[0], period=self.p.period1)
# 在計算SimpleMovingAverage時, 使用sma1(Indicators)作為data
sma2 = btind.SimpleMovingAverage(sma1, period=self.p.period2)
# 通過運算符(Operations)計算來建立新的data
something = sma2 - sma1 + self.data.close
# 在計算SimpleMovingAverage時, 使用something(Operations結果)作為data
sma3 = btind.SimpleMovingAverage(something, period=self.p.period3)
# 使用比較運算符(Operations)建立新的data
greater = sma3 > sma1
# 在計算SimpleMovingAverage時, 使用greater(Operations結果)作為data
sma3 = btind.SimpleMovingAverage(greater, period=self.p.period4)
...
通過示例可以看出,Data Feeds, Indicators,Operations結果都可以被用過data傳遞給Strategy中,來計算新的名額。
參數Parameters
bt支援使用元組的元組或者類字典對象來定義參數Parameters,參數被定義為類的成員變量,可以使用self.params或者self.p來進行通路,使用元組形式的示例如下:
class MyStrategy(bt.Strategy):
params = (('period', 20),)
def __init__(self):
sma = btind.SimpleMovingAverage(self.data, period=self.p.period)
使用字典形式的示例如下:
class MyStrategy(bt.Strategy):
params = dict(period=20)
def __init__(self):
sma = btind.SimpleMovingAverage(self.data, period=self.p.period)
bt采用這種方式定義參數,是為了後續在添加政策時修改參數,或者對參數進行優化(調參)做準備。
歡迎大家關注、點贊、轉發、留言,感謝支援!
微信群用于學習交流,感興趣的讀者請掃碼加微信!
QQ群(676186743)用于資料共享,歡迎加入!
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csATRU1keBpmTyEleYdHMywEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PnBnaugDOwEDO0IjM0AzNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)