Python量化交易学习笔记(18)——放量突破布林线中轨买入策略
本文将探索新的策略回测程序,主要是为了尝试不同的技术指标在backtrader平台上的应用,为后续复杂策略的实现做准备。
本文将实现的策略是,当股票放量突破布林线中轨时进行买入,当股票收盘价低于短期均线时卖出。
买入条件中,放量突破布林线中轨具体指的是,当日股票开盘价在布林线中轨下方,收盘价在布林线中轨上方,当日成交量为10日以来的最高量。卖出条件中,短期均线选取为5日线。回测初始资金100000元,单笔操作单位1000股,佣金千分之一,回测时间自2018年1月1日至2020年3月20日。
策略核心代码还是位于策略类的init方法中:
def __init__(self): self.inds = dict() for i, d in enumerate(self.datas): self.inds[d] = dict() # 布林线中轨 boll_mid = bt.ind.BBands(d.close).mid # 买入条件 self.inds[d]['buy_con'] = bt.And( \ # 突破中轨 d.open < boll_mid, d.close > boll_mid, \ # 放量 d.volume == bt.ind.Highest(d.volume, period = self.p.p_period_volume, plot = False)) # 卖出条件 self.inds[d]['sell_con'] = d.close < bt.ind.SMA(d.close, period = self.p.p_sell_ma)
这里需要注意的是,技术指标在backtrader里是lines对象,而非数值,所以在使用与或操作时,不能使用python自带的and和or操作符,而只能调用backtrader的And和Or函数。对技术指标做比较时可以使用大于号、小于号等符号,这是因为backtrader对这些符号进行了重写。
回测000001后的最终资产为101107.35元:
可以看到,该策略并非每笔交易都会盈利,但是盈利额度较大,亏损额度较小。由于我们选取的交易单位是1000股,而000001的股价只是10元左右,相当于我们只动用了不到20%的资金,因此总盈利额显得较小,如果提高交易手数,盈利总额也会随之提升。
同时回测000001、000002后的最终资产为100082.86元:
同时回测000001、000002、000004后的最终资产为100247.27元:
回测603999后的最终资产为98871.44元:
可以看到该策略也有总体亏损的情况,直觉上判断,该策略可能比较适合大盘股,对小盘股而言,放量的条件比较容易达到,策略缺乏稳定性。
我们进一步尝试将放量突破的标准选为20日以来的最高值时,回测000001的最终资产为100613.27元,可以看到3笔盈利交易,1笔亏损交易。
当我们把回测起始时间改为2008年1月1日后,回测0000001的最终资产为103137.30元,可以看到也存在大量的亏损交易,但是亏损值都较小。
友情提示:本系列学习笔记只做数据分析,记录个人学习过程,不作为交易依据,盈亏自负。
放量突破布林线中轨买入策略代码:
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # 用于datetime对象操作 import os.path # 用于管理路径 import sys # 用于在argvTo[0]中找到脚本名称 import backtrader as bt # 引入backtrader框架 import pandas as pd stk_num = 1 # 回测股票数目 # 创建策略 class BollStrategy(bt.Strategy): # 可配置策略参数 params = dict( p_period_volume = 10, # 前n日最大交易量 p_sell_ma = 5, # 跌破该均线卖出 p_oneplot = False, # 是否打印到同一张图 pstake = 1000, # 单笔交易股票数 ) def __init__(self): self.inds = dict() for i, d in enumerate(self.datas): self.inds[d] = dict() # 布林线中轨 boll_mid = bt.ind.BBands(d.close).mid # 买入条件 self.inds[d]['buy_con'] = bt.And( \ # 突破中轨 d.open < boll_mid, d.close > boll_mid, \ # 放量 d.volume == bt.ind.Highest(d.volume, period = self.p.p_period_volume, plot = False)) # 卖出条件 self.inds[d]['sell_con'] = d.close < bt.ind.SMA(d.close, period = self.p.p_sell_ma) # 跳过第一只股票data,第一只股票data作为主图数据 if i > 0: if self.p.p_oneplot: d.plotinfo.plotmaster = self.datas[0] def next(self): for i, d in enumerate(self.datas): dt, dn = self.datetime.date(), d._name # 获取时间及股票代码 pos = self.getposition(d).size if not pos: # 不在场内,则可以买入 if self.inds[d]['buy_con']: # 如果金叉 self.buy(data = d, size = self.p.pstake) # 买买买 elif self.inds[d]['sell_con']: # 在场内,且死叉 self.close(data = d) # 卖卖卖 def notify_trade(self, trade): dt = self.data.datetime.date() if trade.isclosed: print('{} {} Closed: PnL Gross {}, Net {}'.format( dt, trade.data._name, round(trade.pnl, 2), round(trade.pnlcomm, 2) )) cerebro = bt.Cerebro() # 创建cerebro # 读入股票代码 stk_code_file = '../TQDat/data/tq_stock_code.csv' stk_pools = pd.read_csv(stk_code_file, encoding = 'gbk') if stk_num > stk_pools.shape[0]: print('股票数目不能大于%d' % stk_pools.shape[0]) exit() for i in range(stk_num): stk_code = stk_pools['code'][stk_pools.index[i]] stk_code = '%06d' % stk_code # 读入数据 datapath = '../TQDat/day/stk/' + stk_code + '.csv' # 创建价格数据 data = bt.feeds.GenericCSVData( dataname = datapath, fromdate = datetime.datetime(2018, 1, 1), todate = datetime.datetime(2020, 3, 31), nullvalue = 0.0, dtformat = ('%Y-%m-%d'), datetime = 0, open = 1, high = 2, low = 3, close = 4, volume = 5, openinterest = -1 ) # 在Cerebro中添加股票数据 cerebro.adddata(data, name = stk_code) # 设置启动资金 cerebro.broker.setcash(100000.0) # 设置佣金为千分之一 cerebro.broker.setcommission(commission=0.001) cerebro.addstrategy(BollStrategy, p_oneplot = False) # 添加策略 cerebro.run() # 遍历所有数据 # 打印最后结果 print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.plot() # 绘图
- 点赞
- 收藏
- 分享
- 文章举报
- Python量化交易学习笔记(19)——连续下跌买入止盈止损卖出策略
- Python量化交易学习笔记(20)——保护点卖出策略
- 学习笔记(18):5天Python闯关训练营-104期-反爬策略之代理IP
- Python学习笔记18:标准库之多进程(multiprocessing包)
- python 制作图表 matplotlib - 千月的python linux 系统管理指南学习笔记(18)
- python核心编程学习笔记-2016-08-28-01-习题18-4和习题18-9
- 学习笔记(01):5天Python基础小课-Request header伪装策略
- 【Python】学习笔记——-18、电子邮件
- 【深度学习】笔记18 Ubuntu16.04下python2.7IDLE的安装
- Python学习笔记 18
- 学习笔记(17):5天Python闯关训练营-104期-Request header伪装策略
- python学习笔记18-重点和忘记知识点总结
- Python学习笔记(18)-目录操作与文件读写
- 【python学习笔记】18:numpy数组函数与矩阵运算
- Python学习笔记18-发送邮件
- python学习笔记——爬虫的抓取策略
- Python3 学习笔记18_高级特性(迭代器)_20180308
- python学习笔记十 类文件对象 分类: python基础学习 python 2013-06-18 12:03 254人阅读 评论(0) 收藏
- python学习笔记-(18)python中的动态类型(相当重要)
- 学习笔记(18):Python+OpenCV计算机视觉-图像平滑-高斯滤波