在面向對象編程中,當然在 Python 本身中,現有類的擴展可以通過兩種方式實現。
繼承(或子類化)
組合(或嵌入)
在開髮指標中,僅用幾行代碼開發了指標Trix
。 ChartSchool - Trix參考文獻有一個帶有信號線的Trix
,顯示與 MACD 的相似性。
讓我們使用已經開發的Trix
“組合” MyTrixSignal
class MyTrixSignalComposed(bt.Indicator): lines = ('trix', 'signal') params = (('period', 15), ('sigperiod', 9)) def __init__(self): self.lines.trix = MyTrix(self.data, period=self.p.period) self.lines.signal = btind.EMA(self.lines.trix, period=self.p.sigperiod)
有些東西必須在定義中重複,例如trix
線的名稱和用於計算的period
。已定義新的線路signal
和相應的sigperiod
參數。
2-liner是一個很好的結果。
現在讓我們開始繼承,但首先回顧一下Trix
的樣子:
class MyTrix(bt.Indicator): lines = ('trix',) params = (('period', 15),) def __init__(self): ema1 = btind.EMA(self.data, period=self.p.period) ema2 = btind.EMA(ema1, period=self.p.period) ema3 = btind.EMA(ema2, period=self.p.period) self.lines.trix = 100.0 * (ema3 - ema3(-1)) / ema3(-1)
使用Trix
作為基類,這是TrixSignal
的方面
class MyTrixSignalInherited(MyTrix): lines = ('signal',) params = (('sigperiod', 9),) def __init__(self): super(MyTrixSignalInherited, self).__init__() self.lines.signal = btind.EMA(self.lines.trix, period=self.p.sigperiod)
繼承的指標最終也是一個 2 線,但是:
無需重新定義
trix
線不需要重新定義
period
參數
兩者都繼承自基類Trix
。並且trix
線的計算是在基類的__init__
方法中完成的:
- 超級(MyTrixSignalInherited,自我)。初始化()
組合與繼承的選擇是一個經典。這個例子並不是為了澄清哪個更好,而是更多地表明:
筆記
即使存在線和參數的元定義,繼承也有效,它們也繼承自基類的元定義
最後是兩個版本的代碼和圖表在付諸實施時。
- 第一個顯示繼承的版本
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import backtrader.feeds as btfeeds from mytrix import MyTrixSignalInherited class NoStrategy(bt.Strategy): params = (('trixperiod', 15), ('analyzer', False),) def __init__(self): MyTrixSignalInherited(self.data, period=self.p.trixperiod) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(NoStrategy, trixperiod=15) # Create a Data Feed datapath = ('../datas/2006-day-001.txt') data = bt.feeds.BacktraderCSVData(dataname=datapath) # Add the Data Feed to Cerebro cerebro.adddata(data) # Run over everything cerebro.run() # Plot the result cerebro.plot()
- 第一個顯示組合版本
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import backtrader.feeds as btfeeds from mytrix import MyTrixSignalComposed class NoStrategy(bt.Strategy): params = (('trixperiod', 15), ('analyzer', False),) def __init__(self): MyTrixSignalComposed(self.data, period=self.p.trixperiod) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(NoStrategy, trixperiod=15) # Create a Data Feed datapath = ('../datas/2006-day-001.txt') data = bt.feeds.BacktraderCSVData(dataname=datapath) # Add the Data Feed to Cerebro cerebro.adddata(data) # Run over everything cerebro.run() # Plot the result cerebro.plot()