Backtrader枢轴点交叉绘图

  |  

笔记

由于历史原因,保留此帖子。指针和示例已在源代码中更新, PivotPoint现在可以自动耦合,删除用户代码的样板。

将写一篇新的帖子来引用这个帖子。同时,请检查源中的更新示例。

一个有趣的请求出现了:

  • 中心点

这很有趣,因为指针是如何定义的。文献可以在StockCharts 的 PivotPoint找到。 PivotPoints 使用过去时间框架的close价、 high价和low 。例如对于每日时间范围:

  • 日线图的枢轴点使用上个月的数据

这可能看起来很麻烦,因为对于每个时间范围都需要定义必须使用的其他时间范围。查看公式会引发另一个问题:

Pivot Point (P) = (High + Low + Close)/3
Support 1 (S1) = (P x 2) - High
Support 2 (S2) = P  -  (High  -  Low)
Resistance 1 (R1) = (P x 2) - Low
Resistance 2 (R2) = P + (High  -  Low)

即使文本充满了对前期和过去的引用……这些公式似乎引用了当前时间点。让我们按照文本的建议,在我们第一次尝试 PivotPoint 时使用以前的方法。但首先让我们通过这样做来解决不同时间框架的问题:

  • 指针无法解决问题

尽管这可能看起来令人困惑,但必须考虑到指针必须尽可能愚蠢并由实际公式组成。问题将解决如下:

data = btfeeds.ADataFeed(..., timeframe=bt.TimeFrame.Days)
cerebro.adddata(data)
cerebro.resampledata(data, timeframe=bt.TimeFrame.Months)

后来在战略中:

class MyStrategy(bt.Strategy):
    def __init__(self):
        self.pp = PivotPoint(self.data1)  # the resampled data

现在很清楚了。系统将拥有数据,以及重新采样到所需时间范围的额外输入。 PivotPoint指针将与重新采样的数据一起使用,这些数据已经在所需的每月时间范围内,而原始数据时间范围是每天。

可以开发指针。让我们从遵循文本指示而不是公式开始,然后回顾 1 个句点。

class PivotPoint1(bt.Indicator):
    lines = ('p', 's1', 's2', 'r1', 'r2',)

    def __init__(self):
        h = self.data.high(-1)  # previous high
        l = self.data.low(-1)  # previous low
        c = self.data.close(-1)  # previous close

        self.lines.p = p = (h + l + c) / 3.0

        p2 = p * 2.0
        self.lines.s1 = p2 - h  # (p x 2) - high
        self.lines.r1 = p2 - l  # (p x 2) - low

        hilo = h - l
        self.lines.s2 = p - hilo  # p - (high - low)
        self.lines.r2 = p + hilo  # p + (high - low)

该策略将查看参数usepp1以使用此PivotPoint1

    def __init__(self):
        if self.p.usepp1:
            self.pp = PivotPoint1(self.data1)
        else:
            self.pp = PivotPoint(self.data1)

并且输出由一个简单的next方法控制

    def next(self):
        txt = ','.join(
            ['%04d' % len(self),
             '%04d' % len(self.data0),
             '%04d' % len(self.data1),
             self.data.datetime.date(0).isoformat(),
             '%.2f' % self.pp[0]])

        print(txt)

让我们运行:

./ppsample --usepp1

和输出:

0041,0041,0002,2005-02-28,2962.79
0042,0042,0002,2005-03-01,2962.79
...

马上就清楚了:索引 41 已经属于第 2月。这意味着我们已经跳过了 1 个月的指针计算。现在很清楚为什么 StockCharts 中的文本总是提到计算发生在上个月,但公式似乎引用了当前时刻。

  • 开发人员可能面临相同的设计决策,其中包含多个时间范围内的多个数据。

    在当前每日点,只能交付上个月的关闭柱。

这就是为什么next方法是查看索引[0]的原因。所有这一切都有一个非常简单的解决方法,那就是编写公式,就像 StockCharts 记录它们一样。

