Backtrader 教程:佣金計劃 - 自定義計劃

  |  

將 CommInfo 對象改造成實際涉及的最重要的部分:

  • 保留原來的CommissionInfo類和行為

  • 為輕鬆創建用戶定義的佣金打開大門

  • 使格式 xx% 成為新佣金方案的默認值,而不是 0.xx(只是個人喜好問題),保持行為可配置

筆記

請參閱下面的CommInfoBase文檔字符串以獲取參數參考

定義佣金計劃

它涉及 1 或 2 個步驟

  1. 子類CommInfoBase

    只需更改默認參數就足夠了。 backtrader已經使用模塊backtrader .commissions中的一些定義來做到這一點。期貨的常規行業標準是每份合約和每輪固定金額。定義可以如下:

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

    對於股票和 perc-wise 佣金:

    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意味著它適用於系統中的所有資產。

一個實際的例子

Ticket #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.addcommissioninfo(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.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
    '''

pseudoexec arg 的目的可能看起來晦澀難懂,但它是有目的的。

  • 平台可能會調用該方法來進行可用現金的預計算和一些其他任務

  • 這意味著該方法可能(並且實際上會)使用相同的參數多次調用

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 文檔字符串和參數

請參閱佣金:股票與期貨以供CommInfoBase參考

推薦閱讀

相關文章

Backtrader優化改進

backtrader 1.8.12.99版改進了多處理期間數據饋送和結果的管理方式。

Backtrader寫下來

隨著 1.1.7.88 版本的發布, backtrader有了一個新的補充:作家這可能早就到期了,應該已經存在了,問題 #14中的討論也應該已經開始了開發。但遲到總比沒有好。

Backtrader 教程:佣金計劃

不可知論在繼續之前,讓我們記住, backtrader者試圖對數據代表什麼保持不可知論。不同的佣金方案可以應用於相同的數據集。讓我們看看它是如何做到的。使用代理快捷方式這使最終用戶遠離CommissionInfo對象,因為可以通過單個函數調用創建/設置佣金方案。

Backtrader觀察員和統計

在 backtrader 內部運行的策略主要處理數據 和 指標。 數據被添加到Cerebro 實例中,並最終成為策略輸入的一部分(解析並用作實例的屬性),而指標由策略本身聲明和管理。

Backtrader訂單歷史

通過發佈1.9.55.122, backtrader 現在可用於評估一組外部訂單的性能。

Backtrader教程:數據饋送

backtrader 附帶一組 Data Feed 解析器(在編寫所有基於CSV時),可讓您從不同的來源載入數據。

Backtrader教程:過濾器 - 參考

工作階段篩檢程式 類 backtrader.filters。

Backtrader卡爾曼等

注意 對以下指令的支援從提交開始 發佈1.9.30.x 將是包含它的第1個版本 。 backtrader的原始目標之一是成為純python,即:僅使用標準發行版中可用的軟體包。只有一個例外是matplotlib在沒有重新發明輪子的情況下進行繪圖。

Backtrader教程:指標 - ta-lib

即使 backtrader 提供了已經 high 數量的內置指標,並且開發指標主要是定義輸入,輸出和以自然的方式編寫公式的問題,有些人也希望使用TA-LIB。

Backtrader終極振蕩器

backtrader開發啟動時的目標之一是使開發新的指標變得非常容易(至少對作者本人而言),以在數學和視覺上測試想法。 門票#102 是關於將 UltimateOscillator 添加到 backtrader 注意 它將在下一個版本中添加,同時可以使用下面的代碼使用它。 票證中所示的參考: 以及: 無需在這裡重複。