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作为最后的手段。
原文地址:https://www.cnblogs.com/sidianok/p/13554909.html