Backtrader教程:尺寸调整器

  |  

  • 智能质押

策略提供了交易方法,即:buysell close。让我们看看签名 buy

def buy(self, data=None,
        size=None, price=None, plimit=None,
        exectype=None, valid=None, tradeid=0, **kwargs):

请注意,size 如果调用方未指定默认值,则具有默认值 None 。这是 Sizers 发挥重要作用的地方:

  • size=None要求「战略」询问其实际赌注的Sizer

这显然意味着策略有一个 Sizer:是的,确实如此!后台机制将缺省 sizer 添加到策略中,如果用户尚未添加一个。添加到策略的缺省 SizerSizerFix。定义的初始 lines

class SizerFix(SizerBase):
    params = (('stake', 1),)

很容易猜到,这个Sizer只是使用一个stake1单位(无论是股票,合约等)购买/出售。

使用 Sizers

Cerebro

Sizers 可以通过2种不同的方法通过 Cerebro 添加:

  • addsizer(sizercls, *args, **kwargs)

    添加一个 Sizer ,该将应用于添加到 cerebro的任何策略。可以说,这是缺省 Sizer。例:

    cerebro = bt.Cerebro()
    cerebro.addsizer(bt.sizers.SizerFix, stake=20)  # default sizer for strategies
    
  • addsizer_byidx(idx, sizercls, *args, **kwargs)

    Sizer将仅添加到idx

    这可以idx 作为返回值从 addstrategy获取。如:

    cerebro = bt.Cerebro()
    cerebro.addsizer(bt.sizers.SizerFix, stake=20)  # default sizer for strategies
    
    idx = cerebro.addstrategy(MyStrategy, myparam=myvalue)
    cerebro.addsizer_byidx(idx, bt.sizers.SizerFix, stake=5)
    
    cerebro.addstrategy(MyOtherStrategy)
    

    在这里范例中:

    • 默认 Sizer 已添加到系统中。这适用于没有分配特定 Sizer 的所有策略

    • 对于 MyStrategy,在收集其插入 idx 后,将添加特定的 sizer (更改stake 参数)

    • 第二个策略MyOtherStrategy被添加到系统中。没有为其添加特定的Sizer

    • 这意味着:

      • MyStrategy最终将有一个内部特定的 Sizer

      • MyOtherStrategy将获得缺省 sizer

注意

默认并不意味着策略共用单个Sizer实例。每个策略接收缺省sizer的不同实例

若要共用单个实例,要共用 sizer 应为单例类。如何定义一个超出了 backtrader

从战略

策略类提供了一个 API:setsizer 和(和 getsizer 一个属性 sizer)来管理 Sizer。签章:

  • def setsizer(self, sizer):它需要一个已经实例化的 Sizer

  • def getsizer(self):返回当前 Sizer 实例

  • sizer 它是可以直接获取/设置的属性

在这种情况下, Sizer 可以是例如:

  • 作为参数传递给策略

  • 在使用属性sizer__init__进行设置,或setsizer如:

    class MyStrategy(bt.Strategy):
        params = (('sizer', None),)
    
        def __init__(self):
            if self.p.sizer is not None:
                self.sizer = self.p.sizer
    

    例如,这将允许在cerebro调用发生的同一级别创建Sizer,并将其作为参数传递给系统中的所有策略,从而有效地允许共用Sizer

Sizer 开发

这很容易:

  1. 子类从backtrader.Sizer

    这使您可以访问self.strategy 并且 self.broker 在大多数情况下不需要它。可以使用 broker

    • 数据的位置self.strategy.getposition(data)

    • 完整的投资组合价值通过以下方式self.broker.getvalue()

      请注意,这当然也可以通过以下方式完成self.strategy.broker.getvalue()

    其他一些事情已经在下面作为论据

  2. 重写方法_getsizing(self, comminfo, cash, data, isbuy)

    • comminfo:佣金信息实例,包含有关数据佣金的信息,并允许计算位置值,运营成本,操作佣金

    • cash:经纪人的当前可用现金

    • data:操作的目标

    • isbuy:将 True 用于买入操作和 False 卖出操作

    此方法返回size 买入/卖出操作所需的值

    返回的符号不相关,即:如果操作是卖出操作(isbuy 将是 False),则方法可能返回 5-5。卖出操作将仅使用绝对值。

    Sizer 已经转到 broker 并要求委员会提供给定数据,实际现金水准的信息,并提供对作为操作目标的数据的直接参考

让我们来看看sizer的定义FixedSize

import backtrader as bt

class FixedSize(bt.Sizer):
    params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
        return self.params.stake

这很简单,因为 Sizer 不进行计算,参数就在那里。

但该机制应该允许构建复杂的尺寸(又名定位)系统,以管理进入/退出市场时的赌注。

另一个例子:位置反转器

class FixedRerverser(bt.FixedSize):

    def _getsizing(self, comminfo, cash, data, isbuy):
        position = self.broker.getposition(data)
        size = self.p.stake * (1 + (position.size != 0))
        return size

