![]() 本文继续记录bt相关的概念内容。 Line迭代器backtrader中的Line迭代器和Python里的迭代器关系不大,只是稍微模仿了Python迭代器的一些功能。 在bt中,策略(Strategy)和指标(Indicator)都是Line迭代器。 Line迭代器在自身line迭代的同时,会告知其附属迭代器一起进行迭代。
Line迭代器的关键函数是next,Line迭代器在每次迭代时都会调用next函数,同时Line迭代器中所包含的data数组会在迭代中,由系统将数组索引自动后移一位。 需要注意的是,next函数只有在最小周期后才会被调用,后文将介绍最小周期的概念。 与传统的迭代器相比,Line迭代器还实现了另外两个实用的函数,这两个函数都和前面说到最小周期有关:
Indicator其他一些方法 为了实现运算的加速,Indicator支持被称为runonce的一系列操作。如果只使用next函数也足以完成任务,但是使用runonce可以大大节省计算时间。 在next系列函数中,使用的是索引方式间接地来访问(get/set)数据,而在runonce系列函数中,是直接访问存储数据的底层数组。 runonce系列函数的命名与next系列函数命名一致(once对应next,preonce对应prenext,oncestart对应nextstart),主要包含以下函数:
最小周期 通过一个简单的例子来介绍最小周期的概念,下面的代码中,定义了均线的指标: 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)) 在使用这个指标时,实例化的方式如下:
假设传给该指标的数据是标准的data feed(没有延时,下一个例子会出现的data feed),那么period=25就意味着在计算25周期均线的时候,就会依次调用:
再举一个更复杂的例子,定义一个均线(SimpleMovingAverage )的均线指标,实例化的代码如下: sma1 = btind.SimpleMovingAverage(self.data, period=25)sma2 = btind.SimpleMovingAverage(sma1, period=20) 第1行的代码实现一个与上一个例子相同的25周期均线sma1,第2行代码把sma1作为data feed传入到均线sma2中,sma2就会依次调用:
也就是说,在经过44根K线后,sma2才会直接调用next函数。 最小周期的规则会被自动应用到data feed中,只有经过最小周期后,next函数才会被调用(不考虑在nextstart中默认会调用next),在Strategy和Indicator中都遵循这样的规则。同样,runonce系列函数遵循next函数同样的调用规则。 此外,虽然bt不建议手动设置最小周期,但也提供了相关的函数,在Strategy和Indicator中可以通过setminperiod(minperiod)设置最小周期。 感兴趣的读者也可以关注我的CSDN博客-码农甲V,里面有更多内容。 |
|