Backtrader中文筆記之Using Indicators(指標)


Using Indicators

Indicators can be used in two places in the platform:

指標在平台中的兩個地方使用

  • Inside Strategies

  • 策略里面
  • Inside other Indicators

  • 在另外的指標里面

Indicators in action

指標使用指南

  1. Indicators are always instantiated during __init__ in the Strategy

  2. 指標在策略的__init__中被實例化
  3. Indicator values (or values thereof derived) are used/checked during next

  4. 指示值(或其派生值)將在next期間使用/檢查

There is an important axiom to take into account:

有一個重要的道理需要考慮:

  • Any Indicator (or value thereof derived) declared during __init__ will be precalculated before next is called.
  • 在調用next之前,將預先計算在初始化期間聲明的任何指示符(或其派生的值)

Let’s go for the differences an operation modes.

我們一起來操作不同的模式

 

__init__ vs next

Things works as follows:

  • Any operation involving lines objects during __init__ generates another lines object

  • 在__init__期間,任何設計操作lines對象都會生成另一個lines對象
  • Any operation involving lines objects during next yields regular Python types like floats and bools

  在next中,操作涉及的任何lines對象,都會生成常規的Python類型,比如float和bools

During __init__

Example of an operation during __init__:

hilo_diff = self.data.high - self.data.low

The variable hilo_diff holds a reference to a lines object which is precalculated before calling next and can be accessed using the standard array notation []

變量hilo_diff持有一個對lines對象的引用,該對象在調用next之前被預先計算過,可以使用標准數組符號[]訪問

It does obviously contains for each bar of the data feed the difference between the high and the low.

它顯然包含了數據饋送的每一欄的高低之差。

This also works when mixing simple lines (like those in the self.data Data Feed) and complex ones like indicators:

這也適用於混合簡單的線條(如self.data數據饋送)和指標等復雜數據:

sma = bt.SimpleMovingAverage(self.data.close)
close_sma_diff = self.data.close - sma

 Now close_sma_diff contains again a line object.

現在close_sma_diff又包含了一個line對象

Using logical operatorss:

close_over_sma = self.data.close > sma

 Now the generated lines object will contain an array of booleans.

現在生成的lines對象將包含一個布爾值數組。

 

During next

Example of an operation (logical operator):

close_over_sma = self.data.close > self.sma

 Using the equivalent array (index 0 based notation):(等同於)

close_over_sma = self.data.close[0] > self.sma[0]

 In this case close_over_sma yields a boolen which is the result of comparing two floating point values, the ones returned by the [0] operator applied to self.data.close and self.sma

  在這種情況下,close_over_sma生成一個boolen,這是比較兩個浮點值的結果,[0]運算符返回的值應用於self.data.close以及self.sma

  

The __init__ vs next why

Logic simplification (and with it ease of use) is the key. Calculations and most of the associated logic can be declared during __init__ keeping the actual operational logic to a minimum during next.

邏輯簡化(以及易於使用)是關鍵。計算和大部分相關的邏輯可以在__init__期間聲明,在接下來的期間保持實際的操作邏輯最小。

There is actually a side benefit: speed (due to the precalculation explained at the beginning)

實際上還有一個好處:速度(由於在開始時解釋了預先計算)

A complete example which generates a buy signal during __init__:

一個完整的例子,在__init__產生買入信號:

class MyStrategy(bt.Strategy):

    def __init__(self):

        sma1 = btind.SimpleMovingAverage(self.data)
        ema1 = btind.ExponentialMovingAverage()

        close_over_sma = self.data.close > sma1
        close_over_ema = self.data.close > ema1
        sma_ema_diff = sma1 - ema1

        buy_sig = bt.And(close_over_sma, close_over_ema, sma_ema_diff > 0)

    def next(self):

        if buy_sig:
            self.buy()

 

Note

Python’s and operator cannot be overriden, forcing the platform to define its own And. The same applies to other constructs like Or and If

Python的and操作符不能被重寫,這迫使平台定義自己的and。同樣的道理也適用於其他結構,比如Or和If

It should be obvious that the “declarative” approach during __init__ keeps the bloating of next (where the actual strategy work happens) to a minimum.

很明顯,在__init__期間的“聲明性”方法將next的膨脹(實際的策略工作發生的地方)保持在最小程度。

(Don’t forget there is also a speed up factor)

(別忘了還有加速因素)

Note

When the logic gets really complicated and involves several operations it is usually much better to encapsulate that inside an Indicator.

當邏輯變得非常復雜並涉及多個操作時,通常最好將其封裝在一個指示符中。

 

Some notes

In the example above there are two things which have been simplified in backtrader when compared to other platforms:

