在最近的Canonical vs Non-Canonical 帖子中 MFI
,開發了(aka MoneyFlowIndicator
)。
儘管它是以規範的方式開發的,但它仍然提供了一些改進和成為通用的空間。
讓我們關注實現的第一lines,即創建典型價格的那些
class MFI_Canonical(bt.Indicator): lines = ('mfi',) params = dict(period=14) def __init__(self): tprice = (self.data.close + self.data.low + self.data.high) / 3.0 mfraw = tprice * self.data.volume ...
典型的實例化如下所示
class MyMFIStrategy(bt.Strategy): def __init__(self): mfi = bt.MFI_Canonical(self.data)
這裡的問題應該是顯而易見的:“人們需要一個指標的輸入,low
high
其中的特徵close
和volume
元件(又名*lines在backtrader生態系統中)”*
當然,可能的情況是,人們希望從不同的數據源(lines來自data feeds或來自其他指標lines)創建一MoneyFlowIndicator
個使用元件,就像想要賦予close
更多的權重一樣簡單,而不必開發一個特定的指標。考慮到行業標準OHLCV
的欄位排序,多個輸入,額外的權重,close
實例化可能看起來像這樣
class MyMFIStrategy2(bt.Strategy): def __init__(self): wclose = self.data.close * 5.0 mfi = bt.MFI_Canonical(self.data.high, self.data.low, wclose, self.data.volume)
或者因為使用者以前使用ta-lib
過並幻想過多輸入樣式。
支援多種輸入
backtrader 嘗試盡可能的pythonic,self.datas
並且可以查詢包含系統中 data feeds 清單的數位(並且自動神奇地提供給您的策略)的長度。讓我們用它來區分調用方想要什麼,並正確計算 tprice
和 mfraw
class MFI_MultipleInputs(bt.Indicator): lines = ('mfi',) params = dict(period=14) def __init__(self): if len(self.datas) == 1: # 1 data feed passed, must have components tprice = (self.data.close + self.data.low + self.data.high) / 3.0 mfraw = tprice * self.data.volume else: # if more than 1 data feed, individual components in OHLCV order tprice = (self.data0 + self.data1 + self.data2) / 3.0 mfraw = tprice * self.data3 # No changes with regards to previous implementation flowpos = bt.ind.SumN(mfraw * (tprice > tprice(-1)), period=self.p.period) flowneg = bt.ind.SumN(mfraw * (tprice < tprice(-1)), period=self.p.period) mfiratio = bt.ind.DivByZero(flowpos, flowneg, zero=100.0) self.l.mfi = 100.0 - 100.0 / (1.0 + mfiratio)
注意
請注意各個元件的參考方式(self.dataX
如 self.data0
、 self.data1
)
這與使用self.datas[x]
相同,如 self.datas[0]
...
讓我們以圖形方式看到,此指標產生的結果與規範指標相同,當多個輸入對應於 data feed的原始分量時,產生相同的結果。為此,它將在策略中運行,如下所示
class MyMFIStrategy2(bt.Strategy): def __init__(self): MFI_Canonical(self.data) MFI_MultipleInputs(self.data, plotname='MFI Single Input') MFI_MultipleInputs(self.data.high, self.data.low, self.data.close, self.data.volume, plotname='MFI Multiple Inputs')
無需檢查每個值,從圖片中可以明顯看出,三者的結果相同。
讓我們最終看看如果把更多的權重放在上面close
會發生什麼。讓我們這樣運行。
class MyMFIStrategy2(bt.Strategy): def __init__(self): MFI_MultipleInputs(self.data) MFI_MultipleInputs(self.data.high, self.data.low, self.data.close * 5.0, self.data.volume, plotname='MFI Close * 5.0')
這是否有意義留給讀者,但人們可以清楚地看到,增加重量close
已經改變了模式。
結論
通過簡單地使用pythoniclen
,可以將使用具有多個元件(和固定名稱)的 data feed 的指標轉換為接受多個通用輸入的指標。