backtrader tecent tutorial
这篇文章是对于腾讯课堂backtrader教程的笔记
教程 video link:
第一章: 基础
lines 对象
lines中每个line对象的访问:
- self.datas[0].lines[0] 访问0号线
- self.datas[0].lines.close直接通过名字访问线对象, 可简写为self.datas[0].close, 进一步简写为self.data.close
了解lines含有哪些对象的方法:
1 | self.datas[0].lines.getlinealiases() |
next方法中得到已经处理的bar的数目:
1 | len(self) |
next方法中不能访问line整体,只能使用比如:
1 | self.datas[0].close[0] |
init中只能访问line整体, 比如:
1 | self.datas[0].close |
init方法中, 含线对象可当作其默认线对象使用. 如果有多条线, 那取的是第一条线.
例如, 下面的代码等效:
1 | self.datas[0].lines[0] |
1 | self.datas[0].close |
1 | self.data[0] |
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线的例子
1 | class GenericCSV_PE(GenericCSVData): |
pandas读取数据
1 | dataframe = pandas.read_csv( |
第三章: analyzer 和 observer
常用的analyzer
1 | cerebro.addanalyze(bt.analyzers.SharpeRatio, riskfreerate=0.01, annualize=True, _name='shart_ratio') |
稍微好看的打印方法
1 | for a in thestrat.analyzers: |
内置的一些的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的参数:
取消所有订单
1 | for order in orders: |
buy sell的有效天数
1 | validday = self.data.datetime[0] # current date time |
自定义下单量
1 | class LongOnly(bt.sizer): |
自定义的sizer中可以访问:
- self.strategy
- self.broker
注入sizer到cerebro
cerebro.addsizer_byidx(idx, sizercls, args, *kwargs)
例子:
1 | idx = cerebro.addstratregy(MyStrategy) |
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)
第七章 多股票组合策略
加载多个数据
定期再平衡策略(月线)
例子: