在最近的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)
這裡的問題應該是顯而易見的:“人們需要一個指標的輸入,lowhigh其中的特徵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 的指標轉換為接受多個通用輸入的指標。