class PivotPoint(bt.Indicator):
    lines = ('p', 's1', 's2', 'r1', 'r2',)
    plotinfo = dict(subplot=False)

    def __init__(self):
        h = self.data.high  # current high
        l = self.data.low  # current high
        c = self.data.close  # current high

        self.lines.p = p = (h + l + c) / 3.0

        p2 = p * 2.0
        self.lines.s1 = p2 - h  # (p x 2) - high
        self.lines.r1 = p2 - l  # (p x 2) - low

        hilo = h - l
        self.lines.s2 = p - hilo  # p - (high - low)
        self.lines.r2 = p + hilo  # p + (high - low)

没有usepp1的运行:

./ppsample

新的输出是:

0021,0021,0001,2005-01-31,2962.79
0022,0022,0001,2005-02-01,2962.79
...

瞧!第 1月有20个交易日,一旦完成,指针计算值并可以交付。唯一打印的p ,如果 2中的值相同,是因为该值在整个下个月保持不变。引用股票图表:

Once Pivot Points are set, they do not change and remain in play throughout ...

该指针已经可以使用。让我们去绘图吧。已设置绘图参数

    plotinfo = dict(subplot=False)

计算值与数据比例一致,就像移动平均线一样,它可以沿着数据绘制(因此subplot= False

使用--plot运行:

./ppsample --plot

起泡的藤壶再次攻击。该指针已绘制在月度数据(其来源)上,这在日线图上没有提供任何视觉指示,这将非常有用。

但是backtrader支持从一个数据到另一个数据的交叉绘图。尽管需要在1.2.8.88中进行少量添加以支持对不同时间范围的数据进行交叉绘图。

这是通过让plotmaster说出绘图目标是什么来实现的,方法是将其添加到指针的plotinfo属性中:

./ppsample --plot --plot-on-daily

视觉反馈现在有助于了解PivotPoint提供的内容。

脚本代码和用法

backtrader的来源中作为示例提供:

$ ./ppsample.py --help
usage: ppsample.py [-h] [--data DATA] [--usepp1] [--plot] [--plot-on-daily]

Sample for pivot point and cross plotting

optional arguments:
  -h, --help       show this help message and exit
  --data DATA      Data to be read in (default:
                   ../../datas/2005-2006-day-001.txt)
  --usepp1         Have PivotPoint look 1 period backwards (default: False)
  --plot           Plot the result (default: False)
  --plot-on-daily  Plot the indicator on the daily data (default: False)

PivotPoint的代码

from __future__ import (absolute_import, division, print_function,)
#                        unicode_literals)

import backtrader as bt


class PivotPoint1(bt.Indicator):
    lines = ('p', 's1', 's2', 'r1', 'r2',)

    def __init__(self):
        h = self.data.high(-1)  # previous high
        l = self.data.low(-1)  # previous low
        c = self.data.close(-1)  # previous close

        self.lines.p = p = (h + l + c) / 3.0

        p2 = p * 2.0
        self.lines.s1 = p2 - h  # (p x 2) - high
        self.lines.r1 = p2 - l  # (p x 2) - low

        hilo = h - l
        self.lines.s2 = p - hilo  # p - (high - low)
        self.lines.r2 = p + hilo  # p + (high - low)


class PivotPoint(bt.Indicator):
    lines = ('p', 's1', 's2', 'r1', 'r2',)
    plotinfo = dict(subplot=False)

    def __init__(self):
        h = self.data.high  # current high
        l = self.data.low  # current high
        c = self.data.close  # current high

        self.lines.p = p = (h + l + c) / 3.0

        p2 = p * 2.0
        self.lines.s1 = p2 - h  # (p x 2) - high
        self.lines.r1 = p2 - l  # (p x 2) - low

        hilo = h - l
        self.lines.s2 = p - hilo  # p - (high - low)
        self.lines.r2 = p + hilo  # p + (high - low)

脚本的代码。

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import argparse

import backtrader as bt
import backtrader.feeds as btfeeds
import backtrader.utils.flushfile

from pivotpoint import PivotPoint, PivotPoint1


class St(bt.Strategy):
    params = (('usepp1', False),
              ('plot_on_daily', False))

    def __init__(self):
        if self.p.usepp1:
            self.pp = PivotPoint1(self.data1)
        else:
            self.pp = PivotPoint(self.data1)

        if self.p.plot_on_daily:
            self.pp.plotinfo.plotmaster = self.data0

    def next(self):
        txt = ','.join(
            ['%04d' % len(self),
             '%04d' % len(self.data0),
             '%04d' % len(self.data1),
             self.data.datetime.date(0).isoformat(),
             '%.2f' % self.pp[0]])

        print(txt)


def runstrat():
    args = parse_args()

    cerebro = bt.Cerebro()
    data = btfeeds.BacktraderCSVData(dataname=args.data)
    cerebro.adddata(data)
    cerebro.resampledata(data, timeframe=bt.TimeFrame.Months)

    cerebro.addstrategy(St,
                        usepp1=args.usepp1,
                        plot_on_daily=args.plot_on_daily)
    cerebro.run()
    if args.plot:
        cerebro.plot(style='bar')


def parse_args():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description='Sample for pivot point and cross plotting')

    parser.add_argument('--data', required=False,
                        default='../../datas/2005-2006-day-001.txt',
                        help='Data to be read in')

    parser.add_argument('--usepp1', required=False, action='store_true',
                        help='Have PivotPoint look 1 period backwards')

    parser.add_argument('--plot', required=False, action='store_true',
                        help=('Plot the result'))

    parser.add_argument('--plot-on-daily', required=False, action='store_true',
                        help=('Plot the indicator on the daily data'))

    return parser.parse_args()


