Backtrader细分佣金计划

  |  

不久前,委员会计划的实施进行了重新设计。最重要的是:涉及的部分返工:

  • 保留原始的佣金信息类和行为

  • 打开大门,轻松创建用户定义的佣金

  • 将格式 xx% 作为新佣金方案的默认值,而不是 0.xx(只是一个品味问题),保持行为可配置

扩展委员会概述了基本要素。

注意

请参阅下面的文档字符串CommInfoBase ,以获取参数参考

定义佣金计划

它涉及1或2个步骤

  1. 子类CommInfoBase

    只需更改缺省参数可能就足够了。backtrader 已经使用模块 backtrader.commissions中存在的一些定义来运行此操作。期货的常规行业标准是每份合约和每轮的固定金额。该定义可以按如下方式完成:

    class CommInfo_Futures_Fixed(CommInfoBase):
        params = (
            ('stocklike', False),
            ('commtype', CommInfoBase.COMM_FIXED),
        )
    

    对于股票和perc明智的佣金:

    class CommInfo_Stocks_Perc(CommInfoBase):
        params = (
            ('stocklike', True),
            ('commtype', CommInfoBase.COMM_PERC),
        )
    

    如上所述,此处百分比(作为参数commission传递)的解释的默认值为: xx%。如果旧的/其他的行为被期望 0.xx,它可以很容易地完成:

    class CommInfo_Stocks_PercAbs(CommInfoBase):
        params = (
            ('stocklike', True),
            ('commtype', CommInfoBase.COMM_PERC),
            ('percabs', True),
        )
    
  2. 重写(如果需要)_getcommission 方法

    定义为:

    def _getcommission(self, size, price, pseudoexec):
       '''Calculates the commission of an operation at a given price
    
       pseudoexec: if True the operation has not yet been executed
       '''
    

    更多细节,请参阅下面的实际范例

如何将其应用于平台

一旦子CommInfoBase 类就位,诀窍就是使用 broker.addcommissioninfo 而不是通常 broker.setcommission的 。后者将在内部使用遗留 CommissionInfoObject

比说的更容易做到:

...

comminfo = CommInfo_Stocks_PercAbs(commission=0.005)  # 0.5%
cerebro.broker.addcommissioninfo(comminfo)

addcommissioninfo 方法定义如下:

def addcommissioninfo(self, comminfo, name=None):
    self.comminfo[name] = comminfo

设置name 意味着该 comminfo 对象将仅应用于具有该名称的资源。默认值 表示 None 它适用于系统中的所有资产。

一个实际的例子

票证#45 询问适用于期货的佣金计划,是百分比明智的,并使用整个合约“虚拟”价值的佣金百分比。即:在佣金计算中包括未来乘数。

这应该很容易:

import backtrader as bt

class CommInfo_Fut_Perc_Mult(bt.CommInfoBase):
    params = (
      ('stocklike', False),  # Futures
      ('commtype', bt.CommInfoBase.COMM_PERC),  # Apply % Commission
    # ('percabs', False),  # pass perc as xx% which is the default
    )

    def _getcommission(self, size, price, pseudoexec):
        return size * price * self.p.commission * self.p.mult

将放入系统:

comminfo = CommInfo_Fut_Perc_Mult(
    commission=0.1,  # 0.1%
    mult=10,
    margin=2000  # Margin is needed for futures-like instruments
)

cerebro.broker.addcommission(comminfo)

如果首选格式0.xx 作为默认值,只需将 param percabs 设置为 True

class CommInfo_Fut_Perc_Mult(bt.CommInfoBase):
    params = (
      ('stocklike', False),  # Futures
      ('commtype', bt.CommInfoBase.COMM_PERC),  # Apply % Commission
      ('percabs', True),  # pass perc as 0.xx
    )

comminfo = CommInfo_Fut_Perc_Mult(
    commission=0.001,  # 0.1%
    mult=10,
    margin=2000  # Margin is needed for futures-like instruments
)

cerebro.broker.addcommissioninfo(comminfo)

这一切都应该可以解决问题。

解释pseudoexec

让我们回想一下以下定义_getcommission

def _getcommission(self, size, price, pseudoexec):
    '''Calculates the commission of an operation at a given price

    pseudoexec: if True the operation has not yet been executed
    '''

arg的目的pseudoexec 可能看起来很晦涩难懂,但它有一个目的。

  • 平台可能会调用此方法对可用现金和其他一些任务进行预计算

  • 这意味着该方法可以(实际上也会)使用相同的参数多次调用。

