量化交易学习(三十五)backtrader文档——在指标中耦合不同时间范围
今天这篇是backtrader文档的学习笔记。主要介绍了怎样在指标中耦合不同时间范围。
官方文档链接:https://www.backtrader.com/docu/mixing-timeframes/indicators-mixing-timeframes/
在指标中耦合不同的时间范围
背景:指示器是聪明的傻对象。
-
他们很聪明,因为他们可以进行复杂的计算。
-
他们很愚蠢,因为他们在操作时不知道为计算提供数据的来源是谁
像这样:
- 如果提供值的数据源在Cerebro引擎内具有不同的时间范围、不同的长度,则指标计算将会中断。
下面是一个例子,其中data0的时间范围为天,data1的时间范围为月:
1 | pivotpoint = btind.PivotPoint(self.data1) |
当收盘价低于s1线(第一支撑位)时,会发出卖出信号
注意:根据定义PivotPoint应在更大的时间范围内工作
这会出现以下错误:
1 | return self.array[self.idx + ago] |
原因是这样的:self.data.close
提供从第一个时刻开始的值,但是PivotPoint
(以及s1
线对象)只会在整个月过去后提供值,这大致相当于22 个 self.data0.close
的值。在这 22 次收盘价数据期间,还没有产生 s1
的值,因此尝试从底层数组中获取它的值会失败。
Lines对象支持(ago)
运算符(Python中的特殊方法__call__
)来传递自身的延迟时间的版本:
1 | close1 = self.data.close(-1) |
在此示例中,close1
对象(通过[0]
访问时)始终包含close
线对象前一个bar(-1)
的值 。该语法也可以用于适应耦合不同时间范围的场景。让我们重写上面的pivotpoint
代码片段:
1 | pivotpoint = btind.PivotPoint(self.data1) |
查看()
是如何在不带参数的情况下执行的(在后台提供了None
作为参数)。代码中发生以下情况:
pivotpoint.s1()
返回一个遵循更大范围节奏的内部对象LinesCoupler
。该耦合器用s1
实际的最新交付值填充自身(从默认值NaN
开始)
但要让魔法发挥作用还需要一些额外的东西。Cerebro必须使用以下命令创建:
1 | cerebro = bt.Cerebro(runonce=False) |
或执行:
1 | cerebro.run(runonce=False) |
在此模式下,指标和后期评估的自动线对象将逐步执行,而不是紧密循环。这使得整个操作变慢,但它使得耦合不同时间范围成为可能。
还可以耦合指标中的所有行。之前我们有:
1 | self.sellsignal = self.data0.close < pp.s1() |
耦合指标中的所有行的写法:
1 | pp1 = pp() |
现在整个PivotPoint指标已经耦合,并且可以访问它的任何线对象(即p, r1, r2, s1, s2)。这段代码中只对s1感兴趣并且直接访问它。
全耦合语法
对于具有多条线的线对象(例如像 PivotPoint 之类的指示器):
obj(clockref=None, line=-1)
clockref
:如果clockref
是None
,则周围的对象(比如 Strategy)将作为参考,将较大的时间范围(例如:Months)调整为更小/更快的时间范围(例如:Days)- 如果需要,可以使用另一个参数
line
:- 如果值为默认的
-1
,则所有线对象都是耦合的。 - 如果是另外的整数(例如,
0
或1
),则对应索引的那条线(obj.lines[x]
)将被耦合 - 如果传递一个字符串,则将按名称获取该行。
- 如果值为默认的
在上面的示例中,可以执行以下操作:
1 | Coupled_s1 = pp(行='s1') |
对于只有一条线的线对象(例如来自PivotPoint
指示器的s1
线):
obj(clockref=None)
(参见上文的clockref
参数)
通过()
语法,来自不同时间范围的数据源可以混合在指标中,需要注意cerebro
要用runonce=False
参数实例化。
这一篇就到这里啦。欢迎大家点赞、转发、私信。还没有关注我的朋友可以关注 江达小记