Backtrader回溯

  |  

在一些关于改进的ShapeRatio的提示之后, backtrader 已将此分析仪添加到其武器库中。

文献位于:

从对数回报的好处开始,并遵循在SharpeRatio方程的分母中具有标准偏差的副作用,本文档开发了该分析仪的公式和期望。

最重要的属性之一可能是:

  • 跨时间范围的一致价值

使用SharpeRatio 超额回报与无风险利率/资产的算术平均值除以超额回报与无风险利率/资产的标准偏差。这使得最终值取决于样本数量和甚至可能是 0的标准偏差。在这种情况下,将是 SharpeRatio 无限的。

backtrader包括一个范例,SharpeRatio用于测试使用范例数据的范例,其中包括和2006的价格2005。不同时间帧的返回值:

  • TimeFrame.Years: 11.6473

  • TimeFrame.Months: 0.5425

  • TimeFrame.Weeks: 0.457

  • TimeFrame.Days: 0.4274

注意

为了保持一致性,该比率是年化的。该sharpe-timereturn 范例与运行方式为:

--annualize --timeframe xxx

其中xxx 代表 daysweeksmonths years (默认值)

在此示例中,有一些明确的东西:

  • 时间帧越小,值越小 SharpeRatio

这是由样本数量引起的,对于较小的时间帧,样本数量更大,并增加了可变性,从而增加了标准偏差,这是方程中的SharpeRatio 分母。

对标准偏差的变化有很大的敏感性

这正是他们VWR 试图通过提供跨时间范围的一致值来解决的。同一策略提供以下值:

  • TimeFrame.Years: 1.5368

  • TimeFrame.Months: 1.5163

  • TimeFrame.Weeks: 1.5383

  • TimeFrame.Days: 1.5221

注意

返回VWR (遵循文献)始终以年化形式返回。该范例通过以下方式运行:

--timeframe xxx

其中xxx代表daysweeksmonthsyears

默认值是None 使用数据的基础时间帧,即 days

一致的值,表明策略在提供一致回报方面的表现可以在任何时间范围内进行评估。

注意

从理论上讲,这些值应该是相同的,但这需要将参数(年化周期数)微调tann 为确切的交易周期。这里没有这样做,因为目的只是看一致性。

结论

为用户提供了一种新工具,它提供了一种独立于时间框架的策略评估方法

示例用法

$ ./vwr.py --help
usage: vwr.py [-h] [--data DATA] [--cash CASH] [--fromdate FROMDATE]
              [--todate TODATE] [--writercsv]
              [--tframe {weeks,months,days,years}] [--sigma-max SIGMA_MAX]
              [--tau TAU] [--tann TANN] [--stddev-sample] [--plot [kwargs]]

TimeReturns and VWR

optional arguments:
  -h, --help            show this help message and exit
  --data DATA, -d DATA  data to add to the system (default:
                        ../../datas/2005-2006-day-001.txt)
  --cash CASH           Starting Cash (default: None)
  --fromdate FROMDATE, -f FROMDATE
                        Starting date in YYYY-MM-DD format (default: None)
  --todate TODATE, -t TODATE
                        Starting date in YYYY-MM-DD format (default: None)
  --writercsv, -wcsv    Tell the writer to produce a csv stream (default:
                        False)
  --tframe {weeks,months,days,years}, --timeframe {weeks,months,days,years}
                        TimeFrame for the Returns/Sharpe calculations
                        (default: None)
  --sigma-max SIGMA_MAX
                        VWR Sigma Max (default: None)
  --tau TAU             VWR tau factor (default: None)
  --tann TANN           Annualization factor (default: None)
  --stddev-sample       Consider Bessels correction for stddeviation (default:
                        False)
  --plot [kwargs], -p [kwargs]
                        Plot the read data applying any kwargs passed For
                        example: --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

TFRAMES = dict(
    days=bt.TimeFrame.Days,
    weeks=bt.TimeFrame.Weeks,
    months=bt.TimeFrame.Months,
    years=bt.TimeFrame.Years)


