版本 1.3.0.92提供了混合来自不同时间范围的数据(来自数据馈送和/或指针)的可能性。
背景:指针是智能的哑对象。
他们很聪明,因为他们可以进行复杂的计算。
他们是愚蠢的,因为他们在不知道哪些来源为计算提供数据的情况下进行操作
像这样:
- 如果提供值的数据源在
Cerebro
引擎内具有不同的时间范围、不同的长度,则指针将中断。
计算示例,其中data0
的时间范围为天,而data1
的时间范围为months
:
pivotpoint = btind.PivotPoint(self.data1) sellsignal = self.data0.close < pivotpoint.s1
当收盘价低于s1
线(第一支撑)时,这里寻求卖出信号
笔记
根据定义, PivotPoint
在更大的时间范围内工作
这将在过去出现以下错误:
return self.array[self.idx + ago] IndexError: array index out of range
并且有一个很好的理由: self.data. close
提供从第一个时刻PivotPoint
(以及因此s1
线)只会在整整一个月过去后提供值,这大致相当于self.data0. close
。在这 22 次关闭期间,还没有s1
的值,并且尝试从底层数组中获取它失败。
Lines对象支持(ago)
运算符(Python 中的__call__
特殊方法)以提供其自身的延迟版本:
close1 = self.data.close(-1)
在这个例子中,对象close1
(当通过[0]
访问时)总是包含由close
传递的前一个值( -1
)。该语法已被重用以适应适应时间范围。让我们重写上面的pivotpoint
片段:
pivotpoint = btind.PivotPoint(self.data1) sellsignal = self.data0.close < pivotpoint.s1()
查看()
如何在没有参数的情况下运行(在后台提供None
)。以下情况正在发生:
-
pivotpoint.s1()
正在返回一个内部LinesCoupler
对象,该对象遵循更大范围的节奏。该耦合器使用来自真实s1
的最新交付值填充自身(从默认值NaN
开始)
但是需要一些额外的东西才能使魔法发挥作用。必须使用以下内容创建Cerebro
:
cerebro = bt.Cerebro(runonce=False)
或运行:
cerebro.run(runonce=False)
在这种模式下,指针和后期评估的自动线对像是逐步运行的,而不是紧密循环。这使得整个操作变慢,但它使得它成为可能
底部的示例脚本被打破,现在运行:
$ ./mixing-timeframes.py
带输出:
0021,0021,0001,2005-01-31,2984.75,2935.96,0.00 0022,0022,0001,2005-02-01,3008.85,2935.96,0.00 ... 0073,0073,0003,2005-04-15,3013.89,3010.76,0.00 0074,0074,0003,2005-04-18,2947.79,3010.76,1.00 ...
在第 74行,第一个close < s1
实例发生。
该脚本还提供了对其他可能性的洞察:耦合指针的所有行。之前我们有:
self.sellsignal = self.data0.close < pp.s1()
作为替代方案:
pp1 = pp() self.sellsignal = self.data0.close < pp1.s1
现在整个PivotPoint
指针已耦合,可以访问其任何行(即p
、 r1
、 r2
、 s1
、 s2
)。该脚本只对s1
感兴趣,并且可以直接访问。:
$ ./mixing-timeframes.py --multi
输出:
0021,0021,0001,2005-01-31,2984.75,2935.96,0.00 0022,0022,0001,2005-02-01,3008.85,2935.96,0.00 ... 0073,0073,0003,2005-04-15,3013.89,3010.76,0.00 0074,0074,0003,2005-04-18,2947.79,3010.76,1.00 ...
这里没有惊喜。和以前一样。甚至可以绘制“耦合”对象:
$ ./mixing-timeframes.py --multi --plot
全耦合语法
对于具有多条线的线对象(例如像PivotPoint
这样的指针):
obj(clockref=None, line =-1)
-
clockref
如果clockref
是None
,则周围的对象(在示例中为Strategy
)将作为参考以适应较大的时间范围(例如:Months
)以适应更小/更快的时间范围(例如:Days
)
如果需要,可以使用另一个参考
line
* If the default `-1` is given, all *lines* are coupled. * If another integer (for example, `0` or `1`) a single line will be coupled and fetched by index (from `obj.lines[x]`) * If a string is passed, the line will be fetched by name. In the sample, the following could have been done: ```python coupled_s1 = pp(line='s1') ```
-
对于具有单条线的线对象(例如来自指针PivotPoint
的线s1
):
-
obj(clockref=None)
(参见上面的clockref
)
结论
集成在常规()
语法中,来自不同时间范围的数据馈送可以混合在指针中,始终考虑到需要实例化或使用cerebro
runonce= False
创建 cerebro。
脚本代码和用法
在backtrader
的来源中作为示例提供。用法:
$ ./mixing-timeframes.py --help usage: mixing-timeframes.py [-h] [--data DATA] [--multi] [--plot] Sample for pivot point and cross plotting optional arguments: -h, --help show this help message and exit --data DATA Data to be read in (default: ../../datas/2005-2006-day-001.txt) --multi Couple all lines of the indicator (default: False) --plot Plot the result (default: False)
编码:
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind import backtrader.utils.flushfile class St(bt.Strategy): params = dict(multi=True) def __init__(self): self.pp = pp = btind.PivotPoint(self.data1) pp.plotinfo.plot = False # deactivate plotting if self.p.multi: pp1 = pp() # couple the entire indicators self.sellsignal = self.data0.close < pp1.s1 else: self.sellsignal = self.data0.close < pp.s1() def next(self): txt = ','.join( ['%04d' % len(self), '%04d' % len(self.data0), '%04d' % len(self.data1), self.data.datetime.date(0).isoformat(), '%.2f' % self.data0.close[0], '%.2f' % self.pp.s1[0], '%.2f' % self.sellsignal[0]]) print(txt) def runstrat(): args = parse_args() cerebro = bt.Cerebro() data = btfeeds.BacktraderCSVData(dataname=args.data) cerebro.adddata(data) cerebro.resampledata(data, timeframe=bt.TimeFrame.Months) cerebro.addstrategy(St, multi=args.multi) cerebro.run(stdstats=False, runonce=False) if args.plot: cerebro.plot(style='bar') def parse_args(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Sample for pivot point and cross plotting') parser.add_argument('--data', required=False, default='../../datas/2005-2006-day-001.txt', help='Data to be read in') parser.add_argument('--multi', required=False, action='store_true', help='Couple all lines of the indicator') parser.add_argument('--plot', required=False, action='store_true', help=('Plot the result')) return parser.parse_args() if __name__ == '__main__': runstrat()