即使 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 在后台管理转换)
-
哪些参数和哪些默认值
-
哪个outpu lines 提供指针
移动平均线和MA_Type
要为指针选择特定的移动平均线,例如bt.talib.STOCH
,可以使用 标准 ta-lib MA_Type
访问 bactrader.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 sizer 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()