Backtrader動態指標

  |  

指標是困難的野獸。不是因為它們通常難以編碼,而是主要是因為名稱具有誤導性,並且人們對指標是什麼有不同的期望。

讓我們嘗試至少定義什麼是反向交易者生態系統中的指標。

它是一個定義至少一個輸出的對象,可以定義影響其行為的參數,並將一個或多個數據饋送作為輸入。

為了使指標盡可能通用,選擇了以下設計原則:

  • 輸入數據饋送可以是任何看起來像數據饋送的東西,這帶來了直接的優勢:因為其他指標看起來像數據饋送,所以可以將指標作為輸入傳遞給其他指標

  • 不攜帶datetime時間有效負載。之所以如此,是因為輸入本身可能沒有要同步的datetime時間有效負載。與一般系統範圍的datetime時間同步可能是不正確的,因為該指標可能使用每週時間範圍內的數據,而係統時間可能以秒為單位,因為這是幾個數據饋送中最低的分辨率之一。

  • 操作必須是冪等的,即:如果使用相同的輸入調用兩次且參數不變,則輸出必須相同。

    考慮到可以要求指標在同一時間點以相同的輸入多次執行操作。雖然這似乎不需要,但如果系統支持數據重放(即:從較小的時間幀實時構建較大的時間幀)

  • 最後:指標將其輸出值寫入當前時刻,即:索引0 。如果不是,它將命名為Study 。一項Study將尋找模式並寫入過去的輸出值。

    例如,參見Backtrader社區 - ZigZag

一旦定義(在反向交易者生態系統中)明確,讓我們嘗試看看我們如何實際編寫動態指標。看起來我們不能,因為從前面提到的設計原則來看,指標的操作過程或多或少是……不可變的。

最高的……因為……

通常啟動的一個指標是Highest (別名MaxN ),以在給定時期內獲得最高的東西。如在

import backtrader as bt

class MyStrategy(bt.Strategy)
    def __init__(self):
        self.the_highest_high_15 = bt.ind.Highest(self.data.high, period=15)

    def next(self):
        if self.the_highest_high_15 > X:
            print('ABOUT TO DO SOMETHING')

在這個片段中,我們實例化Highest以跟踪過去15 個週期的最高點。如果最高點大於X ,就可以做點什麼。

這裡的問題:

  • period固定為15

讓它充滿活力

有時,我們需要指標是動態的並改變其行為以對實時條件做出反應。例如,請參閱backtrader社區中的這個問題: Highest high since position was open

我們當然不知道何時開倉/平倉,將period設置為固定值(如15 )是沒有意義的。讓我們看看我們如何做到這一點,將所有內容打包在一個指標中

動態參數

我們將首先使用我們將在指標生命週期內更改的參數,從而實現動態。

import backtrader as bt

class DynamicHighest(bt.Indicator):
    lines = ('dyn_highest',)
    params = dict(tradeopen=False)

    def next(self):
        if self.p.tradeopen:
            self.lines.dyn_highest[0] = max(self.data[0], self.dyn_highest[-1])

class MyStrategy(bt.Strategy)
    def __init__(self):
        self.dyn_highest = DynamicHighest(self.data.high)

    def notify_trade(self, trade):
        self.dyn_highest.p.tradeopen = trade.isopen

    def next(self):
        if self.dyn_highest > X:
            print('ABOUT TO DO SOMETHING')

瞧!我們擁有它,到目前為止,我們還沒有違反為我們的指標制定的規則。我們來看看指標

  • 它定義了一個名為dyn_highest的輸出

  • 它有一個參數tradeopen= False

  • (是的,它需要數據饋送,僅僅是因為它是Indicator的子類)

  • 如果我們總是用相同的輸入調用next ,它總是會返回相同的值

唯一的事情:

  • 如果參數的值改變了,輸出就會改變(上面的規則說只要參數不改變,輸出就保持不變)

我們在notify_trade中使用它來影響我們的DynamicHighest

  • 我們使用通知trade的值isopen作為一個標誌來知道我們是否必須記錄輸入數據的最高點

  • trade結束時, isopen的值為False ,我們將停止記錄最高值

如需參考,請參閱: Backtrader文檔交易

簡單的!!!

使用方法

有些人會反對修改作為指標聲明一部分的param ,並且只應在實例化期間設置。

好吧,我們來找個方法。

import backtrader as bt

class DynamicHighest(bt.Indicator):
    lines = ('dyn_highest',)

    def __init__(self):
        self._tradeopen = False

    def tradeopen(self, yesno):
        self._tradeopen = yesno

    def next(self):
        if self._tradeopen:
            self.lines.dyn_highest[0] = max(self.data[0], self.dyn_highest[-1])

