Backtrader 文档学习-Operating the platform
1. 行迭代器
Line迭代器模仿Python的迭代器,但实际上与它们之间并没有关系。
行迭代器概念描述:
- Line迭代器启动从属Line迭代器,告诉它们进行迭代
backtrader.linebuffer.LineBuffer
感觉需要从数据类型上理解,是两个类,linebuffer 的从属类LineBuffer 。
- Line 迭代器在其自己声明的Line赋值,进行迭代
迭代中最关键的就是next函数,就像python普通的迭代器一样,一个类(对象)只要含有“iter”、"next"两个方法,定义为为迭代器。
- next方法
每一次迭代,next都会被调用。如前面所述,数据源(datas)中的line(例如close)是逻辑计算的基础,line是一组数据,在next中会自动移动到下一个索引,就是对line中的bars逐一处理 。
非标准迭代器,多两个方法: - prenext
在最小周期满足之前,每次迭代都会调用。 - nextstart
当最小周期满足的时候,调用一次。
默认行为是将调用转发到next,如果需要可以重写。
2.Indicators的额外方法
为了加快操作速度,Indicators支持称为runonce的批量操作模式,其实并不是必须的(next方法足够使用了),但是却确实有效减少了操作时间,在大数据处理的时候有用。
once方法实现机制是:取消原来通过索引0来设置或读取数据,而是依赖于直接访问包含原始数据的底层的数组,以及不同状态下传递正确的索引。
once主要包括:
-
once(self, start, end):
当最小周期满足后就调用。在strart和end之间的数据会必须处理,strart和end指的是0为开始的内部数组的索引。 -
preonce(self, start, end)
最小周期满足前调用。 -
oncestart(self, start, end)
最小周期满足的时候调用一次。缺省是调用once,需要的话可以重写函数。
3.最小周期
用SMA解释说明:
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))
strategy初始化:
sma = btind.SimpleMovingAverage(self.data, period=5)
当参数period=5的时候,那么SimpleMovingAverage方法调用次数说明如下:
- prenext: 4 次。因为周期为5的时候,前4个数据无效,每一个无效数据会被调用一次。
sma: array('d', [nan, nan, nan, nan, 5.444])
- nextstart: 1 次 (紧接着就会调用next) ,可以理解为 nextstart 是启动了next ,后面的示例可以看到 。
- next: 再调用n次,直到所有数据处理完毕。
复杂调用:
sma1 = btind.SimpleMovingAverage(self.data, period=25)
sma2 = btind.SimpleMovingAverage(sma1, period=20)
原文
- prenext the first 25 + 18 times for a total of 43 times
- 25 times to let sma1 produce its 1st sensible value
- 18 times to accumulate extra sma1 values
- For a total of 19 values (1 after 25 calls and then 18 more)
- nextstart then 1 time (in turn calling next)
- next the n additional times until the data feed has been exhausted
- sma1同上一个例子一样。
- sma2是计算sma1(25为最小周期的数据源)的移动平均,在sma2中:
- prenext: 开始的 24 + 19 次 ,总共 43 times。(个人理解与文档上似乎不同,总数是对的??)
- 25次后,sma1产生第一个有效值
- 19 用于累积第一个sma2的值 ,(原文为什么是18??)
- 一共19个值 ,(sma1的25次调用,然后18次 ??)
- nextstart 执行1次,然后接着就会调用next
- next: 在调用n次,直到所有数据处理完毕
在处理44个值(bars)之后,然后调用next 。最小周期会自动调整到输入的数据
strategy和Indicator遵循如下规则:
只有自动计算的最小周期到达之后,next才会被调用,禁止对nextstart的调用,看后面的例子,便于理解。
测试一下:
class MyStrategy8(bt.Strategy):
lines = ('sma',)
params = dict(period=20)
def __init__(self):
... # Not relevant for the explanation
self.sma1 = btind.SimpleMovingAverage(self.data0, period=25)
self.sma2 = btind.SimpleMovingAverage(self.sma1, period=20)
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))
print('next sma1:',self.sma1.get(ago=0,size = len(self.sma1)))
print('next sma2:',self.sma1.get(ago=0,size = len(self.sma2)))
# 载入数据源
cerebro = declare_cerebar()
# 加入策略
cerebro.addstrategy(MyStrategy8)
cerebro.run()
- 的确是43次prenext,开始nextstart , next 是44次。
- 由于sma2 是在sma1 上产生的,所以第一次next后 ,sma1 和 sma2 都是24个nan值 。
- 第一次next后 ,sma1 和 sma2长度是44 ,前面24个nan ,后面20个值,随着next,sma1 和 sma2长度递增。
- nextstart 只运行一次,之后启动了next 。
看看结果,再理解原文:
prenext:: current period: 1
prenext:: current period: 2
prenext:: current period: 3
prenext:: current period: 4
prenext:: current period: 5
prenext:: current period: 6
prenext:: current period: 7
prenext:: current period: 8
prenext:: current period: 9
prenext:: current period: 10
prenext:: current period: 11
prenext:: current period: 12
prenext:: current period: 13
prenext:: current period: 14
prenext:: current period: 15
prenext:: current period: 16
prenext:: current period: 17
prenext:: current period: 18
prenext:: current period: 19
prenext:: current period: 20
prenext:: current period: 21
prenext:: current period: 22
prenext:: current period: 23
prenext:: current period: 24
prenext:: current period: 25
prenext:: current period: 26
prenext:: current period: 27
prenext:: current period: 28
prenext:: current period: 29
prenext:: current period: 30
prenext:: current period: 31
prenext:: current period: 32
prenext:: current period: 33
prenext:: current period: 34
prenext:: current period: 35
prenext:: current period: 36
prenext:: current period: 37
prenext:: current period: 38
prenext:: current period: 39
prenext:: current period: 40
prenext:: current period: 41
prenext:: current period: 42
prenext:: current period: 43
nextstart:: current period: 44
next:: current period: 44
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001])
next:: current period: 45
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604])
next:: current period: 46
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728])
next:: current period: 47
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468])
next:: current period: 48
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508])
next:: current period: 49
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292])
next:: current period: 50
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792])
next:: current period: 51
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001])
next:: current period: 52
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942])
next:: current period: 53
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001])
next:: current period: 54
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001])
next:: current period: 55
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001])
next:: current period: 56
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001, 77.5964])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001, 77.5964])
next:: current period: 57
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001, 77.5964, 78.4864])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001, 77.5964, 78.4864])
next:: current period: 58
next sma1: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001, 77.5964, 78.4864, 79.5464])
next sma2: array('d', [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 54.356, 55.0012, 55.7612, 56.4356, 57.258, 58.083999999999996, 58.843199999999996, 59.5708, 60.283199999999994, 61.15, 61.788000000000004, 62.502399999999994, 63.2856, 64.16640000000001, 65.0164, 65.9188, 66.79560000000001, 67.5464, 68.194, 68.93520000000001, 69.604, 70.3728, 71.0468, 71.7508, 72.6292, 73.4792, 74.26440000000001, 74.942, 75.72800000000001, 76.24560000000001, 76.83760000000001, 77.5964, 78.4864, 79.5464])
4.启动和运行
启动和运行需要至少3个Lines对象:
- 一个数据源(data Feed)
- 一个策略(Strategy,继承Strategy的类)
- 一个(cerebro)(拉丁语cerebro是大脑)
5.数据载入
通过计算(直接计算或者通过指标(Indicators))进行回测的数据。
平台支持多种数据源,还是从数据库中到pandas ,然后加载到cerebro 方便,稳妥。
6.继承strategy类
使用backtrader回测数据,主要就是在strategy中实现的,至少有两个方法需要定制:
- init
- next
简单继承类示例:
MyStrategy 继承了bt.Strategy ,重写了 init 和next 方法。
class MyStrategy(bt.Strategy):
def __init__(self):
self.sma = btind.SimpleMovingAverage(self.data, period=20)
def next(self):
if self.sma > self.data.close:
self.buy()
elif self.sma < self.data.close:
self.sell()
下一个例子,重写strategy类的其他方法:
class MyStrategy(bt.Strategy):
def __init__(self):
self.sma = btind.SimpleMovingAverage(self.data, period=20)
def next(self):
if self.sma > self.data.close:
submitted_order = self.buy()
elif self.sma < self.data.close:
submitted_order = self.sell()
def start(self):
print('Backtesting is about to start')
def stop(self):
print('Backtesting is finished')
def notify_order(self, order):
print('An order new/changed/executed/canceled has been received')
以上,在quickstart 的学习文档中都有演示。
7.Cerebro
创建一个cerebro实例,实例化一个cerebro比较简单:
cerebro = bt.Cerebro()
默认设置:
- 创建一个缺省的broker;
- 无佣金
- 预装载数据源(Data Feed)
- 缺省的执行模式是runonce(批量操作),这样速度会更快。
所有的Indicators必须支持runonce模式。定制的Indicator不需支持,cerebro会模拟,也就是不支持runonce的indicators会执行得慢点,但是大多数会按照批量操作运行。
让cerebro动起来:
cerebro.adddata(data)
cerebro.addstrategy(MyStrategy, period=25)
cerebro.run()
说明:
- 加载data
- 加载strategy类,传递给它的参数。对strategy的实例由cerebro在后台完成,实例化使用的参数就是就是addstrategy携带的参数。
- 用户可以按需要添加任意多个strategies和data feeds。平台并不限制策略如何协调使用多个数据和策略。
最后提醒:
- Windows下的交互式Python外壳和某些类型的frozen可执行Python多处理模块存在问题
- 请阅读有关多处理的Python文档。