BackTrader 中文文档(二十七)(1)

简介: BackTrader 中文文档(二十七)


原文:www.backtrader.com/

数据 - 多个时间框架

原文:www.backtrader.com/blog/posts/2015-08-24-data-multitimeframe/data-multitimeframe/

有时,使用不同的时间框架进行投资决策:

  • 周线用于评估趋势
  • 每日执行进入

或者 5 分钟对比 60 分钟。

这意味着在 backtrader 中需要组合多个时间框架的数据以支持这样的组合。

本地支持已经内置。最终用户只需遵循以下规则:

  • 具有最小时间框架的数据(因此是较大数量的条)必须是添加到 Cerebro 实例的第一个数据
  • 数据必须正确地对齐日期时间,以便平台能够理解它们的任何含义

此外,最终用户可以自由地在较短/较大的时间框架上应用指标。当然:

  • 应用于较大时间框架的指标将产生较少的条

平台也将考虑以下内容

  • 较大时间框架的最小周期

最小周期可能会导致在策略添加到 Cerebro 之前需要消耗几个数量级的较小时间框架的数据。

内置的DataResampler将用于创建较大的时间框架。

一些示例如下,但首先是测试脚本的来源。

# Load the Data
    datapath = args.dataname or '../datas/sample/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(
        dataname=datapath)
    tframes = dict(
        daily=bt.TimeFrame.Days,
        weekly=bt.TimeFrame.Weeks,
        monthly=bt.TimeFrame.Months)
    # Handy dictionary for the argument timeframe conversion
    # Resample the data
    if args.noresample:
        datapath = args.dataname2 or '../datas/sample/2006-week-001.txt'
        data2 = btfeeds.BacktraderCSVData(
            dataname=datapath)
    else:
        data2 = bt.DataResampler(
            dataname=data,
            timeframe=tframes[args.timeframe],
            compression=args.compression)

步骤:

  • 加载数据
  • 根据用户指定的参数重新采样它
    脚本还允许加载第二个数据
  • 将数据添加到 cerebro
  • 将重新采样的数据(较大的时间框架)添加到 cerebro
  • 运行

示例 1 - 每日和每周

脚本的调用:

$ ./data-multitimeframe.py --timeframe weekly --compression 1

和输出图表:

示例 2 - 日间和日间压缩(2 根变成 1 根)

脚本的调用:

$ ./data-multitimeframe.py --timeframe daily --compression 2

和输出图表:

示例 3 - 带有 SMA 的策略

虽然绘图很好,但这里的关键问题是显示较大的时间框架如何影响系统,特别是当涉及到起始点时

脚本可以采用--indicators来添加一个策略,该策略在较小时间框架和较大时间框架的数据上创建10 周期的简单移动平均线。

如果只考虑较小的时间框架:

  • next将在 10 个条之后首先被调用,这是简单移动平均需要产生值的时间
    注意
    请记住,策略监视创建的指标,并且只有在所有指标都产生值时才调用next。理由是最终用户已经添加了指标以在逻辑中使用它们,因此如果指标尚未产生值,则不应进行任何逻辑

但在这种情况下,较大的时间框架(每周)会延迟调用next,直到每周数据的简单移动平均产生值为止,这需要… 10 周。

脚本覆盖了nextstart,它只被调用一次,默认调用next以显示首次调用的时间。

调用 1:

只有较小的时间框架,即每日,才有一个简单移动平均值。

命令行和输出

$ ./data-multitimeframe.py --timeframe weekly --compression 1 --indicators --onlydaily
--------------------------------------------------
nextstart called with len 10
--------------------------------------------------

以及图表。

调用 2:

两个时间框架都有一个简单移动平均。

命令行:

$ ./data-multitimeframe.py --timeframe weekly --compression 1 --indicators
--------------------------------------------------
nextstart called with len 50
--------------------------------------------------
--------------------------------------------------
nextstart called with len 51
--------------------------------------------------
--------------------------------------------------
nextstart called with len 52
--------------------------------------------------
--------------------------------------------------
nextstart called with len 53
--------------------------------------------------
--------------------------------------------------
nextstart called with len 54
--------------------------------------------------

