指示灯开发 – backtrader中文教程
指示灯Development
If任何东西(除了一个或多个获胜策略),必须不断开发,这个东西是平台内的自定义Indicator.
Such发展,据笔者,easy.
The以下需要:
- 从指标派生的类(直接或从一个已经存在的子类)
- 定义lines它将hold
An指示器必须至少有1行。如果从现有的派生,线(多个)可能已经被defined
- Optionally限定能改变behavior
- Optionally提供的参数/定制一些其能够明智的元件的所述indicators
- Provide的绘制在
__init__
完全定义的操作与结合(分配)到指示器否则的线(S)提供next
和(任选地)once
methodsIf的指示符可以被完全逻辑/算术运算期间定义初始化,结果被分配到该行:done
是它不是这种情况,至少一个
next
必须被提供,其中所述指示器必须在计算的索引0Optimization一个值分配给线(S)的runonce模式(间歇操作)可以通过提供可以实现一个oncemethod.
Important注:Idempotence
Indicators产生用于他们收到每个条的输出。没有假设必须是有多少次同样的酒吧将被发送制造。操作必须这背后idempotent.
The理由:
- 相同的杆(索引明智)可以与改变的值被发送多次(即改变值是收盘价)
这使得能够,例如,“重放”每日会话,但使用盘中数据这可以由5分钟bars.
It还可以允许平台从现场feed.
A哑得值(但功能)indicator
So可以它是:
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.
The同一指标,但使用下一个方法:
class DummyInd(bt.Indicator): lines = ("dummyline",) params = (("value", 5),) def next(self): self.lines.dummyline[0] = max(0.0, self.params.value)
完成!同样behavior.
Note
Notice如何在__init__
版本bt.Max
是用来分配给线条对象self.lines.dummyline
.
bt.Max
返回一个lines即自动迭代为对象传递给indicator.
Hadmax
被代替,转让本来毫无意义的,因为不是一条线,指标将有与成员变量的固定value.
Duringnext
工作与浮点值直接完成和标准的max
内置可used
Let此次召回的是self.lines.dummyline
是长的符号,它可以缩短为:
self.l.dummyline
甚至:
self.dummyline
后者是唯一可能的,如果代码没有用构件遮挡这个attribute.
The 3rd和最后一个版本提供了额外的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
方法强行超越划伤表面。其实胆量也一直看着into.
The__init__
版本是在任何情况下最好的:
- 一切都局限在initialization
next
和once
(均进行了优化,因为bt.Max
已经拥有它们)与没有必要与指数和/或自动播放提供formulas
Be它需要发展,指示灯也会可以覆盖方法关联到next
和once
:
prenext
和nexstart
preonce
和oncestart
手动/自动最小Period
If尽可能平台将计算,但手动操作可能needed.
Here是可能实现的Simple Moving Average:
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
虽然看上去声音,平台不知道是什么最小周期是即使参数被命名为“时期”(这个名字可能是误导性的,一些指标收到多个“周期” s具有不同用途)
在这种情况下next
会已经呼吁1st酒吧和寄托都会爆炸,因为得到不能返回所需的self.p.period
.
之前解决情况的东西,必须考虑到:
- 提要传递给指标数据可能已经携带了最低period
The样品SimpleMovingAverage可在例如完成:
- 常规数据feed
This具有1的默认周期的最小值(只是等待该1st栏进入系统)
- 另一个移动平均线……而这反过来已经拥有了period
如果是20,并再次在我们的样本均线也已20,我们结束了40 bars
Actually的最小周期内计算说39 ……因为只要第一移动平均制作了条此计数用于下一个移动平均,它创建的重叠条,从而39 needed.
- Other指标/其也携带periods
Alleviating的情况是如下进行的对象:
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
方法告诉系统要考虑到额外的period通过这个指标需要酒吧任何最短期限有可能是在existence.
Sometimes这是绝对需要的,如果所有的计算都做了
完成:这已经传达其周期需要到system.MACDA快
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
实现与直方图的对象!没有必要去想的最小值periods.
EMA
代表Exponential Moving Average(一个平台,内置别名)这一个(已经在平台)已经规定,它需要什么
- 指示符“MACD”和“信号”的命名线在被分配“ – ME2 ME1”这反过来它已经携带声明(幕后)periods
- macd需要从操作的时间段对象取最大值从ME1和ME2的周期(这两者都是具有不同周期的指数移动平均)
- 信号直接将指数移动平均的在此期间MACD。这EMA还考虑到已经存在的MACD期和的样品(period_signal)所需要的量,以计算itself
- histo取最大值的两个操作数的“信号 – MACD”。一旦两个准备好可以HISTO也产生value
A全定制indicator
Let的开发出“表示:”如果移动平均一个简单的自定义指标(可以用一个参数来修改)是给定的数据以上:
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”如果below.
Be所述数据的常规数据馈送1和-1s将产生与比较紧密price.
Although更多中可以看到的Plotting部并具有表现和在绘制世界公民不错,可以加几件事情:
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)
评论被关闭。