Backtrader教程:指针 - ta-lib

  |  

即使 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)

        ...

...

注意如何highlow 并且 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提供ADXADXRlines

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

推荐阅读

相关文章

Backtrader向 OHLC 提供买入价/卖出价数据

最近,backtrader通过实现line覆盖来运行从 ohlc-land 逃逸,这允许重新定义整个层次结构,例如,具有仅具有 bid,ask 和 datetime lines的data feeds。

Backtrader对逐笔报价数据重新采样

backtrader 已经可以从分钟数据中重新采样。接受价格变动数据不是问题,只需将 4 个常用字段(open、 high、 low、 close)设置为价格变动值。 但是传递要重新采样的逐笔报价数据再次生成相同的数据。作为或版本 1.1.11.88,情况已不再如此。

Backtrader期货补偿与现货补偿

版本1.9.32.116 增加了对社区中呈现的有趣用例 的支持 以期货开始交易,包括实物交割 让一个指针告诉你一些事情 如果需要, close 现货价格操作,有效地取消实物交割,无论是为了接收货物还是为了必须交付货物(并希望获利)来头寸。

BacktraderPyFolio 集成

注意 2017年2月 pyfolio API 已更改,不再 create_full_tear_sheet 具有 gross_lev 作为命名参数的参数。

Backtrader教程:数据馈送 - 展期交割

并非每个供应商都为可以交易的工具提供连续的未来。有时提供的数据是仍然有效的到期日期的数据,即:仍在交易的日期 这在回溯测试方面并不是很有帮助,因为数据分散在几个不同的仪器上,这些仪器另外...时间重叠。 能够正确地将这些仪器的数据从过去连接到连续的流中,可以减轻疼痛。

Backtrader交叉回溯测试陷阱

在backtrader 社区中 ,倾向于重复的事情是,用户解释了拷贝在例如 TradingView 中获得的回溯测试结果的意愿,这些天非常流行,或者其他一些回溯测试平台。

Backtrader蟒蛇隐藏的力量3

Last,但并非最不重要的一点是,在这个系列中,关于如何在 backtrader 中使用Python的隐藏功能是一些神奇变量是如何出现的。

Backtrader 多数据范例

社区中的几个主题似乎以如何跟踪订单为导向,特别是当几个data feeds在起作用时,还包括当多个订单一起工作时,

Backtrader教程:分析仪 - PyFolio

注意 从(至少)2017-07-25pyfolio 开始,API已更改,不再 create_full_tear_sheet 具有 gross_lev 作为命名参数的参数。

Backtrader终极振荡器

backtrader开发启动时的目标之一是使开发新的指针变得非常容易(至少对作者本人而言),以在数学和视觉上测试想法。 门票#102 是关于将 UltimateOscillator 添加到 backtrader 注意 它将在下一个版本中添加,同时可以使用下面的代码使用它。 票证中所示的参考: 以及: 无需在这里重复。