TA-Lib#

即使 backtrader 提供了很多内置指标,并且开发指标通常只是定义输入、输出和以自然方式编写公式的问题,但有些人想要使用 TA-LIB 。其中一些原因是:

  • 指标 X*在库中,而不在 backtrader*中(作者将非常乐意接受请求)

  • TA-LIB 的行为是众所周知的,人们对老东西很有信心

为了满足每个人的口味,提供了 TA-LIB 集成。

要求#

  • TA-Lib的Python包装器<https://github.com/mrjbq7/ta-lib> _

  • 它所需的任何依赖项(例如 numpy

安装详细信息请参阅 GitHub 存储库

使用 ta-lib *** ** ** ** ** ** 使用backtrader中的任何内置指标都很简单。下面是一个简单移动平均线(Simple Moving Average)的示例。 首先是backtrader的示例代码:

```python 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的示例代码:

```python 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 指标的 params 是由库本身而不是 backtrader 定义的。在这种情况下, ta-lib 中的 SMA 使用一个名为``timeperiod``的参数来定义操作窗口的大小。

对于需要多个输入的指标,例如 Stochastic

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)

        ...

...

请注意,个别地传递了 highlowclose 。可以始终传递 low (或任何其他数据序列)进行实验。

ta-lib 指标文档已经自动解析并添加到 backtrader 文档中。您也可以查看 ta-lib 的源代码/文档。此外,您还可以执行以下操作::

print(bt.talib.SMA.__doc__)在这种情况下,输出为:

SMA([input_arrays], [timeperiod=30])

简单移动平均线(Overlap Studies)

输入:

price:(任何ndarray)

参数:

timeperiod:30

输出:

real

提供了一些信息:

  • 预期的 输入*( 忽略 ndarray 注释*,因为backtrader会在后台处理转换)

  • 参数及其默认值

  • 指标实际提供的输出*行*

移动平均线和MA_Type#

要为诸如 bt.talib.STOCH 的指标选择特定的 移动平均线 ,可以使用标准的 ta-lib MA_Type ,其通过 backtrader.talib.MA_Type 进行访问。例如:导入backtrader库并打印SMA和T3的代码如下:

```python

import backtrader as bt print(‘SMA:’, bt.talib.MA_Type.SMA) print(‘T3:’, bt.talib.MA_Type.T3)

```

绘制ta-lib指标#

和常规用法一样,绘制 ta-lib 指标并没有什么特别的事情需要做。

备注

输出为 CANDLE (所有寻找蜡烛图案的指标)的指标会给出二进制输出:要么是0,要么是100。为了避免将一个 subplot 添加到图表中,这里有一个自动绘图的转换,可以将它们绘制在识别到的蜡烛图案处的*数据*之上。

示例和比较#

以下是一些 ta-lib 指标输出与 backtrader 内置指标相比较的图表。需要注意的是:

  • ta-lib 指标在图表上加上了 TA_ 前缀。这是特意为了帮助用户区分二者。

  • 如果 移动平均线 (如果两者输出结果相同)在另一个现有的 移动平均线 上面绘制,则无法将这两个指标单独观察,如果这样,说明测试通过。

  • 所有示例都包括一个 CDLDOJI 指标作为参考。

KAMA指标(Kaufman移动平均线) =============================这是第一个例子,因为它是唯一一个有差异的(根据直接比较的所有指标):

  • 样本的初始值不相同

  • 在某个时间点,这两个 KAMA 实现的值收敛,并且表现相同。

在对 ta-lib 源代码进行分析后:

  • ta-lib 的实现选择了一个非行业标准的 KAMA 的第一个值。

    这个选择可以在源代码中看到(引用自源代码): 这里使用昨天的价格作为先前的 KAMA

backtrader 使用的是通常的选择,与例如 Stockcharts 的选择相同:

  • StockCharts 上的 KAMA

    由于我们需要一个初始值来开始计算,第一个 KAMA 只是一个简单移动平均值

因此产生了差异。此外:- ta-lib 中的 KAMA 实现不允许为 Kaufman 定义的 可伸缩常数 指定 fastslow 周期。

示例执行:

$ ./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

输出.. 缩略图:: ta-lib-rsi.png

$ ./talibtest.py --plot --ind macd

输出

$ ./talibtest.py --plot --ind bollinger

输出

阿隆 ====请注意, ta-lib 在与内置指标 backtrader 进行比较时,选择将 down 线放在首位,并且颜色是反转的。

$ ./talibtest.py --plot --ind aroon

输出

$ ./talibtest.py --plot --ind ultimate

输出

$ ./talibtest.py --plot --ind trix.. 缩略图:: ta-lib-trix.png

在这里, backtrader 提供了 * ADX * 和 * ADXR * 线。

$ ./talibtest.py --plot --ind adxr

输出

$ ./talibtest.py --plot --ind dema

输出.. 缩略图:: ta-lib-dema.png

$ ./talibtest.py --plot --ind tema

输出

这里 backtrader 提供了不仅是 ppo 线,还有更传统的 macd 方法。

$ ./talibtest.py --plot --ind ppo

输出

$ ./talibtest.py –plot –ind williamsr

输出

所有指标都具有相同的形状,但如何追踪 动量*或 变化率*有几种定义

$ ./talibtest.py --plot --ind roc

输出

示例用法#

$ ./talibtest.py --help
用法: 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]]TA-Lib的示例
可选参数:
-h, --help

显示此帮助信息并退出

--data0 DATA0

要读取的数据(默认值: ../../datas/yhoo-1996-2015.txt)

--fromdate FROMDATE

起始日期,格式为YYYY-MM-DD(默认值: 2005-01-01)

--todate TODATE

结束日期,格式为YYYY-MM-DD(默认值: 2006-12-31)

–ind {sma,ema,stoc,rsi,macd,bollinger,aroon,ultimate,trix,kama,adxr,dema,tema,ppo,williamsr,roc}

要一起显示的指标对(默认值: sma)

--no-doji

移除十字星蜡烛图模式的检查器(默认值: False)

--use-next

使用next(逐步)而不是once(批处理)(默认值: False)

–plot [kwargs], -p [kwargs]

对读取的数据进行绘图,应用任何传递的kwargs 例如(如有需要,请转义引号):–plot style=”candle”(绘制蜡烛图)(默认值: 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()