量化交易学习(四)backtrader基本概念1

今天这篇是backtrader文档的学习笔记。主要介绍了一些基本概念,包括数据源(Data Feeds)的使用、参数(Parameters)等。

官方文档链接:https://www.backtrader.com/docu/concepts

文中例子中的代码都需要导入以下库:

1
2
3
4
5
6
# 导入backtrader
import backtrader as bt
# 导入指标库
import backtrader.indicators as btind
# 导入数据源库
import backtrader.feeds as btfeeds

数据源

在执行策略时,数据源能自动以数组成员变量的形式为策略提供数据。

以下是backtrader执行策略的代码框架:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyStrategy(bt.Strategy):
params = dict(period=20)

def __init__(self):
sma = btind.SimpleMovingAverage(self.datas[0], period=self.params.period)
...

cerebro = bt.Cerebro()
...
data = btfeeds.MyFeed(...)
cerebro.adddata(data)
...
cerebro.addstrategy(MyStrategy, period=30)
...

有以下两个注意点:

  • 策略类的__init__方法没有接收*args或**kwargs参数
  • 策略类中至少会存在一个self.datas数组/列表/可迭代对象(不存在的话会抛出异常)

数据源添加到cerebro中之后,在策略中就可以按序获取数据了。

数据源的快捷方式

self.datas 数组中的元素可以直接通过自动生成的成员变量访问:

  • self.data 指向 self.datas[0]
  • self.dataX 指向 self.datas[X]

例如:

1
2
3
4
5
6
class MyStrategy(bt.Strategy):
params = dict(period=20)

def __init__(self):
sma = btind.SimpleMovingAverage(self.data, period=self.params.period)
...

忽略数据源

上面的例子可以被简化为:

1
2
3
4
5
6
7
class MyStrategy(bt.Strategy):
params = dict(period=20)

def __init__(self):
sma = btind.SimpleMovingAverage(period=self.params.period)

...

其中,SimpleMovingAverage中的self.data已经被移除了。这时SimpleMovingAverage将默认使用self.datas[0]

几乎任何东西都能成为数据源

除了数据源(Data Feeds)外, 指标(Indicators) 以及运算(Operations)的结果都可以作为数据源。

在前面的例子中SimpleMovingAverage以self.datas[0]作为输入源,下面的例子展示怎么用运算的结果及额外的指标作为数据源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyStrategy(bt.Strategy):
params = dict(period1=20, period2=25, period3=10, period4)

def __init__(self):

sma1 = btind.SimpleMovingAverage(self.datas[0], period=self.p.period1)

# 第二次计算均线的操作使用 sma1 作为数据源
sma2 = btind.SimpleMovingAverage(sma1, period=self.p.period2)

# 通过算数运算创造新的数据源
something = sma2 - sma1 + self.data.close

# 第三次计算均线的操作使用 something 作为数据源
sma3 = btind.SimpleMovingAverage(something, period=self.p.period3)

# 比较运算也能创建新的数据源
greater = sma3 > sma1

# 无意义但合法的值为True/False的均线
# 第四次计算均线的操作使用 greater 作为数据源
sma3 = btind.SimpleMovingAverage(greater, period=self.p.period4)

...

基本上任何通过运算操作转换产生的对象都能作为数据源。

参数

backtrader中几乎所有的类都支持参数的概念。

  • 带默认值的参数被声明为类属性(元组的元组或类似字典的对象)
  • 扫描关键字args (kwargs)以寻找匹配的参数,如果找到,将其从kwargs中删除,并将值赋给相应的参数
  • 参数最终可以在类的实例中通过成员变量self.params使用(简写:self.p)
    使用元组定义参数的例子:
1
2
3
4
5
class MyStrategy(bt.Strategy):
params = (('period', 20),)

def __init__(self):
sma = btind.SimpleMovingAverage(self.data, period=self.p.period)

使用字典定义参数的例子:

1
2
3
4
5
class MyStrategy(bt.Strategy):
params = dict(period=20)

def __init__(self):
sma = btind.SimpleMovingAverage(self.data, period=self.p.period)

这一篇就到这里啦。欢迎大家点赞、转发、私信。

江达小记