avatar

目录
backtrader tecent tutorial notes

backtrader tecent tutorial

这篇文章是对于腾讯课堂backtrader教程的笔记

教程 video link:

https://ke.qq.com/webcourse/index.html#cid=2961673&term_id=103074911&taid=10122795538002185&vid=5285890809636928466

第一章: 基础

lines 对象

lines中每个line对象的访问:

  • self.datas[0].lines[0] 访问0号线
  • self.datas[0].lines.close直接通过名字访问线对象, 可简写为self.datas[0].close, 进一步简写为self.data.close

了解lines含有哪些对象的方法:

python
1
self.datas[0].lines.getlinealiases()

next方法中得到已经处理的bar的数目:

python
1
len(self)

next方法中不能访问line整体,只能使用比如:

python
1
self.datas[0].close[0]

init中只能访问line整体, 比如:

python
1
self.datas[0].close

init方法中, 含线对象可当作其默认线对象使用. 如果有多条线, 那取的是第一条线.

例如, 下面的代码等效:

python
1
self.datas[0].lines[0]
python
1
self.datas[0].close
python
1
self.data[0]
python
1
self.data

lines的长度

len(self.datas[0]) 得到的是当前已处理数据长度

self.datas[0].buflen()是数据线的总长度, 只有在回测中预加载的时候才能使用.

line的切片

self.data.close.get(ago=-1, size=10)

只能放在next中.

line的上下移动错位

self.data.close(-1) 向下移动一位

self.data.close(1) 向上移动一位

notify_order

任何order的变化都会触发notify_order

order.status 有以下几种状态

  • order.Submitted
  • order.Accepted
  • order.Completed
  • order.Canceled
  • order.Margin (margin不足时触发)
  • order.Rejected

notify_trade

trade指仓位从0变成非0, 或者从非0变成0

任何trade的变化都会触发notify_trade

self.close()一定会关闭所有交易, 触发notify_trade

trade的内容:

  • trade.pnl 毛收益
  • trade.pnlcomm 扣佣后收益
  • trade.comission 佣金

pending order

处于submitted或者accepted的订单

order状态图可以用下面的图表示。

例子:

minimum period

几个重要的方法

  • prenext

  • nextstart (这个方法里一定要写self.next!)

  • next

程序运行顺序总结

例子:

常用对象

  • self.data

    self.datas[0]第一个行情数据

    self.datas[1]第二个行情数据

    self.datas[0].close第一个行情数据收盘线

  • self.position

    self.position.size 第一个行情数据仓位数量

    self.posiotion.price 第一个行情数据仓位平均价格

    如果访问data[1],可调用 self.getposition(self.datas[1])来获得仓位

  • self.broker

    self.broker.getcash() 获得现金

    self.broker.getvalue()获得账户市值

    self.broker.getposition(self.datas[0])获得第一个行情数据对象

    self.broker.getposition(self.datas[0])获得第一个行情数据仓位

    self.broker.getposition(self.datas[0])获得第一个行情数据平均价格(平均成本)

  • order

    在notify_order中可使用下面这些东西.

    order.status订单状态 (数字)

    order.getstatusname()订单状态(名字)

    order.getstatusname(order.status)从数字得到状态名称

    订单的9个状态:

    • Created
    • Submitted
    • Accepted
    • Partial
    • Completed
    • Canceled
    • Expired
    • Margin
    • Rejected

    order.isbuy()判断是不是买单

    order.issell()判断是不是卖单

第二章: 数据

数据应该是后复权的数据, 原因是分红计算更准确

GenericCSV的扩展

默认的GenericCSV只有7列, 如果要扩展需要继承并且手动加线.

增加一个pe线的例子

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class GenericCSV_PE(GenericCSVData):
lines = ('pe', )
# 默认第八列
params = (('pe', 8), )

data = GenericCSV_PE(
dataname=datapath,
datetime=2,# 几就表示第几列
open=3,
high=4,
low=5,
close=6,
volume=10,
openinterest=-1, # -1表示没有openinterest信息
pe=12,
dtformat=('%Y%m%d'),
fromdate=datetime(2019, 1, 1),
todate=datetime(2020, 7 , 8)
)

cerebro.adddata(data)

pandas读取数据

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
dataframe = pandas.read_csv(
datapath,
skiprows=0, # 不忽略行
header=0, # 列头在第0行
parse_dates=True, # 解析日期
index_col=2 # 索引列(日期)在第二列
)

