用户定义的佣金
委员会计划的执行不久前进行了修改。最重要的:涉及的返工部分:
- 
保留类和行为的原始 CommissionInfo 
- 
打开大门,轻松创建用户定义的佣金 
- 
使新佣金方案的默认格式为 xx%,而不是 0.xx(只是口味问题),保持行为可配置 
在延长佣金方面概述了基本情况。
笔记
参数参考见下文CommInfoBase的文档串
确定佣金方案
它包括 1 到 2 个步骤
- 
子类化 CommInfoBase只需更改默认参数就足够了。 backtrader已经在模块backtrader.commissions中提供了一些定义。期货的常规行业标准是每笔合约和每轮交易的固定金额。定义如下:py class CommInfo_Futures_Fixed(CommInfoBase): params = ( ('stocklike', False), ('commtype', CommInfoBase.COMM_FIXED), )对于股票和 perc-wise 佣金: py class CommInfo_Stocks_Perc(CommInfoBase): params = ( ('stocklike', True), ('commtype', CommInfoBase.COMM_PERC), )如上所述,此处解释百分比(作为参数 commission传递)的默认值为:xx%。如果希望旧的/其他行为0.xx,则可以轻松完成:py class CommInfo_Stocks_PercAbs(CommInfoBase): params = ( ('stocklike', True), ('commtype', CommInfoBase.COMM_PERC), ('percabs', True), )
- 
覆盖 _getcommission方法(如果需要)定义为: ```py 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的默认值表示它适用于系统中的所有资产。
实例
Ticket询问一种适用于期货的佣金方案,该方案是按百分比计算的,并在整个合同“虚拟”价值上使用佣金百分比。ie:包括佣金计算中的未来乘数。
这应该很容易:
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,只需将参数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
    ''' 
pseudoexecarg 的目的可能看起来很模糊,但它是有目的的。
- 
平台可以调用此方法来预计算可用现金和其他一些任务 
- 
这意味着该方法可以(实际上也将)使用相同的参数多次调用 
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 文档字符串和参数
这是:
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),
    ) 

