本章节我们做回测一个比较偏实际买卖策略,以笔者买过1年多的中国国航601111为例子,

策略为:笔者认为如果5日均线高于10日均线,就认为股价处于上升阶段,就全仓位买入,如果5日均线低于10日均线,笔者认为股价处于下降阶段,全仓位卖出。

我们准备的数据为2006-8-18到2022-3-22 这段时间的中国国航的日行情数据

以下是代码:

import tushare as ts
import pandas as pdimport datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])
# Import the backtrader platform
import backtrader as btclass MyStrategy(bt.Strategy):# 策略参数params = dict(period5=5,  # 5均线周期period10=10,  # 10均线周期look_back_days=30,printlog=False)def __init__(self):self.mas = dict()self.mas10 = dict()# 遍历所有股票,计算20日均线for data in self.datas:self.mas[data._id] = bt.ind.SMA(data.close, period=self.p.period5)self.mas10[data._id] = bt.ind.SMA(data.close, period=self.p.period10)def next(self):# 得到当前的账户价值total_value = self.broker.getvalue()p_value = total_value * 0.9 / 10for data in self.datas:# 获取仓位pos = self.getposition(data).sizeif self.mas10[data._id][0] < self.mas[data._id][0]:size = int(p_value / 100 / data.close[0]) * 100print('10日均线价格->' + str(self.mas10[data._id][0]) + ',5日均线价格->' + str(self.mas[data._id][0]) + \',持仓数量->' + str(pos) + ',买入数量->' + str(size))self.buy(data=data, size=size)if pos > 0 and self.mas10[data._id][0] > self.mas[data._id][0]:print('10日均线价格->' + str(self.mas10[data._id][0]) + ',5日均线价格->' + str(self.mas[data._id][0]) + \',持仓数量->' + str(pos) + ',买入数量->' + str(pos))self.order = self.sell(data=data, size=pos)def log(self, txt, dt=None, doprint=False):if self.params.printlog or doprint:dt = dt or self.datas[0].datetime.date(0)print(f'{dt.isoformat()},{txt}')# 记录交易执行情况(可省略,默认不输出结果)def notify_order(self, order):# 如果order为submitted/accepted,返回空if order.status in [order.Submitted, order.Accepted]:return# 如果order为buy/sell executed,报告价格结果if order.status in [order.Completed]:if order.isbuy():self.log(f'买入:\n价格:{order.executed.price:.2f},\成本:{order.executed.value:.2f},\数量:{order.executed.size:.2f},\手续费:{order.executed.comm:.2f}')self.buyprice = order.executed.priceself.buycomm = order.executed.commelse:self.log(f'卖出:\n价格:{order.executed.price:.2f},\成本: {order.executed.value:.2f},\数量:{order.executed.size:.2f},\手续费{order.executed.comm:.2f}')self.bar_executed = len(self)# 如果指令取消/交易失败, 报告结果elif order.status in [order.Canceled, order.Margin, order.Rejected]:self.log('交易失败')self.order = None# 记录交易收益情况(可省略,默认不输出结果)def notify_trade(self, trade):if not trade.isclosed:returnself.log(f'策略收益:\n毛收益 {trade.pnl:.2f}, 净收益 {trade.pnlcomm:.2f}')pro = ts.pro_api('cbb257058b7cb228769b4949437c27c27e5132e882747dc80f01a5a5')def ts_get_daily_stock(code, start_dt, end_dt):start_dt = start_dt.replace("'", "", 3);end_dt = end_dt.replace("'", "", 3);# start_dt = '20190101'# end_dt=''print(code, start_dt, end_dt)data = pro.daily(ts_code=code, start_date=start_dt, end_date=end_dt)data['trade_date'] = pd.to_datetime(data['trade_date'])data['trade_date'] = pd.to_datetime(data['trade_date'])data = data.sort_values(by='trade_date')data.index = data['trade_date']data['openinterest'] = 0data['volume'] = data['vol']data = data[['open', 'close', 'high', 'low', 'volume']]return data# 读取选股的结果
df = pd.read_csv('stock_alpha.csv')
df.columns = ['ts_code', 'name', 'alpha', 'start_dt', 'end_dt']
min_a = df.sort_values(by='alpha')
min_a = min_a.iloc[:10, :]code = []
code = min_a['ts_code']  # 记录alpha最小的10支股票代码start_dts = []
start_dts = min_a['start_dt']  # 记录alpha最小的10支股票代码end_dts = []
end_dts = min_a['end_dt']  # 记录alpha最小的10支股票代码for i in range(len(code)):data = ts_get_daily_stock(code.iloc[i], start_dts.iloc[i], end_dts.iloc[i])  # 字段分别为股票代码、开始日期、结束日期data.to_csv(code.iloc[i] + '.csv')cerebro = bt.Cerebro()
for i in range(len(code)):  # 循环获取10支股票历史数据dataframe = pd.read_csv(code.iloc[i] + '.csv', index_col=0, parse_dates=True)dataframe['openinterest'] = 0data = bt.feeds.PandasData(dataname=dataframe,fromdate=datetime.datetime(2006, 8, 18),todate=datetime.datetime(2022, 3, 22))
cerebro.adddata(data)# 回测设置
startcash = 100000.0
cerebro.broker.setcash(startcash)
# 设置佣金为千分之一
cerebro.broker.setcommission(commission=0.001)
# 添加策略
cerebro.addstrategy(MyStrategy, printlog=True)
cerebro.run()
# 获取回测结束后的总资金
portvalue = cerebro.broker.getvalue()
pnl = portvalue - startcash
# 打印结果
print(f'总资金: {round(portvalue,2)}')
print(f'净收益: {round(pnl,2)}')cerebro.plot()