data = bt.feeds.PandasData(
dataname=dataframe,
datetime=None, #使用索引列作为日期,如果不是索引列则要赋列名,比如"date"
open=2, # 2 代表open在第二列
high=3,
low=4,
close=5,
volumne=9,
openinterest=-1,
fromdate=datetime(2019, 5, 1)
todate=datetime(2019, 10, 1)
)

第三章: analyzer 和 observer

常用的analyzer

python
1
2
3
4
5
6
7
8
9
10
cerebro.addanalyze(bt.analyzers.SharpeRatio, riskfreerate=0.01, annualize=True, _name='shart_ratio')

cerebro.addanalyze(bt.analyzers.AnnualReturn, _name='annual_return')

cerebro.addanalyze(bt.analyzers.DrawDown, _name='drawdown')

cerebro.addanalyze(bt.analyzers.TradeAnalyzer)

thestrats = cerebro.run()
thestrat = thestrats[0]

稍微好看的打印方法

python
1
2
for a in thestrat.analyzers:
a.print()

内置的一些的analyzers

开发新的observer

第四章: writer, broker, indicator

使用例子

cerebro.addwriter(bt.WriterFile, rounding=2)

cerebro.addwriter(bt.WriterFile, out=’xxx.csv’, rounding=2)

cerebro.addwriter(bt.WriterFile, csv=True, out=’xxx.csv’, rounding=2)

把indicator也输出到writer结果中

使用ta-lib指标

self.sma = bt.talib.SMA(self.data, timeperiod=self.p.period)

自定义指标

indicator中的运算符

第五章: 订单

利用buy/sell/close 下单

buy的参数:

取消所有订单

python
1
2
for order in orders:
self.broker.cancel(order)

buy sell的有效天数

python
1
2
3
4
5
6
7
8
9
10
validday = self.data.datetime[0] # current date time
validday = bt.num2date(validday) + timedelta(days=3)
print('validday', validday)

self.order = self.buy(
size=100,
valid=validday,
exectype=bt.Order.Limit,
price=someprice
)

自定义下单量

python
1
2
3
4
5
6
7
class LongOnly(bt.sizer):
params=(('stake', 100), )
def _getsizing(self, comminfo, cash, data, isbuy):
if isbuy:
return self.p.stake
position = self.broker.getposition(data)
return min(self.p.stake, position.size)

自定义的sizer中可以访问:

  • self.strategy
  • self.broker

注入sizer到cerebro

cerebro.addsizer_byidx(idx, sizercls, args, *kwargs)

例子:

python
1
2
3
4
idx = cerebro.addstratregy(MyStrategy)
cerebro.addsizer_byidx(idx, LongOnly) # MyStrategy使用这个sizer

cerebro.addsizer(bt.sizers.SizerFix, stake=20) # 其他strategy使用这个sizer

order_target_xxx 下单方法

  • self.order_target_size(target=10000) #通过买卖, 将self.data对应的股票仓位数量调整至10000股

  • self.order_target_value(target=10000) #通过买卖, 将self.data对应的股票仓位价值调整至10000元.如果不能整除则向下取整

  • sefl.order_target_percent(target=0.1)

第六章: 策略参数优化, 时间粒度

参数优化命令

strats = cerebro.optstrategy(SmaCross, pfast=[5, 10, 15], pslow=[20, 30, 60])

strats = cerebro.optstrategy(SmaCross, period=[(5, 10), (5, 20), (10, 20)])

混合时间粒度

必须使用cerebro.run(runonce=False)才不会出错

不同时间粒度指标比较,需要加原括号, 例如: self.isober = self.move_average_5min_bar > self.move_average_day_bar()

小粒度合成大粒度

下面的代码将日线数据合成周线, 并储存在self.datas[1]中(data是日线)

cerebro.resampledata(data, timeframe=bt.TimeFrame.Weeks, compression=1)

下面的代码将日线数据合成轴线, 并且将两根轴线合并成一根周线(data是日线)

cerebro.resampledata(data, timeframe=bt.TimeFrame.Weeks, compression=2)

下面的代码将5分钟k线合成10分钟k线(data是5分钟k线)

cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=2)

下面的代码将tick数据合成1分钟数据(data是tick数据)

cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=1)

第七章 多股票组合策略

加载多个数据

定期再平衡策略(月线)

例子:


评论