def runstrat(pargs=None):
    args = parse_args(pargs)

    # Create a cerebro
    cerebro = bt.Cerebro()

    if args.cash is not None:
        cerebro.broker.set_cash(args.cash)

    dkwargs = dict()
    # Get the dates from the args
    if args.fromdate is not None:
        fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d')
        dkwargs['fromdate'] = fromdate
    if args.todate is not None:
        todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d')
        dkwargs['todate'] = todate

    # Create the 1st data
    data = bt.feeds.BacktraderCSVData(dataname=args.data, **dkwargs)
    cerebro.adddata(data)  # Add the data to cerebro

    cerebro.addstrategy(bt.strategies.SMA_CrossOver)  # Add the strategy

    lrkwargs = dict()
    if args.tframe is not None:
        lrkwargs['timeframe'] = TFRAMES[args.tframe]

    if args.tann is not None:
        lrkwargs['tann'] = args.tann

    cerebro.addanalyzer(bt.analyzers.Returns, **lrkwargs)  # Returns

    vwrkwargs = dict()
    if args.tframe is not None:
        vwrkwargs['timeframe'] = TFRAMES[args.tframe]

    if args.tann is not None:
        vwrkwargs['tann'] = args.tann

    if args.sigma_max is not None:
        vwrkwargs['sigma_max'] = args.sigma_max

    if args.tau is not None:
        vwrkwargs['tau'] = args.tau

    cerebro.addanalyzer(bt.analyzers.VWR, **vwrkwargs)  # VWR Analyzer

    # Add a writer to get output
    cerebro.addwriter(bt.WriterFile, csv=args.writercsv, rounding=4)

    cerebro.run()  # And run it

    # Plot if requested
    if args.plot:
        pkwargs = dict(style='bar')
        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='TimeReturns and SharpeRatio')

    parser.add_argument('--data', '-d',
                        default='../../datas/2005-2006-day-001.txt',
                        help='data to add to the system')

    parser.add_argument('--cash', default=None, type=float, required=False,
                        help='Starting Cash')

    parser.add_argument('--fromdate', '-f',
                        default=None,
                        help='Starting date in YYYY-MM-DD format')

    parser.add_argument('--todate', '-t',
                        default=None,
                        help='Starting date in YYYY-MM-DD format')

    parser.add_argument('--writercsv', '-wcsv', action='store_true',
                        help='Tell the writer to produce a csv stream')

    parser.add_argument('--tframe', '--timeframe', default=None,
                        required=False, choices=TFRAMES.keys(),
                        help='TimeFrame for the Returns/Sharpe calculations')

    parser.add_argument('--sigma-max', required=False, action='store',
                        type=float, default=None,
                        help='VWR Sigma Max')

    parser.add_argument('--tau', required=False, action='store',
                        type=float, default=None,
                        help='VWR tau factor')

    parser.add_argument('--tann', required=False, action='store',
                        type=float, default=None,
                        help=('Annualization factor'))

    parser.add_argument('--stddev-sample', required=False, action='store_true',
                        help='Consider Bessels correction for stddeviation')

    # 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:\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类 .observers.基准() 此 observer 存储策略的回报和参考资产的回报,参考资产是传递到系统的数据之一。

Backtrader股票筛选

在寻找其他一些东西时,我在StackOverlow家族网站之一上遇到了一个问题:Quantitative Finance aka Quant StackExchange。问题: 它被标记为Python,因此值得一看的是 backtrader 是否能够胜任这项任务。 分析仪本身 该问题似乎适合用于简单的分析器。

BacktraderPyFolio 集成

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

Backtrader教程:过滤器 - 参考

工作阶段筛检程序 类 backtrader.filters。

Backtrader教程:筛检程序

此功能是 backtrader 的相对较新的补充,必须安装到已经存在的内部结构中。这使得它不像希望的那样灵活且100%功能齐全,但在许多情况下它仍然可以达到目的。 尽管该实现试图允许随插即用的筛检程序链接,但预先存在的内部结构使得很难确保始终可以实现。因此,某些筛选器可能是链接的,而其他一些筛选器可能不是。

Backtrader教程:Cerebro - 优化 - 改进

backtrader版本1.8.12.99改进了在多处理过程中管理data feeds和结果的方式。

Backtrader交叉回溯测试陷阱

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

Backtrader信贷利息

在某些情况下,真实经纪人的现金金额可能会减少,因为资产操作包括利率。例子: 卖空股票 交易所买卖基金包括多头和空头 这意味着不仅交易构成了系统的盈利能力,因为信贷上的利息在帐户上佔有一席之地。 为了涵盖这种情况, backtrader 包括(从发佈1.8.8.96开始)功能来考虑这一点。

Backtrader动量策略

在另一篇伟大的文章中,泰迪·科克(Teddy Koker)再次展示了算法交易策略的发展之路: 研究优先应用 pandas 回溯测试,然后使用 backtrader 荣誉!!! 该帖子可以在以下位置找到: 泰迪·科克(Teddy Koker)给我留言,问我是否可以评论 backtrader的用法。