Backtrader教程:篩檢程式

  |  

此功能是 backtrader 的相對較新的補充,必須安裝到已經存在的內部結構中。這使得它不像希望的那樣靈活且100%功能齊全,但在許多情況下它仍然可以達到目的。

儘管該實現試圖允許隨插即用的篩檢程式連結,但預先存在的內部結構使得很難確保始終可以實現。因此,某些篩選器可能是連結的,而其他一些篩選器可能不是。

目的

  • 轉換 data feed 提供的值以提供不同的 data feed

該實現的開始是為了簡化兩個明顯的篩檢程式的實現,這兩個篩檢程式可以通過 cerebro API直接使用。這些是:

  • 重採樣 (cerebro.resampledata

    這個處,篩選器轉換timeframe傳入data feed的與 compression 。例如:

    (Seconds, 1) -> (Days, 1)
    

    這意味著原始 data feed 是解析度為 1 秒的交割柱。重採樣篩選器截獲數據並對其進行緩衝,直到它可以提供 1 天柱。當看到第二天的 1 秒柱線時,就會發生這種情況。

  • 重播 (cerebro.replaydata

    對於與上述相同的時間範圍,篩檢程式將使用1秒解析度柱來重建1日柱。

    這意味著 1 日柱的傳遞次數與看到 1 秒柱的次數一樣多,並更新以包含最新資訊。

    例如,這類比了實際交易日是如何形成的。

    注意

    數據的長度,len(data) 因此只要日期不改變,策略的長度就保持不變。

工作中的篩檢程式

給定現有的 data feed/source,addfilter 您可以使用 data feed的方法:

data = MyDataFeed(dataname=myname)
data.addfilter(filter, *args, **kwargs)
cerebro.addata(data)

即使它碰巧與重採樣/重放過濾器相容,也可以執行以下操作:

data = MyDataFeed(dataname=myname)
data.addfilter(filter, *args, **kwargs)
cerebro.replaydata(data)

過濾器介面

必須filter 符合給定的介面,如下所示:

  • 接受此簽章的可呼叫物件:

    callable(data, *args, **kwargs)
    

  • 可以實例化和調用的類

    • 在實例化期間, __init__ 該方法必須支持簽名:
    def __init__(self, data, *args, **kwargs)
    
    • __call__ 方法帶有以下簽名:
    def __call__(self, data, *args, **kwargs)
    

    將為每個來自 data feed的新傳入值調用該實例。和\*args \*kwargs 是相同的傳遞給 __init__

    返回值

    * `True`: the inner data fetching loop of the data feed must retry
      fetching data from the feed, becaue the length of the stream was
      manipulated
    
    * `False` even if data may have been edited (example: changed
      `close` price), the length of the stream has remain untouched
    

    在基於類的篩檢程式的情況下,可以實現其他方法

    • last 具有以下簽名:
    def last(self, data, *args, **kwargs)
    

    這將在 data feed 結束時調用,允許篩選器提供它可能具有例如緩衝的數據。典型的情況是重新採樣,因為柱線被緩衝,直到看到下一個時間段的數據。 data feed 結束后,沒有新數據可以將緩衝數據推出。

    last 提供將緩衝數據推出的機會。

注意

很明顯,如果篩檢程式根本不支援任何參數,並且將添加沒有任何參數,則可以簡化簽名,如下所示:

def __init__(self, data, *args, **kwargs) -> def __init__(self, data)

示例篩選器

一個非常快速的過濾器實現:

class SessionFilter(object):
    def __init__(self, data):
        pass

    def __call__(self, data):
        if data.p.sessionstart <= data.datetime.time() <= data.p.sessionend:
            # bar is in the session
            return False  # tell outer data loop the bar can be processed

        # bar outside of the regular session times
        data.backwards()  # remove bar from data stack
        return True  # tell outer data loop to fetch a new bar

此篩選器:

  • 使用data.p.sessionstartdata.p.sessionend (標準 data feed 參數)來決定柱線是否在會話中。

  • 如果在會話中,則返回值False 指示未執行任何操作,並且當前柱的處理可以繼續

  • 如果不在會話中,則該欄將從流中刪除並True 返回以指示必須獲取新欄。

    注意

    介面data.backwards()LineBuffer 用途。這深入挖掘了 backtrader的內部。

此過濾器的使用:

  • 一些 data feeds 包含非正常交易時間數據,交易者可能對此不感興趣。使用此篩選器時,將僅考慮會話中柱。

用於篩選器的數據偽 API

在上面的範例中,已顯示篩選器如何調用data.backwards() 以從流中刪除當前柱。來自 data feed 物件的有用呼叫(旨在作為過濾器的偽 API)是:

  • data.backwards(size=1, force=False):通過向後移動邏輯指標從數據流中刪除大小條(預設值為 1)。如果 force=True為 ,則物理存儲也將被刪除。

    刪除物理存儲是一項精細的操作,僅用作內部操作的駭客攻擊。

  • data.forward(value=float('NaN'), size=1):將存儲向前移動大小條,如果需要,增加物理存儲並填充 value

  • data._addtostack(bar, stash=False):添加到bar堆疊以供以後處理。bar是一個可反覆運算的可反覆運算,其中包含與 data feed一樣lines多的值。

    如果stash=False 添加到堆疊中的柱將在下一次反覆運算開始時立即被系統消耗。

    如果stash=True 柱線將經歷整個循環處理,包括可能被篩檢程式重新解析

  • data._save2stack(erase=False, force=False):將當前數據列保存到堆疊中以供以後處理。如果 erase=Truedata.backwards 將被調用並將接收參數 force

  • data._updatebar(bar, forward=False, ago=0):使用可 bar 反覆運算中的值來覆蓋資料流 ago 位置中的值。使用預設值 ago=0 時,當前柱將更新。與 -1,上一個。

另一個例子:粉紅魚篩檢程式

這是一個可以連結到另一個篩檢程式(即重播篩檢程式)的過濾器的示例,並且意味著如此。Pinkfish這個名字來自圖書館,該圖書館在其主頁上描述了這個想法:使用每日數據來執行只有日內數據才能實現的操作。

要達到以下效果:

  • 每日柱線將分為 2 個分量:OHL 然後 C

  • 這兩個部分通過重播連結在一起,以便在流中發生以下情況:

    With Len X     -> OHL
    With Len X     -> OHLC
    With Len X + 1 -> OHL
    With Len X + 1 -> OHLC
    With Len X + 2 -> OHL
    With Len X + 2 -> OHLC
    ...
    

邏輯:

  • 當收到柱OHLC 線時,它被複製到一個可插入的柱中,並分解為:

    • 酒吧OHL 。因為這個概念實際上並不存在,所以收盤價被開盤價所取代,以真正形成一個 OHLO 柱線。

    • 一個C 也不存在的欄。現實情況是,它將像蜱蟲一樣交付 CCCC

    • 如果分佈在兩個部分之間的volume

    • 當前條形圖已從流中刪除

    • OHLO 零件放入堆疊上進行即時處理

    • CCCC 零件放入儲藏室中,以便在下一輪中進行處理

    • 由於堆疊具有可立即處理的內容,因此篩選器可以返回False 以指示它。

此篩選器可與以下各項配合使用:

  • 重播篩檢程式將 和 CCCC 部分組合在一起OHLO,最終提供條OHLC形圖。

用例:

  • 看到這樣的事情,如果今天的最大值是last20個會話中的最高最大值,則發出一個訂單,該訂單以第2個Close價格變動執行。

代碼:

class DaySplitter_Close(bt.with_metaclass(bt.MetaParams, object)):
    '''
    Splits a daily bar in two parts simulating 2 ticks which will be used to
    replay the data:

      - First tick: ``OHLX``

        The ``Close`` will be replaced by the *average* of ``Open``, ``High``
        and ``Low``

        The session opening time is used for this tick

      and

      - Second tick: ``CCCC``

        The ``Close`` price will be used for the four components of the price

        The session closing time is used for this tick

    The volume will be split amongst the 2 ticks using the parameters:

      - ``closevol`` (default: ``0.5``) The value indicate which percentage, in
        absolute terms from 0.0 to 1.0, has to be assigned to the *closing*
        tick. The rest will be assigned to the ``OHLX`` tick.

    **This filter is meant to be used together with** ``cerebro.replaydata``

    '''
    params = (
        ('closevol', 0.5),  # 0 -> 1 amount of volume to keep for close
    )

    # replaying = True

    def __init__(self, data):
        self.lastdt = None

    def __call__(self, data):
        # Make a copy of the new bar and remove it from stream
        datadt = data.datetime.date()  # keep the date

        if self.lastdt == datadt:
            return False  # skip bars that come again in the filter

        self.lastdt = datadt  # keep ref to last seen bar

        # Make a copy of current data for ohlbar
        ohlbar = [data.lines[i][0] for i in range(data.size())]
        closebar = ohlbar[:]  # Make a copy for the close

        # replace close price with o-h-l average
        ohlprice = ohlbar[data.Open] + ohlbar[data.High] + ohlbar[data.Low]
        ohlbar[data.Close] = ohlprice / 3.0

        vol = ohlbar[data.Volume]  # adjust volume
        ohlbar[data.Volume] = vohl = int(vol * (1.0 - self.p.closevol))

        oi = ohlbar[data.OpenInterest]  # adjust open interst
        ohlbar[data.OpenInterest] = 0

        # Adjust times
        dt = datetime.datetime.combine(datadt, data.p.sessionstart)
        ohlbar[data.DateTime] = data.date2num(dt)

        # Ajust closebar to generate a single tick -> close price
        closebar[data.Open] = cprice = closebar[data.Close]
        closebar[data.High] = cprice
        closebar[data.Low] = cprice
        closebar[data.Volume] = vol - vohl
        ohlbar[data.OpenInterest] = oi

        # Adjust times
        dt = datetime.datetime.combine(datadt, data.p.sessionend)
        closebar[data.DateTime] = data.date2num(dt)

        # Update stream
        data.backwards(force=True)  # remove the copied bar from stream
        data._add2stack(ohlbar)  # add ohlbar to stack
        # Add 2nd part to stash to delay processing to next round
        data._add2stack(closebar, stash=True)

        return False  # initial tick can be further processed from stack

推薦閱讀

相關文章

Backtrader向 OHLC 提供買入價/賣出價數據

最近,backtrader通過實現line覆蓋來執行從 ohlc-land 逃逸,這允許重新定義整個層次結構,例如,具有僅具有 bid,ask 和 datetime lines的data feeds。

Backtrader按日線交易

似乎在世界某個地方有一種权益(Interest)可以總結如下: 使用每日柱線引入訂單,但使用開盤價 這來自工單#105订单执行逻辑与当前数据和#101动态投注计算中的對話 backtrader 嘗試盡可能保持現實,並且在處理每日柱線時適用以下前提: 當每日柱被評估時,柱線已經結束 這是有道理的,

Backtrader教程:經紀人 - 開倉作弊

“發佈”1.9.44.116 添加了對 Cheat-On-Open的支援。這似乎是那些全力以赴的人的需求功能,他們在酒吧 close 后進行了計算,但希望與 open 價格相匹配。 當開盤價跳空(上漲或下跌,取決於是否buysell有效)並且現金不足以進行全面運營時,這樣的用例就會失敗。這將強制代理拒絕該操作。

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

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

Backtrader教程:過濾器 - 參考

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

Backtrader智慧質押

版本 1.6.4.93 標誌著 backtrader 的一個重要里程碑,即使版本號的更改很小。 職位大小調整是閱讀Van K. Tharp的《Trade Your Way To Financial Freedom 》後,為這個專案奠定基礎的事情之一。

Backtrader混合時間幀

1.3.0.92版本帶來了混合來自不同時間幀的數據(來自 data feeds 和/或指標)的可能性。 到版本:https://github.com/mementum/backtrader/發佈/標籤/1.3.0.92 背景:指示器是智慧啞物件。 他們很聰明,因為他們可以進行複雜的計算。

Backtrader多數據範例

社區中的幾個主題似乎以如何跟蹤訂單為導向,特別是當幾個data feeds在起作用時,還包括當多個訂單一起工作時,

Backtrader信貸利息

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

Backtrader動量策略

在另一篇偉大的文章中,泰迪·科克(Teddy Koker)再次展示了演算法交易策略的發展之路: 研究優先應用 pandas 回溯測試,然後使用 backtrader 榮譽!!! 該帖子可以在以下位置找到: 泰迪·科克(Teddy Koker)給我留言,問我是否可以評論 backtrader的用法。