class MyStrategy(bt.Strategy)
    def __init__(self):
        self.dyn_highest = DynamicHighest(self.data.high)

    def notify_trade(self, trade):
        self.dyn_highest.tradeopen(trade.isopen)

    def next(self):
        if self.dyn_highest > X:
            print('ABOUT TO DO SOMETHING')

差別不大,但現在該指標有一些額外的樣板,帶有__init__和方法tradeopen(self, yesno) 。但是我們DynamicHighest的動態是相同的。

獎勵:讓它通用

讓我們恢復params並製作一個可以應用不同功能的指標,而不僅僅是max

import backtrader as bt

class DynamicFn(bt.Indicator):
    lines = ('dyn_highest',)
    params = dict(fn=None)

    def __init__(self):
        self._tradeopen = False
        # Safeguard for not set function
        self._fn = self.p.fn or lambda x, y: x

    def tradeopen(self, yesno):
        self._tradeopen = yesno

    def next(self):
        if self._tradeopen:
            self.lines.dyn_highest[0] = self._fn(self.data[0], self.dyn_highest[-1])

class MyStrategy(bt.Strategy)
    def __init__(self):
        self.dyn_highest = DynamicHighest(self.data.high, fn=max)

    def notify_trade(self, trade):
        self.dyn_highest.tradeopen(trade.isopen)

    def next(self):
        if self.dyn_highest > X:
            print('ABOUT TO DO SOMETHING')

說完了!我們添加了:

  • params=dict(fn=None)

    收集最終用戶想要使用的功能

  • 如果用戶未傳遞特定函數,則使用佔位符函數的保護措施:

    # Safeguard for not set function
    self._fn = self.p.fn or lambda x, y: x
    
  • 我們使用函數(或占位符)進行計算:

    self.lines.dyn_highest[0] = self._fn(self.data[0], self.dyn_highest[-1])
    
  • 在調用我們的(現在命名的) DynamicFn指標時說明我們想要使用哪個函數…… max (這裡沒有意外):

    self.dyn_highest = DynamicHighest(self.data.high, fn=max)
    

今天所剩無幾……盡情享受吧!!!

推薦閱讀

相關文章

Backtrader教程:經紀人 - 體積灌裝 - 灌裝機

backtrader經紀商類比在使用volume執行訂單時具有預設策略: 忽略 volume 這是基於2個前提: 在市場中交易的流動性足以一次性完全吸收買入/賣出訂單 真正的 volume 匹配需要真正的狼 一個簡單的例子是Fill or Kill 訂單。

Backtrader對逐筆報價數據重新取樣

backtrader 已經可以從分鐘數據中重新採樣。接受價格變動數據不是問題,只需將 4 個常用欄位(open、 high、 low、 close)設置為價格變動值。 但是傳遞要重新採樣的逐筆報價數據再次生成相同的數據。作為或版本 1.1.11.88,情況已不再如此。

Backtrader同步不同市場

使用次數越多, backtrader 必須面對的想法和意外場景的混合就越多。對於每個新平臺,一個挑戰是要看看平臺是否能夠達到開發開始時設定的期望,靈活性和易用性是目標,Python被選為基石。 工單#76 提出了一個問題,即是否可以完成具有不同交易日曆的同步市場。

Backtrader教程:數據饋送

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

Backtrader迪克森移動平均線

下面的reddit帖子以自己的作者Nathan Dickson(reddit句柄)命名了這個平均值Dickson移動平均線。 在一次對reddit Algotrading 的定期訪問中,我發現了一篇關於移動平均線的帖子,該移動平均線試圖模仿Jurik移動平均線(又名JMA)。

Backtrader回溯

在一些關於改進的ShapeRatio的提示之後, backtrader 已將此分析儀添加到其武器庫中。 文獻位於: 從對數回報的好處開始,並遵循在SharpeRatio方程的分母中具有標準偏差的副作用,本文檔開發了該分析儀的公式和期望。

Backtrader 教程:交易

交易的定義:當工具中的頭寸從 0 變為大小 X 時,交易打開,對於多頭/空頭頭寸可能為正/負)當頭寸從 X 變為 0 時,交易平倉。以下兩個動作:正轉負負轉正實際上被視為:一筆交易已關閉(倉位從 X 變為 0)新交易已開立(倉位從 0 變為 Y)交易只是提供信息,沒有用戶可調用的方法。

Backtrader 教程:指標 - 時間框架混合

版本 1.3.0.92提供了混合來自不同時間範圍的數據(來自數據饋送和/或指標)的可能性。背景:指標是智能的啞對象。他們很聰明,因為他們可以進行複雜的計算。他們是愚蠢的,因為他們在不知道哪些來源為計算提供數據的情況下進行操作像這樣:如果提供值的數據源在Cerebro引擎內具有不同的時間範圍、不同的長度,則指標將中斷。

Backtrader教程:尺寸調整器

智慧質押 策略提供了交易方法,即:buy和 sell close。

Backtrader多數據範例

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