注意这里的两件事:

  • 不是在10个周期之后被调用,而是在 50 个周期之后第一次被调用。
    这是因为在较大(周)时间框架上应用简单移动平均值后产生了一个值,… 这是 10 周* 5 天/周… 50 天。
  • nextstart被调用了 5 次,而不是仅 1 次。
    这是将时间框架混合并(在这种情况下仅有一个)指标应用于较大时间框架的自然副作用。
    较大时间框架的简单移动平均值在消耗 5 个日间条时产生 5 倍相同的值。
    由于周期的开始由较大的时间框架控制,nextstart被调用了 5 次。

以及图表。

结论

多时间框架数据可以在backtrader中使用,无需特殊对象或调整:只需先添加较小的时间框架。

测试脚本。

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import argparse
import backtrader as bt
import backtrader.feeds as btfeeds
import backtrader.indicators as btind
class SMAStrategy(bt.Strategy):
    params = (
        ('period', 10),
        ('onlydaily', False),
    )
    def __init__(self):
        self.sma_small_tf = btind.SMA(self.data, period=self.p.period)
        if not self.p.onlydaily:
            self.sma_large_tf = btind.SMA(self.data1, period=self.p.period)
    def nextstart(self):
        print('--------------------------------------------------')
        print('nextstart called with len', len(self))
        print('--------------------------------------------------')
        super(SMAStrategy, self).nextstart()
def runstrat():
    args = parse_args()
    # Create a cerebro entity
    cerebro = bt.Cerebro(stdstats=False)
    # Add a strategy
    if not args.indicators:
        cerebro.addstrategy(bt.Strategy)
    else:
        cerebro.addstrategy(
            SMAStrategy,
            # args for the strategy
            period=args.period,
            onlydaily=args.onlydaily,
        )
    # Load the Data
    datapath = args.dataname or '../datas/sample/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(
        dataname=datapath)
    tframes = dict(
        daily=bt.TimeFrame.Days,
        weekly=bt.TimeFrame.Weeks,
        monthly=bt.TimeFrame.Months)
    # Handy dictionary for the argument timeframe conversion
    # Resample the data
    if args.noresample:
        datapath = args.dataname2 or '../datas/sample/2006-week-001.txt'
        data2 = btfeeds.BacktraderCSVData(
            dataname=datapath)
    else:
        data2 = bt.DataResampler(
            dataname=data,
            timeframe=tframes[args.timeframe],
            compression=args.compression)
    # First add the original data - smaller timeframe
    cerebro.adddata(data)
    # And then the large timeframe
    cerebro.adddata(data2)
    # Run over everything
    cerebro.run()
    # Plot the result
    cerebro.plot(style='bar')
def parse_args():
    parser = argparse.ArgumentParser(
        description='Pandas test script')
    parser.add_argument('--dataname', default='', required=False,
                        help='File Data to Load')
    parser.add_argument('--dataname2', default='', required=False,
                        help='Larger timeframe file to load')
    parser.add_argument('--noresample', action='store_true',
                        help='Do not resample, rather load larger timeframe')
    parser.add_argument('--timeframe', default='weekly', required=False,
                        choices=['daily', 'weekly', 'monhtly'],
                        help='Timeframe to resample to')
    parser.add_argument('--compression', default=1, required=False, type=int,
                        help='Compress n bars into 1')
    parser.add_argument('--indicators', action='store_true',
                        help='Wether to apply Strategy with indicators')
    parser.add_argument('--onlydaily', action='store_true',
                        help='Indicator only to be applied to daily timeframe')
    parser.add_argument('--period', default=10, required=False, type=int,
                        help='Period to apply to indicator')
    return parser.parse_args()
if __name__ == '__main__':
    runstrat()

数据重新取样

原文:www.backtrader.com/blog/posts/2015-08-23-data-resampling/data-resampling/

当数据仅在一个时间段可用,而分析必须针对不同的时间段进行时,就是时候进行一些重新取样了。

“重新取样”实际上应该称为“向上取样”,因为要从一个源时间段转换到一个较大的时间段(例如:从天到周)

“向下采样”目前还不可能。

backtrader 通过将原始数据传递给一个智能命名为 DataResampler 的过滤器对象来支持重新取样。

该类具有两个功能:

  • 更改时间框架
  • 压缩条柱

为此,DataResampler 在构造过程中使用标准的 feed.DataBase 参数:

  • timeframe(默认:bt.TimeFrame.Days)
    目标时间段必须与源时间段相等或更大才能有用
  • compression(默认:1)
    将所选值 “n” 压缩到 1 条柱