以上的代码如果配置好环境可以直接运行,得到结果

总资金: 230494.3
净收益: 130494.3

执行结果图为:

让我意想不到的是这个策略竟然是盈利的,从2006年开始到2022年,中间经历过2008、2015、2020这么惨烈的时代,竟然还有盈利,看来有时候简单的打法反而是最有效的打法。

后续笔者会继续为大家做讲解指标的获取和基础数据的获取

量化交易5-backtrader编写均线策略相关推荐

  1. 量化交易 聚宽 双均线策略

    量化交易 聚宽 双均线策略 # 导入函数库 from jqdata import *# 初始化函数,设定基准等等 def initialize(context):# 设定沪深300作为基准set_be ...

  2. 量化交易入门之vnpy简单策略编写

    本篇博客将介绍量化交易框架vnpy的简单策略编写.在阅读本博客前的环境准备请看我的上一篇博客.传送门如下: 零基础搭建量化交易框架 一.开发环境 因为python版本兼容有点差,且源码功能都有所变化, ...

  3. 量化交易初级阶段——简单多因子策略实现指数增强

    多因子策略是量化交易之中最为常见的策略之一,相当于技术指标之中的均线,只要是学量化都会学到多因子策略. 多因子的总体思路很像高考.现在高考也是刚刚结束,也祝愿各位考生金榜题名!我就按照高考的思路简单说 ...

  4. 量化交易 聚宽 布林带策略

    量化交易 聚宽 布林带策略 # 导入函数库 from jqdata import *# 初始化函数,设定基准等等 def initialize(context):# 使用真实价格set_option( ...

  5. 量化交易 聚宽 均值回归策略

    量化交易 聚宽 均值回归策略 # 导入函数库 from jqdata import *# 初始化函数,设定基准等等 def initialize(context):# 设定沪深300作为基准set_b ...

  6. 量化交易 聚宽 多因子策略(市值, ROE)

    量化交易 聚宽 多因子策略(市值, ROE) # 导入函数库 from jqdata import *# 初始化函数,设定基准等等 def initialize(context):# 设定沪深300作 ...

  7. 量化交易入门阶段:动量策略和均线结合又会怎样?

    在之前的文章<找到真"学霸"--动量策略优化>中跟大家说了一下动量策略可以通过选择那些涨幅排名靠前,并且涨幅大于200%的股票进行策略优化. 在更早之前,和大家讲了很多 ...

  8. 自己做量化交易软件(7)通通量化回测设计2-双均线策略回测

    前一篇介绍了回测类的设计,我们这篇简单介绍一下回测程序设计. 我们以5日均线和20日均线的交叉作为买卖点策略,来计算对一只股票交易的收益情况.这里仅仅是一个双均线策略演示的例子.读者可以在此基础上,修 ...

  9. 【学习笔记】优矿量化交易入门(一)策略框架编写

    半自动化优矿 全自动化IB 面向对象 策略框架编写 start = '2017-01-01' # 回测起始时间 end = '2018-01-01' # 回测结束时间 universe = Dynam ...

最新文章

  1. 2021新款 iPad,包邮送一个!10月25日截止
  2. R语言生存分析寿命表(life table)实战案例:比较两种药物治疗感染患者的生存时间
  3. Ruby中爬虫的实现
  4. moco 搭建接口mock环境入门
  5. 【ARM】Tiny4412裸机编程之LED(一)
  6. __declspec(dllimport)
  7. This application failed to start because it could not find or load the Qt platform plugin xcb in
  8. ubuntu与win10互换硬盘
  9. java中输出系统时间
  10. diff算法阮一峰_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法
  11. MBTI性格类型测试
  12. tflite C++ API 部署分类模型
  13. mysql简述光标_MySQL数据库光标使用介绍
  14. 计算机三级权限管理方法,Serv―U 三级用户权限机制及配置一例
  15. win10+GeForce 940mx安装cuda
  16. 图像处理空间域、变换域、时域和频域的含义理解:spatial VS transforms domain
  17. Exception in thread “main“ java.lang.ClassCastException 类型转换异常
  18. 开发者除了技术硬实力之外,还有哪些不可或缺的软实力
  19. iOS教程:移动终端游戏动画设计的12个原则
  20. 历代诗词咏宁夏注释1----常星景: 六盘

热门文章

  1. jQuery--复制节点clone()详解
  2. 同向放大器、反向放大器的区别
  3. USDCNY--USDCNH 配对交易___境内及离岸人民币即期的协整关系及配对交易策略分析
  4. 债券的到期收益率、即期收益率、远期收益率及远期利率的推导
  5. Java后端生成Echarts并渲染Word转PDF
  6. 机器翻译古文也翻车?读了20次“苟富贵勿相忘”后,谷歌:没钱的人总会被遗忘...
  7. 怎样在Mac上查找WiFi密码并在iPhone上共享它?
  8. MySQL 使用 Workbench 建表时 PK NN UQ BIN UN ZF AI G 的含义
  9. 前端jQuery的jQuery 插件库的插件(使用方法)
  10. 谈谈第一次Web项目的感想(上)