本文继续记录bt相关的概念内容。
Line迭代器
backtrader中的Line迭代器和Python里的迭代器关系不大,只是稍微模仿了Python迭代器的一些功能。
在bt中,策略(Strategy)和指标(Indicator)都是Line迭代器。
Line迭代器在自身line迭代的同时,会告知其附属迭代器一起进行迭代。
- next
Line迭代器的关键函数是next,Line迭代器在每次迭代时都会调用next函数,同时Line迭代器中所包含的data数组会在迭代中,由系统将数组索引自动后移一位。
需要注意的是,next函数只有在最小周期后才会被调用,后文将介绍最小周期的概念。
与传统的迭代器相比,Line迭代器还实现了另外两个实用的函数,这两个函数都和前面说到最小周期有关:
- prenext,在最小周期前,每次迭代都会被调用
- nextstart,当最小周期到达时,此函数会被调用一次,且仅被调用一次,默认的实现方式是调用next函数。
Indicator其他一些方法
为了实现运算的加速,Indicator支持被称为runonce的一系列操作。如果只使用next函数也足以完成任务,但是使用runonce可以大大节省计算时间。
在next系列函数中,使用的是索引方式间接地来访问(get/set)数据,而在runonce系列函数中,是直接访问存储数据的底层数组。
runonce系列函数的命名与next系列函数命名一致(once对应next,preonce对应prenext,oncestart对应nextstart),主要包含以下函数:
- once(self, start, end) ,在最小周期后的每次迭代都会被调用,start和end用于约束函数所处理的底层数组的范围
- preonce(self, start, end),在最小周期前,每次迭代都会被调用
- oncestart(self, start, end),当最小周期到达时,此函数会被调用一次,且仅被调用一次,默认的实现方式是调用once函数。
最小周期
通过一个简单的例子来介绍最小周期的概念,下面的代码中,定义了均线的指标:
class SimpleMovingAverage(Indicator):
lines = ('sma',)
params = dict(period=20)
def __init__(self):
... # Not relevant for the explanation
def prenext(self):
print('prenext:: current period:', len(self))
def nextstart(self):
print('nextstart:: current period:', len(self))
# emulate default behavior ... call next
self.next()
def next(self):
print('next:: current period:', len(self))
在使用这个指标时,实例化的方式如下:
sma = btind.SimpleMovingAverage(self.data, period=25)
假设传给该指标的数据是标准的data feed(没有延时,下一个例子会出现的data feed),那么period=25就意味着在计算25周期均线的时候,就会依次调用:
- prenext 24次
- nextstart 1次(默认去调用next)
- next 直到data feed被消费完毕
再举一个更复杂的例子,定义一个均线(SimpleMovingAverage )的均线指标,实例化的代码如下:
sma1 = btind.SimpleMovingAverage(self.data, period=25)
sma2 = btind.SimpleMovingAverage(sma1, period=20)
第1行的代码实现一个与上一个例子相同的25周期均线sma1,第2行代码把sma1作为data feed传入到均线sma2中,sma2就会依次调用:
- prenext 前25+18=43次,其中前25个时间周期生成了第1个sma1的数据,再经过18个时间周期,共生成了19个sma1数据
- nextstart 1次(默认去调用next)
- next 直到data feed被消费完毕
也就是说,在经过44根K线后,sma2才会直接调用next函数。
最小周期的规则会被自动应用到data feed中,只有经过最小周期后,next函数才会被调用(不考虑在nextstart中默认会调用next),在Strategy和Indicator中都遵循这样的规则。同样,runonce系列函数遵循next函数同样的调用规则。
此外,虽然bt不建议手动设置最小周期,但也提供了相关的函数,在Strategy和Indicator中可以通过setminperiod(minperiod)设置最小周期。
博客内容只用于交流学习,不构成投资建议,盈亏自负!
个人博客:http://coderx.com.cn/(优先更新)
项目最新代码:https://gitee.com/sl/quant_from_scratch
欢迎大家转发、留言。有微信群用于学习交流,感兴趣的读者请扫码加微信!
如果认为博客对您有帮助,可以扫码进行捐赠,感谢!
微信二维码 | 微信捐赠二维码 |
---|---|