在上面的例子中,與其他平台相比,backtrader簡化了兩個方面:

  • Declared Indicators are neither getting a parent parameter (like the strategy in which they are being created nor is any kind of “register” method/function being called.

  • 聲明的指標既沒有父參數(就像創建它們的策略一樣,也沒有調用任何類型的“注冊”方法/函數。
  •  

    And in spite of it the strategy will kick the calculation of the Indicators and any lines object generated because of operations (like sma - ema)

  • 盡管如此,由於操作(如sma - ema),該策略還是會影響指標的計算和任何線條對象的生成。
  • ExponentialMovingAverage is being instantiated without self.data

  • ExponentialMovingAverage實例化時沒有self.data

     

    This is intentional. If no data is passed, the 1st data of the parent (in this case the Strategy in which is being created) will be automatically passed in the background

  • 這是故意的。如果沒有傳遞數據,父節點的第一個數據(在本例中是創建的策略也就是self.data)將自動在后台傳遞

 

 

Indicator Plotting

指標繪圖

First and foremost:

  • Declared Indicators get automatically plotted (if cerebro.plot is called)

  • 聲明的指標將自動繪制(如果cerebro.plot被調用)
  • lines objects from operations DO NOT GET plotted (like close_over_sma = self.data.close > self.sma)

  • 不打印來自操作的lines對象
  •  

    There is an auxiliary LinePlotterIndicator which plots such operations if wished with the following approach:

  有一個輔助的LinePlotterIndicator,可根據需要使用以下方法繪制這些操作: 

close_over_sma = self.data.close > self.sma
LinePlotterIndicator(close_over_sma, name='Close_over_SMA')

   name參數為該指示符保留的單行命名

 

Controlling plotting

控制畫圖

During the development of an Indicator a plotinfo declaration can be added. It can be a tuple of tuples (2 elements), a dict or an OrderedDict. It looks like:

在指示器的開發過程中,可以添加plotinfo聲明。它可以是元組(2個元素)、dict或OrderedDict。它看起來像:

class MyIndicator(bt.Indicator):

    ....
    plotinfo = dict(subplot=False)
    ....

 The value can be later accessed (and set) as follows (if needed):

以后可以按如下方式訪問(和設置)該值(如果需要)

myind = MyIndicator(self.data, someparam=value)
myind.plotinfo.subplot = True

 The value can even be set during instantiation:

值甚至可以在實例化的時候設置

myind = MyIndicator(self.data, someparams=value, subplot=True)

 The subplot=True will be passed to the (behind the scenes) intantiated member variable plotinfo for the indicator.

subblot=True將被傳遞給指標的(幕后)指定成員變量plotinfo。

The plotinfo offers the following parameters to control plotting behavior:

  plotinfo提供以下參數來控制打印行為:
    • plot (default: True)

      Whether the indicator is to be plotted or not

    • 是否標繪指標
    • subplot (default: True)

      Whether to plot the indicator in a different window. For indicators like moving averages the default is changed to False

    • 是否在其他窗口中繪制指示器。對於移動平均數這樣的指標,默認值改為False
    • plotname (default: '')

      Sets the plotname to show on the plot. The empty value means the canonical name of the indicator (class.__name__) will be used. This has some limitations because Python identifiers cannot use for example arithmetic operators.

    • 設置要在打印上顯示的打印名稱。空值表示將使用指示符的規范名稱(class.__name__)。這有一些限制,因為Python標識符不能使用例如算術運算符。

      An indicator like DI+ will be declared as follows:

    • 像DI+這樣的指標將聲明如下:
    • class DIPlus(bt.Indicator):
          plotinfo=dict(plotname='DI+')
      
  • Making the plot “nicer”

  • plotabove (default: False)

    Indicators are usually plotted (those with subplot=True) below the data they have operated on. Setting this to True will make the indicator be plotted above the data.

  • 指標通常標繪在它們所操作的數據下方(子subplot=True的指標)。將此設置為True將使指示器繪制在數據上方。
  • plotlinelabels (default: False)

    Meant for “indicators” on “indicators”. If one calculates the SimpleMovingAverage of the RSI the plot will usually show the name “SimpleMovingAverage” for the corresponding plotted line. This is the name of the “Indicator” and not the actual line being plotted.

  • 指“指標”上的“指標”。如果計算RSI的SimpleMovingAverage,則繪圖通常會顯示相應繪制線的名稱“SimpleMovingAverage”。這是“指標”的名稱,而不是實際繪制的直線。
  •  

    This default behavior makes sense because the user wants to usually see that a SimpleMovingAverage has been created using the RSI.

  • 這種默認行為是有意義的,因為用戶通常希望看到使用RSI創建了一個SimpleMovingAverage。

    if the value is set to True the actual name of the line inside the SimpleMovingAverage will be used.

  • 如果該值設置為True,則將使用SimpleMovingAverage中的行的實際名稱。
  • plotymargin (default: 0.0)

    Amount of margin to leave at the top and bottom of the indicator (0.15 -> 15%). Sometimes the matplotlib plots go too far to the top/bottom of the axis and a margin may be wished

  • 在指示器頂部和底部保留的余量(0.15->15%)。有時,matplotlib繪圖到軸的頂部/底部太遠,可能希望有一個邊距
  • plotyticks (default: [])

    Used to control the drawn y scale ticks

  • 用於控制繪制的y比例刻度

    If an empty list is passed the “y ticks” will be automatically calculated. For something like a Stochastic it may make sense to set this to well-known idustry standards like: [20.0, 50.0, 80.0]

  • 如果傳遞了一個空列表,“y記號”將自動計算。對於類似隨機的情況,將其設置為眾所周知的行業標准可能是有意義的,比如:[20.0,50.0,80.0]

     

    Some indicators offer parameters like upperband and lowerband that are actually used to manipulate the y ticks

  • 有些指示器提供了參數,如upperband和lowerband,這些參數實際上用於操縱y記號
  • plothlines (default: [])

    Used to control the drawing of horizontal lines along the indicator axis.

  • 用於控制繪制的x比例刻度
  •  

    If an empty list is passed no horizontal lines will drawn.

    For something like a Stochastic it may make sense to draw lines for well-known idustry standards like: [20.0, 80.0]

    Some indicators offer parameters like upperband and lowerband that are actually used to manipulate the horizontal lines

  • plotyhlines (default: [])

    Used to simultaneously control plotyticks and plothlines using a single parameter.

  • 用於使用單個參數同時控制plotyticks和Plothline。
  • plotforce (default: False)

    If for some reason you believe an indicator should be plotting and it is not plotting … set this to True as a last resort.

  • 如果出於某種原因,您認為某個指標應該在繪圖,而它沒有在繪圖…請將此設置為True作為最后的手段。

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM