Backtrader教程:指標 - 開發

  |  

如果必須開發任何東西(除了一個或多個獲勝策略之外),那麼這個東西就是一個自定義指標。

根據作者的說法,平臺內的這種開發很容易。

需要滿足以下條件:

  • 從指標派生的類(直接或從現有的子類派生)

  • 定義它將保持lines

    指標必須至少具有 1 line。如果從現有派生,則可能已定義line

  • (可選)定義可以改變行為的參數

  • 可選地提供/自定義一些元素,這些元素可以合理地繪製指標

  • 提供__init__ 完全定義的操作,並將綁定(賦值)到指標的 line,或者提供 next 和(可選) once 方法

    如果在初始化期間可以使用邏輯/算術運算完全定義指標,並將結果分配給 line: 完成

    如果不是這種情況,至少必須提供 anext ,其中指標必須為索引 0 處的 line賦值

    通過提供一次方法,可以優化運行 模式(批處理操作)的計算。

重要提示:冪等性

指標為它們收到的每個柱產生一個輸出。無需假設同一柱將被發送多少次。操作必須是冪等的。

這背後的基本原理:

  • 同一根柱線(指數方面)可以多次發送,值會發生變化(即變化的值是收盤價)

例如,這可以「重放」每日會話,但使用可以由5分鐘柱組成的日內數據。

它還可以允許平臺從即時源中獲取值。

虛擬(但功能性)指示器

那麼它可以是:

class DummyInd(bt.Indicator):
    lines = ('dummyline',)

    params = (('value', 5),)

    def __init__(self):
        self.lines.dummyline = bt.Max(0.0, self.params.value)

做!指標將始終輸出相同的值:0.0 或 self.params.value(如果它恰好大於 0.0)。

相同的指標,但使用下一個方法:

class DummyInd(bt.Indicator):
    lines = ('dummyline',)

    params = (('value', 5),)

    def next(self):
        self.lines.dummyline[0] = max(0.0, self.params.value)

做!相同的行為。

注意

請注意如何在__init__ 版本中 bt.Max 用於分配給 Line 物件 self.lines.dummyline

bt.Max 返回一個 lines 物件,該對象針對傳遞給指標的每個柱自動反覆運算。

如果max 被使用,assigment將是毫無意義的,因為指標將具有具有固定值的成員變數,而不是 line

在工作期間next 直接使用浮點值完成,並且可以使用標準 max 內置

讓我們回想一下,self.lines.dummyline 這是長符號,它可以縮短為:

  • self.l.dummyline

甚至:

  • self.dummyline

後者只有在代碼沒有用成員屬性遮蓋它時才有可能。

第 3 和第 last 版提供了優化計算的附加 once 方法:

class DummyInd(bt.Indicator):
    lines = ('dummyline',)

    params = (('value', 5),)

    def next(self):
        self.lines.dummyline[0] = max(0.0, self.params.value)

    def once(self, start, end):
       dummy_array = self.lines.dummyline.array

       for i in xrange(start, end):
           dummy_array[i] = max(0.0, self.params.value)

更有效,但開發該once 方法已迫使划傷表面。實際上,已經研究了膽量。

無論如何,該__init__ 版本都是最好的:

  • 一切都局限於初始化

  • nextonce (兩者都經過優化,因為 bt.Max 已經有了它們)自動提供,無需使用索引和/或公式

無論是開發需要的,指標還可以覆蓋與 和 once相關的next方法:

  • prenextnexstart

  • preonceoncestart

手動/自動最短週期

如果可能的話,平臺將計算它,但可能需要手動操作。

以下是簡單移動平均線的潛在實現:

class SimpleMovingAverage1(Indicator):
    lines = ('sma',)
    params = (('period', 20),)

    def next(self):
        datasum = math.fsum(self.data.get(size=self.p.period))
        self.lines.sma[0] = datasum / self.p.period

雖然看起來不錯,但平臺不知道最小周期是什麼,即使參數被命名為“period”(名稱可能具有誤導性,並且某些指標會收到幾個具有不同用法的“period”)

在這種情況下next ,已經調用了第1 柱,並且everthing會爆炸,因為get無法返回所需的 self.p.period

在解決這種情況之前,必須考慮一些事情:

  • 傳遞給指標的 data feeds 可能已經具有 最小週期

示例 SimpleMovingAverage 可以在例如以下方面完成:

  • 一般 data feed

    這有一個預設的最小週期 1 (只需等待進入系統的第 1 根 柱線)

  • 另一條移動平均線...而這又已經有一個句號

    如果這是 20,並且我們的樣本移動平均線也有 20,我們最終得到的最小週期為 40 根柱線

    實際上,內部計算顯示39 ...因為一旦第一條移動平均線產生了一根柱線,這就會計入下一條移動平均線,這會創建一個重疊的柱線,因此需要39個。

  • 其他也帶有周期的指標/物件

緩解這種情況的做法如下:

class SimpleMovingAverage1(Indicator):
    lines = ('sma',)
    params = (('period', 20),)

    def __init__(self):
        self.addminperiod(self.params.period)

    def next(self):
        datasum = math.fsum(self.data.get(size=self.p.period))
        self.lines.sma[0] = datasum / self.p.period

addminperiod 方法是告訴系統考慮該指標所需的額外週期柱,以達到可能存在的任何最小週期。

有時,如果所有計算都是使用已經將其週期需求傳達給系統的物件完成的,則絕對不需要這樣做。

使用直方圖的快速 MACD 實現:

from backtrader.indicators import EMA

class MACD(Indicator):
    lines = ('macd', 'signal', 'histo',)
    params = (('period_me1', 12), ('period_me2', 26), ('period_signal', 9),)

    def __init__(self):
        me1 = EMA(self.data, period=self.p.period_me1)
        me2 = EMA(self.data, period=self.p.period_me2)
        self.l.macd = me1 - me2
        self.l.signal = EMA(self.l.macd, period=self.p.period_signal)
        self.l.histo = self.l.macd - self.l.signal

做!無需考慮最小週期。

  • EMA 代表指數移動平均線(平臺內置別名)

    這個(已經在平臺中)已經說明瞭它需要什麼

  • 指標 「macd」 和 「signal」 的命名 lines 正在被分配對象,這些對象已經帶有聲明的(幕後)週期

    • macd 從操作「me1 - me2」中獲取週期,而操作又從 me1 和 me2 的週期中獲取最大值(這兩個週期都是具有不同週期的指數移動平均線)

    • 信號直接取麥克德上指數移動平均線的週期。此 EMA 還考慮了已經存在的 macd 週期和計算自身所需的樣本量 (period_signal)

    • histo 取兩個操作數“信號 - macd”中的最大值。一旦兩者都準備好了,histo也可以產生價值

完整的自訂指標

讓我們開發一個簡單的自定義指標,它「指示」移動平均線(可以用參數修改)是否高於給定數據:

import backtrader as bt
import backtrader.indicators as btind

class OverUnderMovAv(bt.Indicator):
    lines = ('overunder',)
    params = dict(period=20, movav=btind.MovAv.Simple)

    def __init__(self):
        movav = self.p.movav(self.data, period=self.p.period)
        self.l.overunder = bt.Cmp(movav, self.data)

做!如果平均值高於數據,則指標的值為“1”;如果低於數據,則指標的值為“-1”。

作為常規 data feed 1和-1將與 close 價格相比產生1和-1的數據。

雖然在繪圖部分可以看到更多,並且在繪圖世界中有一個舉止和善良的公民,但可以添加一些東西:

import backtrader as bt
import backtrader.indicators as btind

class OverUnderMovAv(bt.Indicator):
    lines = ('overunder',)
    params = dict(period=20, movav=bt.ind.MovAv.Simple)

    plotinfo = dict(
        # Add extra margins above and below the 1s and -1s
        plotymargin=0.15,

        # Plot a reference horizontal line at 1.0 and -1.0
        plothlines=[1.0, -1.0],

        # Simplify the y scale to 1.0 and -1.0
        plotyticks=[1.0, -1.0])

    # Plot the line "overunder" (the only one) with dash style
    # ls stands for linestyle and is directly passed to matplotlib
    plotlines = dict(overunder=dict(ls='--'))

    def _plotlabel(self):
        # This method returns a list of labels that will be displayed
        # behind the name of the indicator on the plot

        # The period must always be there
        plabels = [self.p.period]

        # Put only the moving average if it's not the default one
        plabels += [self.p.movav] * self.p.notdefault('movav')

        return plabels

    def __init__(self):
        movav = self.p.movav(self.data, period=self.p.period)
        self.l.overunder = bt.Cmp(movav, self.data)

推薦閱讀

相關文章

Backtrader教程:指標 - 開發

如果必須開發任何東西(除了一個或多個獲勝策略之外),那麼這個東西就是一個自定義指標。 根據作者的說法,平臺內的這種開發很容易。 需要滿足以下條件: 從指標派生的類(直接或從現有的子類派生) 定義它將保持lines 指標必須至少具有 1 line。

Backtrader期貨補償與現貨補償

版本1.9.32.116 增加了對社區中呈現的有趣用例 的支援 以期貨開始交易,包括實物交割 讓一個指標告訴你一些事情 如果需要, close 現貨價格操作,有效地取消實物交割,無論是為了接收貨物還是為了必須交付貨物(並希望獲利)來頭寸。

Backtrader教程:日誌記錄 - 編寫器

將以下內容寫出到流中: csv 流,

Backtrader教程:數據饋送 - 擴展 (Extending DataFeed)

GitHub 中的問題實際上是在推動文檔部分的完成,或者説明我瞭解我是否backtrader 具有我從一開始就設想的易用性和靈活性以及在此過程中做出的決定。 在本例中為問題 #9。

Backtrader跨越數位

《backtrader》的發佈1.9.27.105糾正了一個疏忽。這是一個疏忽,因為拼圖的所有部分都已到位,但啟動並不是在所有角落都進行的。 該機制使用一個名為的屬性_mindatas,因此讓我們將其稱為: mindatas。 社區問了這個問題,答案並不是很到位。

Backtrader數據多時間幀

有時投資決策是使用不同的時間框架做出的: 每周評估趨勢 每天執行條目 或者5分鐘對60分鐘。 這意味著需要將多個時間幀的數據組合在 backtrader 中以支援此類組合。 對它的本機支持已經內置。

Backtraderta-lib 集成

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

Backtrader教程:數據饋送 - 熊貓

注意 pandas 並且必須安裝其依賴項 支援Pandas Dataframes似乎受到很多人的關注,他們依賴於已經可用的解析代碼來分析不同的數據源(包括CSV)和Pandas提供的其他功能。 數據饋送的重要聲明。 注意 這些只是 聲明。不要盲目複製此代碼。

Backtrader教程:分析儀 - PyFolio

注意 從(至少)2017-07-25pyfolio 開始,API已更改,不再 create_full_tear_sheet 具有 gross_lev 作為命名參數的參數。

Backtrader信貸利息

在某些情況下,真實經紀人的現金金額可能會減少,因為資產操作包括利率。例子: 賣空股票 交易所買賣基金包括多頭和空頭 這意味著不僅交易構成了系統的盈利能力,因為信貸上的利息在帳戶上佔有一席之地。 為了涵蓋這種情況, backtrader 包括(從發佈1.8.8.96開始)功能來考慮這一點。