量化投资学习笔记81——实现量化交易经典策略:布林带策略

参考:https://zhuanlan.zhihu.com/p/64238996
首先看了一下backtrader文档,可以添加基准数据观察器的,试试。

1
self.__cerebro.addobserver(bt.observers.Benchmark, data = self.__benchFeed, timeframe = bt.TimeFrame.NoTimeFrame)

注意要先用adddata将数据添加,否则会报错。但添加基准数据以后貌似回测指标都没啥变化呀。
现在来实现布林带策略吧。
有上中下三条带,突破下带买入,突破上带卖出。
backtrader的Indicators里有BollingerBands指标的,可以直接用。
先写策略类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# coding:utf-8
# 布林带策略实现


import backtrader as bt
import backtest
import pandas as pd
import math


class Bolling(bt.Strategy):
params = dict(
period = 50
)

def __init__(self):
self.bb = bt.ind.BBands(period = self.p.period, devfactor = 2.0)
self.dataclose = self.datas[0].close
self.order = None

def log(self, txt, dt=None):
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))

def next(self):
# self.log("持仓%d" % (self.position.size))
if self.order:
return
if not self.position:
# 突破下轨 买入
if self.bb.bot > self.datas[0].close:
cash = self.broker.get_cash()
stock = math.ceil(cash/self.dataclose/100)*100 - 100
self.order = self.buy(size = stock, price = self.datas[0].close, exectype = bt.Order.Market)
else:
# 持仓且突破上轨,卖出
if self.bb.bot < self.datas[0].close:
self.order = self.close()

def notify_order(self, order):
# 有交易提交/被接受,啥也不做
if order.status in [order.Submitted, order.Accepted]:
return

self.order = None

if __name__ == "__main__":
start = "2018-01-01"
end = "2020-07-05"
name = ["nasetf"]
code = ["513100"]
backtest = backtest.BackTest(Bolling, start, end, code, name, 10000)
result = backtest.run()
# backtest.output()
print(result)



表现很差,绝大部分时间在空仓,年化收益率0.5%,不如余额宝。
再试试调整参数,用不同的周期跑。cerebro有一个optstragtegy函数用来跑不同的参数,但是怎么加到自己的类里呢?
加了一个函数

1
2
3
4
5
6
# 进行参数优化
def _optStrategy(self, *args, **kwargs):
self.__cerebro = bt.Cerebro(maxcpus = 1)
self.__cerebro.optstrategy(self.__strategy, *args, **kwargs)
self.createDataFeeds()
self.settingCerebro()

因为我是用手机写的,多线程运行有问题,所以指定使用一个cpu。
再加一个优化回测函数

1
2
3
4
5
# 执行参数优化的回测
def optRun(self, *args, **kwargs):
self._optStrategy(*args, **kwargs)
self.__cerebro.run()
self.init()

在策略类里实现stop函数

1
2
def stop(self):
self.log("周期%d期末账户总值%.2f" % (self.p.period, self.broker.getvalue()))

就可以用

1
backtest.optRun(period = range(5, 50))

实现参数优化了。

周期14最好。
应该还可以改进,显示其它回测指标,以后再说吧。

代码地址还是: https://github.com/zwdnet/MyQuant/tree/master/47
主要修改了backtest.py文件,增加了一个策略类文件Bolling.py。

我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地

欢迎打赏!感谢支持!