即使 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和ADXRlines。
$ ./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()