量化投资学习笔记79——实现量化交易经典策略:双均线策略

搜索了一下,主要实现双均线策略,布林带策略,海龟交易法,多因子选股,网格交易法这几种策略。
首先看双均线策略,参考这两篇: http://www.snailtoday.com/archives/18598 https://zhuanlan.zhihu.com/p/43317574
由短周期均线自下方向上穿越长周期的均线,则形成“金叉”,反之为“死叉”。双均线金叉的时候,表明该股票很强势,反之很弱势,我们就在强势的时候买,弱势的时候卖。

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
# coding:utf-8
# 双均线策略实现


import backtrader as bt
import backtest
import math


# 双均线策略类
class SmaCross(bt.Strategy):
params = dict(
pfast = 5,
pslow = 30
)

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

def __init__(self):
sma1 = bt.ind.SMA(period = self.p.pfast)
sma2 = bt.ind.SMA(period = self.p.pslow)
self.crossover = bt.ind.CrossOver(sma1, sma2)
self.dataclose = self.datas[0].close
self.order = None

def next(self):
if not self.position:
if self.crossover > 0:
cash = self.broker.get_cash()
stock = math.ceil(cash/self.dataclose/100)*100 - 100
print("数量", stock)
self.order = self.buy(size = stock, price = self.datas[0].close)
self.log("买入")
elif self.crossover < 0:
self.order = self.close()
self.log("卖出")


if __name__ == "__main__":
start = "2018-01-01"
end = "2020-07-05"
name = ["300etf"]
code = ["510300"]
backtest = backtest.BackTest(SmaCross, start, end, code, name, 10000)
backtest.run()
backtest.output()

期末资金:8760.36 夏普比例: -0.2841412997849817
年化收益率: OrderedDict([(2018, -0.22430925900000043), (2019, 0.19074554997170012), (2020, -0.0515497175750389)])
最大回撤:23.20,最大回撤周期292 总收益率:-0.13


表现不好,是亏的。一开始没注意,默认买入数量是1股,要自己计算后设定买入数量。
再修改一下backtest类,将回测结果数据保存到一个Series里,方便不同策略比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 计算胜率信息
def _winInfo(self):
trade_info = self.__results[0].analyzers.TA.get_analysis()
total_trade_num = trade_info["total"]["total"]
win_num = trade_info["won"]["total"]
lost_num = trade_info["lost"]["total"]
self.__backtestResult["交易次数"] = total_trade_num
self.__backtestResult["胜率"] = win_num/total_trade_num
self.__backtestResult["败率"] = lost_num/total_trade_num

# 计算并保存回测结果指标
def _Result(self):
self.__backtestResult["账户总额"] = self.getValue()
self.__backtestResult["总收益率"] = self.__results[0].analyzers.RE.get_analysis()["rtot"]
self.__backtestResult["年化收益率"] = self.__results[0].analyzers.RE.get_analysis()["rnorm"]
self.__backtestResult["夏普比率"] = self.__results[0].analyzers.sharpe.get_analysis()["sharperatio"]
self.__backtestResult["最大回撤"] = self.__results[0].analyzers.DD.get_analysis().max.drawdown
self.__backtestResult["最大回撤期间"] = self.__results[0].analyzers.DD.get_analysis().max.len
# 计算胜率信息
self._winInfo()

# 获取回测指标
def getResult(self):
return self.__backtestResult


这个策略并不咋样啊。
另外backtrader貌似没有直接计算α、β、信息比例等指标的方法,自己实现吧。等下次吧。
代码地址: https://github.com/zwdnet/MyQuant/tree/master/47

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

欢迎打赏!感谢支持!