即使 backtrader 提供了已經 high 數量的內置指標,並且開發指標主要是定義輸入,輸出和以自然的方式編寫公式的問題,有些人也希望使用TA-LIB。一些原因:
-
指標 X 在庫中,而不是在 backtrader 中(作者很樂意接受請求)
-
TA-LIB的行為是眾所周知的,人們相信好的舊事物
為了滿足每一種口味,TA-LIB集成提供了。
要求
-
Python wrapper for TA-Lib
-
它需要的任何依賴項(例如 numpy)
安裝詳細信息位於 GitHub 儲存庫中
使用 ta-lib
就像使用 backtrader中內置的任何指標一樣簡單。簡單移動平均線示例。首先是 backtrader 一個:
import backtrader as bt class MyStrategy(bt.Strategy): params = (('period', 20),) def __init__(self): self.sma = bt.indicators.SMA(self.data, period=self.p.period) ... ...
現在以 ta-lib 為例:
import backtrader as bt class MyStrategy(bt.Strategy): params = (('period', 20),) def __init__(self): self.sma = bt.talib.SMA(self.data, timeperiod=self.p.period) ... ...
Et voilá!當然,ta-lib 指標的參數是由庫本身定義的,而不是由 backtrader定義的。在這種情況下,ta-lib 中的 SMA 採用一個名為定義timeperiod
操作視窗大小的參數。
對於需要多個輸入的指標,例如隨機指標:
import backtrader as bt class MyStrategy(bt.Strategy): params = (('period', 20),) def __init__(self): self.stoc = bt.talib.STOCH(self.data.high, self.data.low, self.data.close, fastk_period=14, slowk_period=3, slowd_period=3) ... ...
注意如何high
, low
並且 close
已經單獨通過。人們總是 open
可以通過而不是 low
(或任何其他數據系列)並進行實驗。
ta-lib 指標文檔會自動解析並添加到 backtrader 文檔中。您也可以查看 ta-lib 原始程式碼/文件。或者兼職做:
print(bt.talib.SMA.__doc__)
在這種情況下,輸出:
SMA([input_arrays], [timeperiod=30]) Simple Moving Average (Overlap Studies) Inputs: price: (any ndarray) Parameters: timeperiod: 30 Outputs: real
它提供了一些資訊:
-
哪個輸入是預期的(忽略“ndarray”註釋,因為 backtrader 在後台管理轉換)
-
哪些參數和哪些預設值
-
指標實際提供 lines 輸出
移動平均線和MA_Type
要為指標選擇特定的移動平均線,例如bt.talib.STOCH
,可以使用 標準 ta-lib MA_Type
訪問 backtrader.talib.MA_Type
。例如:
import backtrader as bt print('SMA:', bt.talib.MA_Type.SMA) print('T3:', bt.talib.MA_Type.T3)
繪製 ta-lib 指標
就像常規用法一樣,繪製ta-lib指標也沒什麼特別的。
注意
輸出蠟燭的指標(所有尋找燭台模式的指標)提供二進位輸出:0 或 100。為了避免向圖表添加 asubplot
,有一個自動繪製轉換,以在識別模式的時間點將它們繪製在數據上。
示例和比較
以下是將一些 ta-lib 指標的輸出與 backtrader中等效的內置指標進行比較的圖。要考慮:
-
ta-lib 指標在圖上獲取
TA_
前綴。這是由示例專門完成的,以説明用戶發現哪個是 -
移動平均線(如果兩者都提供相同的結果)將繪製在其他現有移動平均線之上。這兩個指標不能分開看到,如果是這種情況,測試就是通過。
-
所有樣品都包括一個
CDLDOJI
指標作為參考
KAMA (考夫曼移動平均線)
這是第 1 個 範例,因為它是唯一一個(來自樣本直接比較的所有指標)有差異:
-
樣本的初始值不相同
-
在某個時間點,值會收斂,並且兩個 KAMA 實現具有相同的行為。
在分析了 ta-lib 原始程式碼之後:
-
ta-lib 中的實現為 KAMA 的第 1個 值提供了非行業標準選擇。
選擇可以在原始碼中引用原始程式碼中看到):昨天的價格在這裡與以前的KAMA一樣使用。
backtrader 做通常的選擇,這與例如Stockcharts中的選擇相同:
-
KAMA在股票圖表
由於我們需要一個初始值來開始計算,因此第一個KAMA只是一個簡單的移動平均線
因此,區別。此外:
- ta-lib
KAMA
實現不允許指定和slow
週期來fast
調整 Kaufman 定義的可伸縮常量。
範例執行:
$ ./talibtest.py --plot --ind kama
輸出
斷續器
$ ./talibtest.py --plot --ind sma
輸出
均線
$ ./talibtest.py --plot --ind ema
輸出
隨機
$ ./talibtest.py --plot --ind stoc
輸出
斷續器
$ ./talibtest.py --plot --ind rsi
輸出
麥克德
$ ./talibtest.py --plot --ind macd
輸出
布林帶
$ ./talibtest.py --plot --ind bollinger
輸出
阿龍
請注意,ta-lib 選擇先放下 line ,與 backtrader 內置指標相比,顏色是反轉的。
$ ./talibtest.py --plot --ind aroon
輸出
終極振蕩器
$ ./talibtest.py --plot --ind ultimate
輸出
特裡克斯
$ ./talibtest.py --plot --ind trix
輸出
斷續器
在這裡,backtrader提供ADX
和ADXR
lines。
$ ./talibtest.py --plot --ind adxr
輸出
德馬
$ ./talibtest.py --plot --ind dema
輸出
特瑪
$ ./talibtest.py --plot --ind tema
輸出
斷續器
在這裡, backtrader 不僅ppo
提供了 line,而且提供了更傳統的 macd
方法。
$ ./talibtest.py --plot --ind ppo
輸出
威廉姆斯
$ ./talibtest.py --plot --ind williamsr
輸出
大鵬
所有指標都顯示具有完全相同的形狀,但如何跟蹤動量或變化率有幾個定義
$ ./talibtest.py --plot --ind roc
輸出
示例用法
$ ./talibtest.py --help usage: talibtest.py [-h] [--data0 DATA0] [--fromdate FROMDATE] [--todate TODATE] [--ind {sma,ema,stoc,rsi,macd,bollinger,aroon,ultimate,trix,kama,adxr,dema,tema,ppo,williamsr,roc}] [--no-doji] [--use-next] [--plot [kwargs]] Sample for ta-lib optional arguments: -h, --help show this help message and exit --data0 DATA0 Data to be read in (default: ../../datas/yhoo-1996-2015.txt) --fromdate FROMDATE Starting date in YYYY-MM-DD format (default: 2005-01-01) --todate TODATE Ending date in YYYY-MM-DD format (default: 2006-12-31) --ind {sma,ema,stoc,rsi,macd,bollinger,aroon,ultimate,trix,kama,adxr,dema,tema,ppo,williamsr,roc} Which indicator pair to show together (default: sma) --no-doji Remove Doji CandleStick pattern checker (default: False) --use-next Use next (step by step) instead of once (batch) (default: False) --plot [kwargs], -p [kwargs] Plot the read data applying any kwargs passed For example (escape the quotes if needed): --plot style="candle" (to plot candles) (default: None)
示例代碼
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import datetime import backtrader as bt class TALibStrategy(bt.Strategy): params = (('ind', 'sma'), ('doji', True),) INDS = ['sma', 'ema', 'stoc', 'rsi', 'macd', 'bollinger', 'aroon', 'ultimate', 'trix', 'kama', 'adxr', 'dema', 'ppo', 'tema', 'roc', 'williamsr'] def __init__(self): if self.p.doji: bt.talib.CDLDOJI(self.data.open, self.data.high, self.data.low, self.data.close) if self.p.ind == 'sma': bt.talib.SMA(self.data.close, timeperiod=25, plotname='TA_SMA') bt.indicators.SMA(self.data, period=25) elif self.p.ind == 'ema': bt.talib.EMA(timeperiod=25, plotname='TA_SMA') bt.indicators.EMA(period=25) elif self.p.ind == 'stoc': bt.talib.STOCH(self.data.high, self.data.low, self.data.close, fastk_period=14, slowk_period=3, slowd_period=3, plotname='TA_STOCH') bt.indicators.Stochastic(self.data) elif self.p.ind == 'macd': bt.talib.MACD(self.data, plotname='TA_MACD') bt.indicators.MACD(self.data) bt.indicators.MACDHisto(self.data) elif self.p.ind == 'bollinger': bt.talib.BBANDS(self.data, timeperiod=25, plotname='TA_BBANDS') bt.indicators.BollingerBands(self.data, period=25) elif self.p.ind == 'rsi': bt.talib.RSI(self.data, plotname='TA_RSI') bt.indicators.RSI(self.data) elif self.p.ind == 'aroon': bt.talib.AROON(self.data.high, self.data.low, plotname='TA_AROON') bt.indicators.AroonIndicator(self.data) elif self.p.ind == 'ultimate': bt.talib.ULTOSC(self.data.high, self.data.low, self.data.close, plotname='TA_ULTOSC') bt.indicators.UltimateOscillator(self.data) elif self.p.ind == 'trix': bt.talib.TRIX(self.data, timeperiod=25, plotname='TA_TRIX') bt.indicators.Trix(self.data, period=25) elif self.p.ind == 'adxr': bt.talib.ADXR(self.data.high, self.data.low, self.data.close, plotname='TA_ADXR') bt.indicators.ADXR(self.data) elif self.p.ind == 'kama': bt.talib.KAMA(self.data, timeperiod=25, plotname='TA_KAMA') bt.indicators.KAMA(self.data, period=25) elif self.p.ind == 'dema': bt.talib.DEMA(self.data, timeperiod=25, plotname='TA_DEMA') bt.indicators.DEMA(self.data, period=25) elif self.p.ind == 'ppo': bt.talib.PPO(self.data, plotname='TA_PPO') bt.indicators.PPO(self.data, _movav=bt.indicators.SMA) elif self.p.ind == 'tema': bt.talib.TEMA(self.data, timeperiod=25, plotname='TA_TEMA') bt.indicators.TEMA(self.data, period=25) elif self.p.ind == 'roc': bt.talib.ROC(self.data, timeperiod=12, plotname='TA_ROC') bt.talib.ROCP(self.data, timeperiod=12, plotname='TA_ROCP') bt.talib.ROCR(self.data, timeperiod=12, plotname='TA_ROCR') bt.talib.ROCR100(self.data, timeperiod=12, plotname='TA_ROCR100') bt.indicators.ROC(self.data, period=12) bt.indicators.Momentum(self.data, period=12) bt.indicators.MomentumOscillator(self.data, period=12) elif self.p.ind == 'williamsr': bt.talib.WILLR(self.data.high, self.data.low, self.data.close, plotname='TA_WILLR') bt.indicators.WilliamsR(self.data) def runstrat(args=None): args = parse_args(args) cerebro = bt.Cerebro() dkwargs = dict() if args.fromdate: fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') dkwargs['fromdate'] = fromdate if args.todate: todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') dkwargs['todate'] = todate data0 = bt.feeds.YahooFinanceCSVData(dataname=args.data0, **dkwargs) cerebro.adddata(data0) cerebro.addstrategy(TALibStrategy, ind=args.ind, doji=not args.no_doji) cerebro.run(runcone=not args.use_next, stdstats=False) if args.plot: pkwargs = dict(style='candle') if args.plot is not True: # evals to True but is not True npkwargs = eval('dict(' + args.plot + ')') # args were passed pkwargs.update(npkwargs) cerebro.plot(**pkwargs) def parse_args(pargs=None): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Sample for sizer') parser.add_argument('--data0', required=False, default='../../datas/yhoo-1996-2015.txt', help='Data to be read in') parser.add_argument('--fromdate', required=False, default='2005-01-01', help='Starting date in YYYY-MM-DD format') parser.add_argument('--todate', required=False, default='2006-12-31', help='Ending date in YYYY-MM-DD format') parser.add_argument('--ind', required=False, action='store', default=TALibStrategy.INDS[0], choices=TALibStrategy.INDS, help=('Which indicator pair to show together')) parser.add_argument('--no-doji', required=False, action='store_true', help=('Remove Doji CandleStick pattern checker')) parser.add_argument('--use-next', required=False, action='store_true', help=('Use next (step by step) ' 'instead of once (batch)')) # Plot options parser.add_argument('--plot', '-p', nargs='?', required=False, metavar='kwargs', const=True, help=('Plot the read data applying any kwargs passed\n' '\n' 'For example (escape the quotes if needed):\n' '\n' ' --plot style="candle" (to plot candles)\n')) if pargs is not None: return parser.parse_args(pargs) return parser.parse_args() if __name__ == '__main__': runstrat()