Backtrader教程:筛检程序

  |  

此功能是 backtrader 的相对较新的补充,必须安装到已经存在的内部结构中。这使得它不像希望的那样灵活且100%功能齐全,但在许多情况下它仍然可以达到目的。

尽管该实现试图允许随插即用的筛检程序链接,但预先存在的内部结构使得很难确保始终可以实现。因此,某些筛选器可能是链接的,而其他一些筛选器可能不是。

目的

  • 转换 data feed 提供的值以提供不同的 data feed

该实现的开始是为了简化两个明显的筛检程序的实现,这两个筛检程序可以通过 cerebro API直接使用。这些是:

  • 重采样 (cerebro.resampledata

    这个处,筛选器转换timeframe传入data feed的与 compression 。例如:

    (Seconds, 1) -> (Days, 1)
    

    这意味着原始 data feed 是分辨率为 1 秒的交割柱。重采样筛选器截获数据并对其进行缓冲,直到它可以提供 1 天柱。当看到第二天的 1 秒柱线时,就会发生这种情况。

  • 重播 (cerebro.replaydata

    对于与上述相同的时间范围,筛检程序将使用1秒分辨率柱来重建1日柱。

    这意味着 1 日柱的传递次数与看到 1 秒柱的次数一样多,并更新以包含最新信息。

    例如,这模拟了实际交易日是如何形成的。

    注意

    数据的长度,len(data) 因此只要日期不改变,策略的长度就保持不变。

工作中的筛检程序

给定现有的 data feed/source,addfilter 您可以使用 data feed的方法:

data = MyDataFeed(dataname=myname)
data.addfilter(filter, *args, **kwargs)
cerebro.addata(data)

即使它碰巧与重采样/重放过滤器兼容,也可以运行以下操作:

data = MyDataFeed(dataname=myname)
data.addfilter(filter, *args, **kwargs)
cerebro.replaydata(data)

过滤器接口

必须filter 符合给定的接口,如下所示:

  • 接受此签章的可调用对象:

    callable(data, *args, **kwargs)
    

  • 可以实例化和调用的类

    • 在实例化期间, __init__ 该方法必须支持签名:
    def __init__(self, data, *args, **kwargs)
    
    • __call__ 方法带有以下签名:
    def __call__(self, data, *args, **kwargs)
    

    将为每个来自 data feed的新传入值调用该实例。和\*args \*kwargs 是相同的传递给 __init__

    返回值

    * `True`: the inner data fetching loop of the data feed must retry
      fetching data from the feed, becaue the length of the stream was
      manipulated
    
    * `False` even if data may have been edited (example: changed
      `close` price), the length of the stream has remain untouched
    

    在基于类的筛检程序的情况下,可以实现其他方法

    • last 具有以下签名:
    def last(self, data, *args, **kwargs)
    

    这将在 data feed 结束时调用,允许筛选器提供它可能具有例如缓冲的数据。典型的情况是重新采样,因为柱线被缓冲,直到看到下一个时间段的数据。 data feed 结束后,没有新数据可以将缓冲数据推出。

    last 提供将缓冲数据推出的机会。

注意

很明显,如果筛检程序根本不支持任何参数,并且将添加没有任何参数,则可以简化签名,如下所示:

def __init__(self, data, *args, **kwargs) -> def __init__(self, data)

示例筛选器

一个非常快速的过滤器实现:

class SessionFilter(object):
    def __init__(self, data):
        pass

    def __call__(self, data):
        if data.p.sessionstart <= data.datetime.time() <= data.p.sessionend:
            # bar is in the session
            return False  # tell outer data loop the bar can be processed

        # bar outside of the regular session times
        data.backwards()  # remove bar from data stack
        return True  # tell outer data loop to fetch a new bar

此筛选器:

  • 使用data.p.sessionstartdata.p.sessionend (标准 data feed 参数)来决定柱线是否在会话中。

  • 如果在会话中,则返回值False 指示未运行任何操作,并且当前柱的处理可以继续

  • 如果不在会话中,则该栏将从流中删除并True 返回以指示必须获取新栏。

    注意

    接口data.backwards()LineBuffer 用途。这深入挖掘了 backtrader的内部。

此过滤器的使用:

  • 一些 data feeds 包含非正常交易时间数据,交易者可能对此不感兴趣。使用此筛选器时,将仅考虑会话中柱。

用于筛选器的数据伪 API

在上面的范例中,已显示筛选器如何调用data.backwards() 以从流中删除当前柱。来自 data feed 对象的有用调用(旨在作为过滤器的伪 API)是:

  • data.backwards(size=1, force=False):通过向后移动逻辑指针从数据流中删除大小条(默认值为 1)。如果 force=True为 ,则物理存储也将被删除。

    删除物理存储是一项精细的操作,仅用作内部操作的黑客攻击。

  • data.forward(value=float('NaN'), size=1):将存储向前移动大小条,如果需要,增加物理存储并填充 value

  • data._addtostack(bar, stash=False):添加到bar堆栈以供以后处理。bar是一个可反复运算的可反复运算,其中包含与 data feed一样lines多的值。

    如果stash=False 添加到堆栈中的柱将在下一次反复运算开始时立即被系统消耗。

    如果stash=True 柱线将经历整个循环处理,包括可能被筛检程序重新解析

  • data._save2stack(erase=False, force=False):将当前数据列保存到堆栈中以供以后处理。如果 erase=Truedata.backwards 将被调用并将接收参数 force

  • data._updatebar(bar, forward=False, ago=0):使用可 bar 反复运算中的值来覆盖数据流 ago 位置中的值。使用默认值 ago=0 时,当前柱将更新。与 -1,上一个。

另一个例子:粉红鱼筛检程序

这是一个可以链接到另一个筛检程序(即重播筛检程序)的过滤器的示例,并且意味着如此。Pinkfish这个名字来自图书馆,该图书馆在其主页上描述了这个想法:使用每日数据来运行只有日内数据才能实现的操作。

要达到以下效果:

  • 每日柱线将分为 2 个分量:OHL 然后 C

  • 这两个部分通过重播链接在一起,以便在流中发生以下情况:

    With Len X     -> OHL
    With Len X     -> OHLC
    With Len X + 1 -> OHL
    With Len X + 1 -> OHLC
    With Len X + 2 -> OHL
    With Len X + 2 -> OHLC
    ...
    

逻辑:

  • 当收到柱OHLC 线时,它被拷贝到一个可插入的柱中,并分解为:

    • 酒吧OHL 。因为这个概念实际上并不存在,所以收盘价被开盘价所取代,以真正形成一个 OHLO 柱线。

    • 一个C 也不存在的栏。现实情况是,它将像蜱虫一样交付 CCCC

    • 如果分布在两个部分之间的volume

    • 当前条形图已从流中删除

    • OHLO 零件放入堆栈上进行即时处理

    • CCCC 零件放入储藏室中,以便在下一轮中进行处理

    • 由于堆栈具有可立即处理的内容,因此筛选器可以返回False 以指示它。

此筛选器可与以下各项配合使用:

  • 重播筛检程序将 和 CCCC 部分组合在一起OHLO,最终提供条OHLC形图。

用例:

  • 看到这样的事情,如果今天的最大值是last20个会话中的最高最大值,则发出一个订单,该订单以第2个Close价格变动运行。

代码:

class DaySplitter_Close(bt.with_metaclass(bt.MetaParams, object)):
    '''
    Splits a daily bar in two parts simulating 2 ticks which will be used to
    replay the data:

      - First tick: ``OHLX``

        The ``Close`` will be replaced by the *average* of ``Open``, ``High``
        and ``Low``

        The session opening time is used for this tick

      and

      - Second tick: ``CCCC``

        The ``Close`` price will be used for the four components of the price

        The session closing time is used for this tick

    The volume will be split amongst the 2 ticks using the parameters:

      - ``closevol`` (default: ``0.5``) The value indicate which percentage, in
        absolute terms from 0.0 to 1.0, has to be assigned to the *closing*
        tick. The rest will be assigned to the ``OHLX`` tick.

    **This filter is meant to be used together with** ``cerebro.replaydata``

    '''
    params = (
        ('closevol', 0.5),  # 0 -> 1 amount of volume to keep for close
    )

    # replaying = True

    def __init__(self, data):
        self.lastdt = None

    def __call__(self, data):
        # Make a copy of the new bar and remove it from stream
        datadt = data.datetime.date()  # keep the date

        if self.lastdt == datadt:
            return False  # skip bars that come again in the filter

        self.lastdt = datadt  # keep ref to last seen bar

        # Make a copy of current data for ohlbar
        ohlbar = [data.lines[i][0] for i in range(data.size())]
        closebar = ohlbar[:]  # Make a copy for the close

        # replace close price with o-h-l average
        ohlprice = ohlbar[data.Open] + ohlbar[data.High] + ohlbar[data.Low]
        ohlbar[data.Close] = ohlprice / 3.0

        vol = ohlbar[data.Volume]  # adjust volume
        ohlbar[data.Volume] = vohl = int(vol * (1.0 - self.p.closevol))

        oi = ohlbar[data.OpenInterest]  # adjust open interst
        ohlbar[data.OpenInterest] = 0

        # Adjust times
        dt = datetime.datetime.combine(datadt, data.p.sessionstart)
        ohlbar[data.DateTime] = data.date2num(dt)

        # Ajust closebar to generate a single tick -> close price
        closebar[data.Open] = cprice = closebar[data.Close]
        closebar[data.High] = cprice
        closebar[data.Low] = cprice
        closebar[data.Volume] = vol - vohl
        ohlbar[data.OpenInterest] = oi

        # Adjust times
        dt = datetime.datetime.combine(datadt, data.p.sessionend)
        closebar[data.DateTime] = data.date2num(dt)

        # Update stream
        data.backwards(force=True)  # remove the copied bar from stream
        data._add2stack(ohlbar)  # add ohlbar to stack
        # Add 2nd part to stash to delay processing to next round
        data._add2stack(closebar, stash=True)

        return False  # initial tick can be further processed from stack

推荐阅读

相关文章

Backtrader教程:日志记录 - 编写器

将以下内容写出到流中: csv 流,

Backtrader教程:过滤器 - 参考

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

Backtrader跨越数字

《backtrader》的发布1.9.27.105纠正了一个疏忽。这是一个疏忽,因为拼图的所有部分都已到位,但启动并不是在所有角落都进行的。 该机制使用一个名为的属性_mindatas,因此让我们将其称为: mindatas。 社区问了这个问题,答案并不是很到位。

Backtrader教程:Cerebro - 优化 - 改进

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

Backtrader智能质押

版本 1.6.4.93 标志着 backtrader 的一个重要里程碑,即使版本号的更改很小。 职位大小调整是阅读Van K. Tharp的《Trade Your Way To Financial Freedom 》后,为这个项目奠定基础的事情之一。

Backtrader混合时间帧

1.3.0.92版本带来了混合来自不同时间帧的数据(来自 data feeds 和/或指针)的可能性。 到版本:https://github.com/mementum/backtrader/发布/标签/1.3.0.92 背景:指示器是智能哑对象。 他们很聪明,因为他们可以进行复杂的计算。

Backtraderta-lib 集成

即使 backtrader 提供了已经 high 数量的内置指针,并且开发指针主要是定义输入,输出和以自然的方式编写公式的问题,有些人也希望使用TA-LIB。

Backtrader蟒蛇隐藏的力量3

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

Backtrader 多数据范例

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

Backtrader信贷利息

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