第一次接觸Python,朋友帶着玩,發現官方文檔寫得好棒(https://www.backtrader.com/docu/),以下内容來自于官方文檔,以及我自己的學習心得。
資料結構:
資料格式:必須有6列(日期時間,開盤,收盤,最高,最低,持倉量?)
用lines存儲:很多line組成的list 數組類型(?)。
dataFeed:本地讀入csv或者txt檔案用 bt.feeds.GenericCSVData 類,該類可以重載源資料每列的屬性,從0開始。本來之前按照官方文檔用的Yahoo那個類,調試半天資料都對不上,後來才發現是 因為Yahoo類定義的列屬性順序不可調,例子裡用的源檔案順序又不完全是按照Yahoo類定義的排列,導緻除了收盤價,其他的資料都對不上号。
資料通路的方法有很多種,對于源資料而言,一旦讀入data.lines,在資料源類執行個體中的資料就不會改變了,實際改變的會是名額裡的資料。以下通路方式都是等價的:
if self.movav.lines.sma[0] > self.data.lines.close[0]:
print(self.data_close[0]) # 等價于self.data.close[0],self.data.lines.close[0],self.data0[0],self.data.lines[0][0]
print(self.data.close[0]) # 此類等價僅支援資料源,名額不支援
print(self.movav.sma[0]) # self.movav.sma等價于self.movav.lines[0],self.movav.line0,self.movav.line_0
官方還有更詳細的說明,通過這個說明,才真的有點明白怎麼通路實際資料。
對于每個名額的類,在類定義時需要定義lines的值,比如對于SMA類,最開始會定義lines的屬性值為sma,此時通過self.mov.sma[0],就可以取到最新的一個平均值了。所有名額的傳回都是存在List中的,我了解就是數組中,是以單單通過self.mov.sma實際上得到的是一個指針位址。
Line的操作:
BT平台不支援List的Slice!! 因為平台的資料源将0認為是最新的資料,-1是前一個資料。這個與Python預設的定義不一樣,是以不支援slice函數。平台通過 get函數,取得list中的指定資料段:注意取出來的資料順序,是從舊到新的順序。我測試了下,也可以用append來指派,哈哈,笨方法。
first_t = t.get(size = (periods)) # t.get(ago = 0,size = periods):從目前資料開始取前periods個資料,如果周期是10,則取即0~-9,注意順序
first_t2 = t.get(ago =-1,size=(periods))#從第二新的資料開始取,一共periods個資料
for li in range(-1*(periods),0):
# print(li,t.lines[0][li])
first_t.append(t.lines[0][li])
政策中的__init__: 僅定義名額,參數,不會實際加載任何資料。但是如果定義了k線數值,即period,則系統會統計,必須滿足所有名額的k線量達成後,會進入next進行實際計算。比如5日均線,與10日ATR,init中會數到10個bar(K線)後才會進入next 加載資料,并計算5日SMA和10日ATR。
next:執行真正的資料加載,以及名額計算。