pseudoexec 指示调用是否对应于订单的实际运行。虽然乍一看这似乎并不「相关」,但如果考虑以下情况:

  • 一旦协商的合约金额超过5000单位,经纪人提供50%的期货往返佣金折扣

    在这种情况下,如果pseudoexec 不存在,则对方法的多个非运行调用将很快触发折扣已到位的假设。

将方案付诸实践:

import backtrader as bt

class CommInfo_Fut_Discount(bt.CommInfoBase):
    params = (
      ('stocklike', False),  # Futures
      ('commtype', bt.CommInfoBase.COMM_FIXED),  # Apply Commission

      # Custom params for the discount
      ('discount_volume', 5000),  # minimum contracts to achieve discount
      ('discount_perc', 50.0),  # 50.0% discount
    )

    negotiated_volume = 0  # attribute to keep track of the actual volume

    def _getcommission(self, size, price, pseudoexec):
        if self.negotiated_volume > self.p.discount_volume:
           actual_discount = self.p.discount_perc / 100.0
        else:
           actual_discount = 0.0

        commission = self.p.commission * (1.0 - actual_discount)
        commvalue = size * price * commission

        if not pseudoexec:
           # keep track of actual real executed size for future discounts
           self.negotiated_volume += size

        return commvalue

希望现在的目的和存在pseudoexec 是明确的。

CommInfoBase docstring and params

在这里:

class CommInfoBase(with_metaclass(MetaParams)):
    '''Base Class for the Commission Schemes.

    Params:

      - commission (def: 0.0): base commission value in percentage or monetary
        units

      - mult (def 1.0): multiplier applied to the asset for value/profit

      - margin (def: None): amount of monetary units needed to open/hold an
        operation. It only applies if the final ``_stocklike`` attribute in the
        class is set to False

      - commtype (def: None): Supported values are CommInfoBase.COMM_PERC
        (commission to be understood as %) and CommInfoBase.COMM_FIXED
        (commission to be understood as monetary units)

        The default value of ``None`` is a supported value to retain
        compatibility with the legacy ``CommissionInfo`` object. If
        ``commtype`` is set to None, then the following applies:

          - margin is None: Internal _commtype is set to COMM_PERC and
            _stocklike is set to True (Operating %-wise with Stocks)

          - margin is not None: _commtype set to COMM_FIXED and _stocklike set
            to False (Operating with fixed rount-trip commission with Futures)

        If this param is set to something else than None, then it will be
        passed to the internal ``_commtype`` attribute and the same will be
        done with the param ``stocklike`` and the internal attribute
        ``_stocklike``

      - stocklike (def: False):  Indicates if the instrument is Stock-like or
        Futures-like (see the ``commtype`` discussion above)

      - percabs (def: False): when ``commtype`` is set to COMM_PERC, whether
        the parameter ``commission`` has to be understood as XX% or 0.XX

        If this param is True: 0.XX
        If this param is False: XX%

    Attributes:

      - _stocklike: Final value to use for Stock-like/Futures-like behavior
      - _commtype: Final value to use for PERC vs FIXED commissions

      This two are used internally instead of the declared params to enable the
      compatibility check described above for the legacy ``CommissionInfo``
      object
    '''

    COMM_PERC, COMM_FIXED = range(2)

    params = (
        ('commission', 0.0), ('mult', 1.0), ('margin', None),
        ('commtype', None),
        ('stocklike', False),
        ('percabs', False),
    )

推荐阅读

相关文章

Backtrader向 OHLC 提供买入价/卖出价数据

最近,backtrader通过实现line覆盖来运行从 ohlc-land 逃逸,这允许重新定义整个层次结构,例如,具有仅具有 bid,ask 和 datetime lines的data feeds。

Backtrader细分佣金计划

不久前,委员会计划的实施进行了重新设计。最重要的是:涉及的部分返工: 保留原始的佣金信息类和行为 打开大门,轻松创建用户定义的佣金 将格式 xx% 作为新佣金方案的默认值,而不是 0.xx(只是一个品味问题),保持行为可配置 扩展委员会概述了基本要素。

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

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

Backtrader教程:操作平台

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

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

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

BacktraderPyFolio 集成

注意 2017年2月 pyfolio API 已更改,不再 create_full_tear_sheet 具有 gross_lev 作为命名参数的参数。

Backtrader教程:过滤器 - 参考

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

数据多时间帧

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

Backtraderta-lib 集成

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

Backtrader教程:佣金计划 - 信贷利息

在某些情况下,真实经纪人的现金金额可能会减少,因为资产操作包括利率。例子: 卖空股票 交易所买卖基金包括多头和空头 该费用直接与经纪人帐户中的现金余额挂钩。但它仍然可以被视为佣金计划的一部分。因此,它已被建模为 backtrader。