Backtrader 教程:订单 - 期货现货补偿

  |  

1.9.32.116版增加了对社区中一个有趣的用例的支持

  • 与未来开始交易,包括实物交割

  • 让指针告诉你一些事情

  • 如果需要,通过以现货价格操作平仓,有效地取消实物交割,无论是接收货物还是必须交付货物(并希望获利)

    期货在现货价格操作发生的同一天到期

这意味着:

  • 该平台接收来自两种不同资产的数据点

  • 平台必须以某种方式了解资产是相关的,并且现货价格操作将关闭未来未平仓头寸

    现实中,未来没有封闭,只有实物交割得到补偿

使用该补偿概念, backtrader添加了一种方法,让用户与平台沟通,一个数据馈送上的事物将对另一个数据馈送产生补偿影响。使用模式

import backtrader as bt

cerebro = bt.Cerebro()

data0 = bt.feeds.MyFavouriteDataFeed(dataname='futurename')
cerebro.adddata(data0)

data1 = bt.feeds.MyFavouriteDataFeed(dataname='spotname')
data1.compensate(data0)  # let the system know ops on data1 affect data0
cerebro.adddata(data1)

...

cerebro.run()

把它们放在一起

一个例子总是值一千个帖子,所以让我们把所有的部分放在一起。

  • 使用来自backtrader来源的标准示例提要之一。这将是未来

  • 通过重复使用相同的提要并添加一个过滤器来仿真相似但不同的价格,该过滤器将随机将价格移动到上方/下方一些点,以创建点差。很简单:

    # The filter which changes the close price
    def close_changer(data, *args, **kwargs):
        data.close[0] += 50.0 * random.randint(-1, 1)
        return False  # length of stream is unchanged
    
  • 在同一轴上绘图将混合默认包含的BuyObserver标记,因此标准观察者将被禁用并手动读取以使用不同的每个数据标记进行绘图

  • 仓位随机入仓,10天后出仓

    这与未来的到期期限不匹配,但这只是将功能落实到位,而不是检查交易日历

!!!笔记

  A simulation including execution on the spot price on the day of
  future expiration would require activating `cheat-on-close` to
  make sure the orders are executed when the future expires. This is
  not needed in this sample, because the expiration is being chosen
  at random.
  • 注意策略

    • buy操作在data0上运行

    • sell操作在data1上运行

    class St(bt.Strategy):
        def __init__(self):
            bt.obs.BuySell(self.data0, barplot=True)  # done here for
            BuySellArrows(self.data1, barplot=True)  # different markers per data
    
        def next(self):
            if not self.position:
                if random.randint(0, 1):
                    self.buy(data=self.data0)
                    self.entered = len(self)
    
            else:  # in the market
                if (len(self) - self.entered) >= 10:
                    self.sell(data=self.data1)
    

运行:

$ ./future-spot.py --no-comp

有了这个图形输出。

它有效:

  • buy操作用一个向上的绿色三角形表示,图例告诉我们它们属于预期的data0

  • sell操作用一个向下的箭头表示,图例告诉我们它们按预期属于data1

  • 交易正在关闭,即使它们使用data0打开并使用data1关闭,也达到了预期的效果(这在现实生活中避免了通过未来获得的货物的实物交付)

人们只能想像如果在没有补偿的情况下应用相同的逻辑会发生什么。我们开始做吧:

$ ./future-spot.py --no-comp

和输出

很明显,这会惨遭失败:

  • 逻辑预期data0上的仓位将通过data1上的操作关闭,并且仅在data0上未在市场上时打开仓位

  • 但补偿已被停用,对data0的初始操作(绿色三角形)永远不会关闭,因此永远不会启动其他操作,并且data1上的空头头寸开始累积。

示例使用

$ ./future-spot.py --help
usage: future-spot.py [-h] [--no-comp]

Compensation example

optional arguments:
  -h, --help  show this help message and exit
  --no-comp

示例代码

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

import argparse
import random
import backtrader as bt


# The filter which changes the close price
def close_changer(data, *args, **kwargs):
    data.close[0] += 50.0 * random.randint(-1, 1)
    return False  # length of stream is unchanged


# override the standard markers
class BuySellArrows(bt.observers.BuySell):
    plotlines = dict(buy=dict(marker='$\u21E7$', markersize=12.0),
                     sell=dict(marker='$\u21E9$', markersize=12.0))


class St(bt.Strategy):
    def __init__(self):
        bt.obs.BuySell(self.data0, barplot=True)  # done here for
        BuySellArrows(self.data1, barplot=True)  # different markers per data

    def next(self):
        if not self.position:
            if random.randint(0, 1):
                self.buy(data=self.data0)
                self.entered = len(self)

        else:  # in the market
            if (len(self) - self.entered) >= 10:
                self.sell(data=self.data1)


def runstrat(args=None):
    args = parse_args(args)
    cerebro = bt.Cerebro()

    dataname = '../../datas/2006-day-001.txt'  # data feed

    data0 = bt.feeds.BacktraderCSVData(dataname=dataname, name='data0')
    cerebro.adddata(data0)

    data1 = bt.feeds.BacktraderCSVData(dataname=dataname, name='data1')
    data1.addfilter(close_changer)
    if not args.no_comp:
        data1.compensate(data0)
    data1.plotinfo.plotmaster = data0
    cerebro.adddata(data1)

    cerebro.addstrategy(St)  # sample strategy

    cerebro.addobserver(bt.obs.Broker)  # removed below with stdstats=False
    cerebro.addobserver(bt.obs.Trades)  # removed below with stdstats=False

    cerebro.broker.set_coc(True)
    cerebro.run(stdstats=False)  # execute
    cerebro.plot(volume=False)  # and plot


def parse_args(pargs=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=('Compensation example'))

    parser.add_argument('--no-comp', required=False, action='store_true')
    return parser.parse_args(pargs)


if __name__ == '__main__':
    runstrat()

推荐阅读

相关文章

Backtrader期货展期

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

BacktraderPython Hidden Powers 2

让我们进一步讨论一下Python的隐藏功能如何在 backtrader 中使用,以及如何实现它以尝试实现主要目标:易用性 这些定义是什么? 例如指针: import backtrader as bt class MyIndicator(bt.

Backtrader教程:操作平台

Line 反复运算器 为了参与操作,plaftorm使用 line 反复运算器的概念。它们已经松散地模仿了Python的反复运算器,但实际上与它们无关。 策略和指针是 line 反复运算器。

Backtrader教程:观察者 - 基准测试

工单 #89 是关于针对资产添加基准测试的。明智的是,人们实际上可能有一个策略,即使积极,也低于简单地跟踪资产所能提供的策略。

Backtrader体积填充

到目前为止, backtrader中的默认交易量填充策略相当简单明了:忽略音量笔记2016 年 7 月 15 日更正了实现中的错误并更新了示例以close头寸并在休息后重复。

Backtraderta-lib 集成

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

Backtrader教程:经纪商

经纪商仿真器该模拟支持不同的订单类型,根据当前现金检查提交的订单现金需求,跟踪每次反复运算的cerebro 现金和价值,并在不同数据上保持当前位置。

Backtrader卡尔曼等

注意 对以下指令的支持从提交开始 发布1.9.30.x 将是包含它的第1个版本 。 backtrader的原始目标之一是成为纯python,即:仅使用标准发行版中可用的软件包。只有一个例外是matplotlib在没有重新发明轮子的情况下进行绘图。

Backtrader动量策略

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

Backtrader数据馈送开发

添加新的基于 CSV 的数据馈送很容易。