Last,但並非最不重要的一點是,在這個系列中,關於如何在 backtrader 中使用Python的隱藏功能是一些神奇變數是如何出現的。
self.datas其他人從哪裡來?
通常的可疑類(或其子類)StrategyIndicator, 、 Analyzer、 Observer 具有自動魔法定義的屬性,例如包含 data feeds的陣列。
Data Feeds 將添加到實例中cerebro ,如下所示:
from datetime import datetime import backtrader as bt cerebro = bt.Cerebro() data = bt.YahooFinanceData(dataname=my_ticker, fromdate=datetime(2016, 1, 1)) cerebro.adddata(data) ...
當高於簡單移動平均線時,我們對示例的close 獲勝策略將持續很長時間。我們將使用信號來縮短範例:
class MyStrategy(bt.SignalStrategy):
params = (('period', 30),)
def __init__(self):
mysig = self.data.close > bt.indicators.SMA(period=self.p.period)
self.signal_add(bt.signal.SIGNAL_LONG, mysig)
它被新增到混合中:
cerebro.addstrategy(MyStrategy)
任何讀者都會注意到:
-
__init__不帶參數,無論是否命名 -
沒有
super調用,因此不會直接要求基類執行其 init -
引用的
self.data定義mysig可能與YahooFinanceData添加到cerebro確實如此!
實際上還有其他屬性,這些屬性在那裡,在示例中看不到。例如:
-
self.datas:包含添加到的所有 data feeds 的陣列cerebro -
self.dataX:其中X是一個數位,它反映了數據添加到 cerebro 的順序(data0將是上面添加的數據) -
self.data:指向self.data0。為了方便起見,這隻是一個佇列,因為大多數示例和策略僅針對單個數據
可以在文件中找到更多內容:
如何創建這些屬性?
在本系列的第 2 篇文章中,發現類創建機制和實例創建機制被截獲。後者用於執行此操作。
-
cerebro通過以下方式接收類adstrategy -
它將在需要時實例化它,並將自身添加為屬性
-
策略
new的類方法在創建Strategy實例期間被截獲,並檢查哪些 data feeds 在cerebro它確實創建了上面提到的陣列和別名
此機制應用於 backtrader 生態系統中的許多其他物件,以便簡化最終使用者必須執行的操作。因此:
-
例如,無需不斷創建包含命名
datas參數的函數原型,也無需將其分配給self.datas因為它是在後台自動神奇地完成的
這種攔截的另一個例子
讓我們定義一個獲勝指標,並將其添加到獲勝策略中。我們將重新包裝 close SMA的想法:
class MyIndicator(bt.Indicator):
params = (('period', 30),)
lines = ('signal',)
def __init__(self):
self.lines.signal = self.data - bt.indicators.SMA
現在將其添加到常規策略中:
class MyStrategy(bt.Strategy):
params = (('period', 30),)
def __init__(self):
self.mysig = MyIndicator(period=self.p.period)
def next(self):
if self.mysig:
pass # do something like buy ...
從上面的代碼中,顯然有一個計算正在進行MyIndicator:
self.lines.signal = self.data - bt.indicators.SMA
但它似乎無處可做。如本系列的第 1 篇文章所示,該操作會生成一個物件,該物件被 self.lines.signal 分配給併發生以下情況:
-
此物件還會截獲其創建過程
-
它掃描堆疊以瞭解正在創建的上下文,在本例中為
MyIndicators -
在初始化完成後,它會將自己添加到
MyIndicator -
稍後在計算時
MyIndicator,它將依次計算由self.lines.signal
不錯,但誰計算MyIndicator
遵循完全相同的過程:
-
MyIndicator在創建過程中掃描堆疊並找到MyStrategy -
並將自己添加到結構中
MyStrategy -
在調用之前
next,MyIndicator被要求重新計算自身,這反過來又告訴self.lines.signal重新計算自己
該過程可以具有多層間接尋址。
對用戶來說最好的事情:
-
無需像創建某些內容時那樣
register_operation添加調用 -
無需手動觸發計算
總結
本系列中 last 文章展示了如何使用類/實例創建攔截來簡化最終使用者生活的另一個示例::
-
從生態系統中添加需要的物件並創建別名
-
自動註冊類和觸發計算