Backtrader期货补偿与现货补偿

  |  

版本1.9.32.116 增加了对社区中呈现的有趣用例 的支持

  • 以期货开始交易,包括实物交割

  • 让一个指针告诉你一些事情

  • 如果需要, close 现货价格操作,有效地取消实物交割,无论是为了接收货物还是为了必须交付货物(并希望获利)来头寸。

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

这意味着:

  • 该平台提供来自两个不同资产的数据点

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

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

使用这种补偿概念,增加了一种方式,backtrader 让用户向平台传达一个 data feed 的东西会对另一个产生补偿作用。使用模式

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 。这将是未来

  • 模拟一个相似但不同的价格,通过重用相同的Feed并添加一个筛检程序,该筛检程序将价格随机移动到高于/低于某个点,以创建点差。简单如下:

    # 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 的标记,因此标准 observers 将被禁用并手动重新添加以使用不同的每数据标记进行打印

  • 仓位将随机输入并在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 预期

  • 交易正在被关闭,即使它们正在opendata0和被关闭data1,也达到了预期的效果(在现实生活中,这是为了避免通过未来获得的货物的实际交付)

人们只能想像,如果在不进行补偿的情况下应用相同的逻辑,会发生什么。让我们来做吧:

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

和输出

很明显,这失败了:

  • 该逻辑期望在 上data0止损由操作data1平仓,并且仅在不在市场上时open仓位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跨越数字

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

Backtrader按日线交易

似乎在世界某个地方有一种权益(Interest)可以总结如下: 使用每日柱线引入订单,但使用开盘价 这来自工单#105订单执行逻辑与当前数据和#101动态投注计算中的对话 backtrader 尝试尽可能保持现实,并且在处理每日柱线时适用以下前提: 当每日柱被评估时,柱线已经结束 这是有道理的,

Backtrader教程:安装

要求和版本 backtrader 是独立的,没有外部依赖关系(除非要绘图) 基本要求是: Python 2.7 Python 3.2 / 3.3/ 3.4 / 3.5 pypy/pypy3 如果需要绘图,则其他要求: Matplotlib >= 1.4.

Backtrader期货补偿与现货补偿

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

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

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

Backtrader教程:数据馈送 - 扩展(Extending DataFeed)

GitHub 中的问题实际上是在推动文档部分的完成,或者説明我了解我是否backtrader 具有我从一开始就设想的易用性和灵活性以及在此过程中做出的决定。 在本例中为问题 #9。

数据多时间帧

有时投资决策是使用不同的时间框架做出的: 每周评估趋势 每天执行条目 或者5分钟对60分钟。 这意味着需要将多个时间帧的数据组合在 backtrader 中以支援此类组合。 对它的本机支持已经内置。

Backtrader 多数据范例

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

Backtrader教程:分析仪 - PyFolio

注意 从(至少)2017-07-25pyfolio 开始,API已更改,不再 create_full_tear_sheet 具有 gross_lev 作为命名参数的参数。

Backtrader信贷利息

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