if __name__ == '__main__':
    runstrat()

推荐阅读

相关文章

Backtrader教程:观察者 - 参考

基准 backtrader类 .observers.基准() 此 observer 存储策略的回报和参考资产的回报,参考资产是传递到系统的数据之一。

Backtrader 教程:佣金计划

不可知论在继续之前,让我们记住, backtrader者试图对数据代表什么保持不可知论。不同的佣金方案可以应用于相同的数据集。让我们看看它是如何做到的。使用代理快捷方式这使最终用户远离CommissionInfo对象,因为可以通过单个函数调用创建/设置佣金方案。

Backtrader观察员和统计

在 backtrader 内部运行的策略主要处理数据 和 指针。 数据被添加到Cerebro 实例中,并最终成为策略输入的一部分(解析并用作实例的属性),而指针由策略本身声明和管理。

Backtrader教程:数据馈送 - 重新采样

如果数据仅在单个时间范围内可用,并且必须在不同的时间范围内进行分析,则是时候进行一些重新采样了。 “重采样”实际上应该称为“上采样”,因为一个人从源时间帧到更大的时间帧(例如:几天到几周) backtrader 内置支持通过筛选器对象传递原始数据,从而进行重采样。

Backtrader期货补偿与现货补偿

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

Backtrader交叉回溯测试陷阱

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

Backtrader扩展佣金计划

佣金和相关功能由单个类 CommissionInfo 管理,该类主要通过调用 broker.setcommission 进行实例化。有一些帖子讨论了这种行为。佣金:股票与期货提高佣金:股票与期货该概念仅限于具有保证金和每份合约固定佣金的期货以及具有基于价格/规模百分比的佣金的股票。

Backtrader 教程:Cerebro - 节省内存

版本 1.3.1.92重新设计并完全实现了以前存在的内存节省方案,尽管没有太多吹捧和较少使用。 backtrader是(并将进一步)在具有大量 RAM 的机器上开发的,再加上通过绘图的视觉反馈是一个很好的拥有并且几乎是必须拥有的事实,mde 很容易做出设计决策:保留所有内容记忆。

BacktraderCSV 数据馈送开发

backtrader已经提供了通用 CSV数据提要和一些特定的 CSV数据提要。

Backtrader 教程:佣金计划 - 扩展

佣金和相关功能由单个类CommissionInfo管理,该类主要通过调用broker.setcommission进行实例化。该概念仅限于具有保证金和每份合约固定佣金的期货以及具有基于价格/规模百分比的佣金的股票。不是最灵活的计划,即使它已经达到了目的。