不久前,委員會計劃的實施進行了重新設計。最重要的是:涉及的部分返工:
-  
保留原始的傭金資訊類和行為
 -  
打開大門,輕鬆創建使用者定義的傭金
 -  
將格式 xx% 作為新傭金方案的預設值,而不是 0.xx(只是一個品味問題),保持行為可配置
 
擴展委員會概述了基本要素。
注意
請參閱下面的文件字串CommInfoBase ,以獲取參數參考
定義傭金計劃
它涉及1或2個步驟
-  
子類
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), ) -  
重寫(如果需要)
_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),
    )