指標可以在平台的兩個地方使用:
內部策略
其他指標內部
指標在行動
指標總是在策略中的
__init__
期間實例化next
使用/檢查指標值(或其派生值)
有一個重要的公理需要考慮:
- 在
__init__
期間聲明的任何Indicator
(或其派生值)都將在調用next
之前預先計算。
讓我們來看看操作模式的差異。
__init__
與next
事情如下:
在
__init__
期間任何涉及線對象的操作都會生成另一個線對象在
next
期間任何涉及行對象的操作都會產生常規的 Python 類型,例如浮點數和布爾值。
在__init__
期間
__init__
期間的操作示例:
hilo_diff = self.data.high - self.data.low
變量hilo_diff
包含對lines對象的引用,該對像在調用next
之前預先計算,可以使用標準數組表示法[]
訪問
它顯然包含數據饋送的每個條形圖的最高價和最低價之間的差異。
這也適用於混合簡單的線條(如 self.data數據饋送中的那些)和復雜的線條如指標:
sma = bt.SimpleMovingAverage(self.data.close) close_sma_diff = self.data.close - sma
現在close_sma_diff
再次包含一個線對象。
使用邏輯運算符:
close_over_sma = self.data.close > sma
現在生成的lines對象將包含一個布爾數組。
next
期間
操作示例(邏輯運算符):
close_over_sma = self.data.close > self.sma
使用等效數組(基於索引 0 的符號):
close_over_sma = self.data.close[0] > self.sma[0]
在這種情況下, close_over_sma
產生一個布爾值,它是比較兩個浮點值的結果,由[0]
運算符返回的值應用於self.data. close
和self.sma
__init__
與next
為什麼
邏輯簡化(以及易用性)是關鍵。計算和大部分相關邏輯可以在__init__
期間聲明,在next
期間將實際操作邏輯保持在最低限度。
實際上還有一個附帶的好處:速度(由於開頭解釋的預先計算)
在__init__
期間生成買入信號的完整示例:
class MyStrategy(bt.Strategy): def __init__(self): sma1 = btind.SimpleMovingAverage(self.data) ema1 = btind.ExponentialMovingAverage() close_over_sma = self.data.close > sma1 close_over_ema = self.data.close > ema1 sma_ema_diff = sma1 - ema1 buy_sig = bt.And(close_over_sma, close_over_ema, sma_ema_diff > 0) def next(self): if buy_sig: self.buy()
筆記
Python 的and
運算符不能被覆蓋,迫使平台定義自己的And
。這同樣適用於其他結構,如Or
和If
很明顯, __init__
期間的“聲明式”方法將next
(實際策略工作發生的地方)的膨脹降至最低。
(別忘了還有一個加速因素)
筆記
當邏輯變得非常複雜並涉及多個操作時,通常將其封裝在Indicator
中會更好。
一些筆記
在上面的示例中,與其他平台相比, backtrader
簡化了兩件事:
聲明的
Indicators
既沒有獲得父參數(如創建它們的策略,也沒有調用任何類型的“註冊”方法/函數。儘管如此,該策略將啟動
Indicators
的計算以及由於操作生成的任何線對象(如sma - ema
)ExponentialMovingAverage
在沒有self.data
的情況下被實例化這是故意的。如果沒有
data
傳遞,則父級的第一個數據(在這種情況下是正在創建的策略)將在後台自動傳遞
指標繪圖
首先也是最重要的:
聲明的
Indicators
會自動繪製(如果調用cerebro .plot)操作中的線條對像不會被繪製(如
close_over_sma = self.data. close > self.sma
)如果需要,有一個輔助
LinePlotterIndicator
可以使用以下方法繪製此類操作:close_over_sma = self.data.close > self.sma LinePlotterIndicator(close_over_sma, name='Close_over_SMA')
name
參數為該指標持有的單行提供名稱。
控制繪圖
在開髮Indicator
期間,可以添加plotinfo
聲明。它可以是元組的元組(2 個元素)、 dict
或OrderedDict
。看起來像:
class MyIndicator(bt.Indicator): .... plotinfo = dict(subplot=False) ....
稍後可以按如下方式訪問(和設置)該值(如果需要):
myind = MyIndicator(self.data, someparam=value) myind.plotinfo.subplot = True
該值甚至可以在實例化期間設置:
myind = MyIndicator(self.data, someparams=value, subplot=True)
subplot= True
將傳遞給指標的(在幕後)實例化成員變量plotinfo
。
plotinfo
提供以下參數來控制繪圖行為:
plot
(默認值:True
)是否要繪製指標
subplot
(默認值:True
)是否在不同的窗口中繪製指標。對於移動平均線等指標,默認值更改為
False
plotname
(默認值:''
)設置要在繪圖上顯示的繪圖名稱。空值意味著將使用指標的規範名稱 (
class.__name__
)。這有一些限制,因為 Python 標識符不能使用例如算術運算符。像 DI+ 這樣的指標將聲明如下:
class DIPlus(bt.Indicator): plotinfo=dict(plotname='DI+')
讓劇情“更精彩”
plotabove
(默認值:False
)指標通常繪製在他們操作的數據下方(那些
subplot= True
)。將此設置為True
將使指標繪製在數據上方。plotlinelabels
(默認值:False
)用於“指標”上的“指標”。如果計算 RSI 的 SimpleMovingAverage,繪圖通常會顯示相應繪製線的名稱“SimpleMovingAverage”。這是“指標”的名稱,而不是實際繪製的線。
這種默認行為是有意義的,因為用戶通常希望看到使用 RSI 創建了 SimpleMovingAverage。
如果該值設置為
True
,則將使用 SimpleMovingAverage中行的實際名稱。plotymargin
(默認值:0.0
)在指標頂部和底部留下的保證金量 (
0.15
-> 15%)。有時matplotlib
繪圖離軸的頂部/底部太遠,可能希望留出餘量plotyticks
(默認值:[]
)用於控制繪製的 y 刻度刻度
如果傳遞了一個空列表,則會自動計算“y ticks”。對於像隨機指標這樣的東西,將其設置為眾所周知的行業標準可能是有意義的,例如:
[20.0, 50.0, 80.0]
一些指標提供了實際用於操縱 y 刻度的參數,例如
upperband
和lowerband
plothlines
(默認值:[]
)用於控制沿指標軸繪製水平線。
如果傳遞一個空列表,則不會繪製水平線。
對於像隨機指標這樣的東西,為眾所周知的行業標準畫線可能是有意義的,例如:
[20.0, 80.0]
一些指標提供實際用於操縱水平線的參數,
upperband
和lowerband
plotyhlines
(默認值:[]
)用於使用單個參數同時控制 plotyticks 和 plothlines。
plotforce
(默認值:False
)如果由於某種原因您認為某個指標應該在繪圖而它沒有在繪圖……作為最後的手段,將其設置為
True
。