这个创建在现有FixedSize 的基础上,继承 params 并覆盖 _getsizing

  • position通过属性获取数据broker

  • 用于position.size 决定是否将固定赌注翻倍

  • 返回计算值

这将消除《战略》的负担,即决定是否必须逆转或开仓, Sizer 处于控制之中,可以随时更换而不影响逻辑。

实用 Sizer 适用性

考虑到复杂的大小调整算法,可以使用两种不同的sizers将策略从仅做多转换为多空。只需改变cerebro运行中的Sizer,策略就会改变行为。一个非常简单的close交叉SMA算法:

class CloseSMA(bt.Strategy):
    params = (('period', 15),)

    def __init__(self):
        sma = bt.indicators.SMA(self.data, period=self.p.period)
        self.crossover = bt.indicators.CrossOver(self.data, sma)

    def next(self):
        if self.crossover > 0:
            self.buy()

        elif self.crossover < 0:
            self.sell()

请注意,该策略如何不考虑当前头寸(通过查看self.position)来决定是否必须实际完成买入或卖出。仅考虑来自的 CrossOver 信号。 Sizers 将负责一切。

sizer 将负责在卖出时仅返回非零大小,如果仓位已经 open

class LongOnly(bt.Sizer):
    params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
      if isbuy:
          return self.p.stake

      # Sell situation
      position = self.broker.getposition(data)
      if not position.size:
          return 0  # do not sell if nothing is open

      return self.p.stake

将它们放在一起(并假设已经导入 backtrader 并且数据已添加到系统中):

...
cerebro.addstrategy(CloseSMA)
cerebro.addsizer(LongOnly)
...
cerebro.run()
...

图表(从源中包含的范例中对此进行测试)。

长短版本只是将SizerFixedReverser更改为如上所示:

...
cerebro.addstrategy(CloseSMA)
cerebro.addsizer(FixedReverser)
...
cerebro.run()
...

输出图表。

请注意差异:

  • 重复的交易数量

  • 现金水平永远不会回到价值,因为策略总是在市场上

这两种方法都是负面的,但这只是一个例子。

Sizer 参考

backtrader类 .Sizer()

这是 Sizers的基类。任何 sizer 都应对此进行子类化并重写该_getsizing 方法

成员单位:

  • strategy:将由 sizer 正在工作的策略设置

    允许访问策略的整个 API,例如,如果需要以下位置_getsizing的实际数据位置:

    position = self.strategy.getposition(data)
    
  • broker:将由 sizer 正在工作的策略设置

    提供对信息的访问,一些复杂的 sizers 可能需要,如投资组合价值,..

_getsizing(通信信息、现金、数据、购买)

此方法必须由 Sizer 的子类覆盖,以提供大小调整功能

参数:

* `comminfo`: The CommissionInfo instance that contains
  information about the commission for the data and allows
  calculation of position value, operation cost, commision for the
  operation

* `cash`: current available cash in the *broker*

* `data`: target of the operation

* `isbuy`: will be `True` for *buy* operations and `False`
  for *sell* operations

该方法必须返回要运行的实际大小(整型)。如果0 返回,则不会运行任何内容。

将使用返回值的绝对值

推荐阅读

相关文章

Backtrader期货补偿与现货补偿

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

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

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

Backtrader跨越数字

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

Backtrader智能质押

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

Backtrader条形同步

文献和/或行业中缺乏标准公式不是问题,因为问题实际上可以总结为: 条形同步 工单 #23 提出了一些问题,即是否可以 backtrader 考虑计算 相对体积 指针。 请求者需要将给定时刻的 volume 与前一个交易日的相同时刻进行比较。

Backtrader python 隐藏的细节

只有当遇到 backtrader 的真实用户时,人们才能意识到平台中使用的抽象和Python功能是否有意义。 在不撇开python的座右铭的情况下, backtrader 试图为用户提供尽可能多的控制权,同时通过将Python提供的隐藏功能付诸行动来简化使用。 第一个示例是系列文章的第一篇。

Backtrader教程:日期时间 - 管理

在 1.5.0 版之前, backtrader 使用直接的方法来进行时间管理,因为数据源计算的任何日期时间都只是按面值使用。 对于任何用户输入也是如此,例如可以提供给任何数据源的参数fromdate (或 sessionstart)的情况 考虑到直接控制冻结的数据源以进行回溯测试,这种方法很好。

Backtrader蟒蛇隐藏的力量3

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

Backtrader卡尔曼等

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

Backtrader终极振荡器

backtrader开发启动时的目标之一是使开发新的指针变得非常容易(至少对作者本人而言),以在数学和视觉上测试想法。 门票#102 是关于将 UltimateOscillator 添加到 backtrader 注意 它将在下一个版本中添加,同时可以使用下面的代码使用它。 票证中所示的参考: 以及: 无需在这里重复。