让我们看一个从每日到每周的手工脚本示例:

$ ./data-resampling.py --timeframe weekly --compression 1

输出结果:

我们可以将其与原始每日数据进行比较:

$ ./data-resampling.py --timeframe daily --compression 1

输出结果:

这是通过执行以下步骤来完成的魔术:

  • 像往常一样加载数据
  • 将数据馈送到具有所需的DataResampler
  • 时间框架
  • 压缩

示例代码(底部的整个脚本)。

# Load the Data
    datapath = args.dataname or '../datas/sample/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(
        dataname=datapath)
    # Handy dictionary for the argument timeframe conversion
    tframes = dict(
        daily=bt.TimeFrame.Days,
        weekly=bt.TimeFrame.Weeks,
        monthly=bt.TimeFrame.Months)
    # Resample the data
    data_resampled = bt.DataResampler(
        dataname=data,
        timeframe=tframes[args.timeframe],
        compression=args.compression)
    # Add the resample data instead of the original
    cerebro.adddata(data_resampled)

最后一个例子中,我们首先将时间框架从每日更改为每周,然后应用 3 到 1 的压缩:

$ ./data-resampling.py --timeframe weekly --compression 3

输出结果:

从原始的 256 个每日条柱变为 18 个 3 周条柱。具体情况如下:

  • 52 周
  • 52 / 3 = 17.33 因此为 18 条柱

这不需要太多。当然,分钟数据也可以进行重新取样。

重新取样测试脚本的示例代码。

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import argparse
import backtrader as bt
import backtrader.feeds as btfeeds
def runstrat():
    args = parse_args()
    # Create a cerebro entity
    cerebro = bt.Cerebro(stdstats=False)
    # Add a strategy
    cerebro.addstrategy(bt.Strategy)
    # Load the Data
    datapath = args.dataname or '../datas/sample/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(
        dataname=datapath)
    # Handy dictionary for the argument timeframe conversion
    tframes = dict(
        daily=bt.TimeFrame.Days,
        weekly=bt.TimeFrame.Weeks,
        monthly=bt.TimeFrame.Months)
    # Resample the data
    data_resampled = bt.DataResampler(
        dataname=data,
        timeframe=tframes[args.timeframe],
        compression=args.compression)
    # Add the resample data instead of the original
    cerebro.adddata(data_resampled)
    # Run over everything
    cerebro.run()
    # Plot the result
    cerebro.plot(style='bar')
def parse_args():
    parser = argparse.ArgumentParser(
        description='Pandas test script')
    parser.add_argument('--dataname', default='', required=False,
                        help='File Data to Load')
    parser.add_argument('--timeframe', default='weekly', required=False,
                        choices=['daily', 'weekly', 'monhtly'],
                        help='Timeframe to resample to')
    parser.add_argument('--compression', default=1, required=False, type=int,
                        help='Compress n bars into 1')
    return parser.parse_args()
if __name__ == '__main__':
    runstrat()


BackTrader 中文文档(二十七)(2)https://developer.aliyun.com/article/1505478

相关文章
|
5天前
|
存储 数据库连接 数据库
BackTrader 中文文档(二十七)(4)
BackTrader 中文文档(二十七)
10 0
|
5天前
|
索引
BackTrader 中文文档(二十七)(3)
BackTrader 中文文档(二十七)
10 0
|
5天前
|
算法 索引 Python
BackTrader 中文文档(二十七)(2)
BackTrader 中文文档(二十七)
15 0
|
5天前
BackTrader 中文文档(二十九)(3)
BackTrader 中文文档(二十九)
10 0
|
5天前
BackTrader 中文文档(二十九)(2)
BackTrader 中文文档(二十九)
11 0
|
5天前
|
算法 索引
BackTrader 中文文档(二十九)(1)
BackTrader 中文文档(二十九)
11 0
|
5天前
|
存储 API
BackTrader 中文文档(二十九)(4)
BackTrader 中文文档(二十九)
14 0
|
5天前
BackTrader 中文文档(二十八)(2)
BackTrader 中文文档(二十八)
11 0
|
5天前
|
测试技术 C语言 Python
BackTrader 中文文档(二十八)(4)
BackTrader 中文文档(二十八)
14 0
|
5天前
|
Python
BackTrader 中文文档(二十八)(1)
BackTrader 中文文档(二十八)
10 0