基于Python的量化交易回测框架Backtrader初识记录(二)

版权声明:本文为博主原创文章,如需转载请贴上原博文链接:基于Python的量化交易回测框架Backtrader初识记录(二)-CSDN博客


前言:在上一篇文章 基于Python的量化交易回测框架Backtrader初识记录(一)中,已经初步建立了策略框架并进行了简单回测,但是使用的个股数据还是未复权的,导致K线图看上去显得很异常(例如会出现大幅跳空),且如果建立在未复权的数据上进行量化策略回测操作,很可能会造成策略失效或者异常执行,故本篇借助Tushare的复权因子将个股数据进行前复权处理并制定简单的sma量化策略进行回测验证。


目录

一、数据准备

1.1 个股数据获取

1.2 前复权数据处理

二、简单的SMA量化策略回测

2.1 指标定义

2.2 策略制定

2.2.1 入场/出场策略

2.2.2 买入策略

2.2.3 卖出策略

三、实例“000001.SZ 平安银行”的简单SMA量化策略回测

附:多种个股的SMA量化策略回测结果

盈利实例

亏损实例


一、数据准备

1.1 个股数据获取

        本篇内容基于《A股行情数据获取&量化交易策略的结构设计》项目完成,故直接使用本地数据库中的数据完成回测。

1.2 前复权数据处理

        当完成上述项目中的前两个步骤之后,个股数据就全部存储到本地了,那么接下来就要将复权因子存储到本地,运行`Module/mysql_data_storage.py`文件后,如图1.1所示,就在本地新建了关于复权因子的数据库。

【在进行前复权数据处理过程中遇到一些问题,比如复权因子数量多于个股日线行情数量而并非一一对应(猜测因为个股在不开盘期间是没有数据的,而复权因子是一年365天都有数据所导致的),但此处不是本文重点故作简述】

图1.1 复权因子数据库

二、简单的SMA量化策略回测

2.1 指标定义

        在策略类的初始化函数中定义需要使用到的指标,如下代码所示,使用到的指标总共就三个,分别是`MovingAverageSimple`、`AccelerationDecelerationOscillator`和`RelativeStrengthIndex`,其中主要通过`MovingAverageSimple`指标来进行买卖点的判断,剩余两个作为辅助指标:

MovingAverageSimple():简单移动平均线

AccelerationDecelerationOscillator():加速/减速振荡器(协助判断趋势变化的量能)

RelativeStrengthIndex():相对强度指数(协助判断股票买卖力量对比)

class MyStrategy(bt.Strategy):# 设置周期(数字代表天数)params = (('p5', 5), ('p10', 10), ('p20', 20), ('p30', 30), ('p45', 45), ('p60', 60))def __init__(self, ):"""Constructor for MyStrategy"""# 使用数据的close(收盘价格)self.dataclose = self.datas[0].close# 跟踪待处理订单、买价、佣金self.order = Noneself.buyprice = Noneself.buycomm = None# ============ 参数与指标定义 ============# 添加SMA指标self.sma_5 = bt.indicators.MovingAverageSimple(period=self.p.p5)self.sma_10 = bt.indicators.MovingAverageSimple(period=self.p.p10)  # 默认均线周期是10天,可自行设置self.sma_20 = bt.indicators.MovingAverageSimple(period=self.p.p20)  # 默认均线周期是20天,可自行设置self.sma_30 = bt.indicators.MovingAverageSimple(period=self.p.p30)  # 默认均线周期是30天,可自行设置self.sma_45 = bt.indicators.MovingAverageSimple(period=self.p.p45)  # 默认均线周期是45天,可自行设置self.sma_60 = bt.indicators.MovingAverageSimple(period=self.p.p60)  # 默认均线周期是60天,可自行设置# 买卖点标志self.count = 0self.sma_bs1 = self.sma_5 - self.sma_10  # >0:5天均线由零值以下上穿10天均线;<0:反之同理self.sma_bs2 = self.sma_20 - self.sma_30  # >0:20天均线由零值以下上穿30天均线;<0:反之同理# 添加辅助指标self.accdeosc = bt.indicators.AccelerationDecelerationOscillator()  # 加减速振荡器self.rsi = bt.indicators.RelativeStrengthIndex()  # 相对强弱指标

2.2 策略制定

         想要在市场中获利,从趋势角度而言,上升趋势会比在下降趋势中更容易;从收益角度而言,卖出价格一定要高于买入价格(在不考虑佣金等其他费用的情况下,至少卖出价格要不低于买入价格)才不会有亏损,那么根据这三个指标建立的策略如下所示:

    def next(self):"""# 策略核心:均线和趋势能量买卖策略:return:"""# 显示收盘价self.log('Close, %.2f' % self.dataclose[0])# 如果存在待处理订单则不能发起第二个订单if self.order:return# 检查是否在市场(如果已经有仓位则不能再次买入)if not self.position:# 买入前提:均线不能呈下降趋势# 买点要求(需要同时满足):#           1.20天均线上穿30天均线#           2.20天均线呈上升趋势#           3.连续两天下跌的能量变弱或连续两天上涨的能量变强if not self.sma_30 < self.sma_45 < self.sma_60:  # 60天、45天、30天均线依次呈下降趋势,且前一根压着后一根if (self.sma_bs2[-1] < 0 < self.sma_bs2[0]) and \(self.sma_20[-1] < self.sma_20[0]) and \(self.accdeosc[-2] < self.accdeosc[-1] < self.accdeosc[0]):self.log('BUY CREATE, %.2f' % self.dataclose[0])self.order = self.buy()  # 跟踪创建的订单,避免出现第二个订单else:# 卖出前提:上升趋势减弱或被向下突破则卖出# 卖点要求(需要同时满足):#           1.连续两天收盘价在20天均线以下#           2.连续三天上涨的能量变弱或连续下跌的能量变强#           3.五天均线在10天或20天均线之下if self.accdeosc[-1] > self.accdeosc[0]:self.count += 1if self.dataclose[0] < self.sma_20 and \self.dataclose[-1] < self.sma_20 and \self.count >= 3 and \(self.sma_5 < self.sma_10 or self.sma_5 < self.sma_20):self.log('SELL CREATED, %.2f' % self.dataclose[0])self.order = self.sell()  

        下面简述一下买卖策略的主要思路:

2.2.1 入场/出场策略

        首先最重要的就是,在卖出股票之前,你在市场上必须得要有仓位,换句话说就是,你手上一定要有股票才能够卖出(这里仅针对股票,不针对期货等其他金融产品),这里设计的就是最简单的进场/出场策略:空仓才能执行买策略,非空仓(即有仓位)才能执行卖策略

if not self.position:xxx
else:xxx

2.2.2 买入策略

        如前面所说,买入是为了盈利的,那么在下降趋势下盈利的可能就没有在上升趋势下盈利的可能性高,所以给出买入之前的大前提:市场必须不能处在下降趋势下:

# 60天、45天、30天均线依次呈下降趋势,且前一根压着后一根
if not self.sma_30 < self.sma_45 < self.sma_60:  xxx

        当然,这样定义上升趋势不太严谨 ,有过实操经验的都知道,更加严谨的表达应该是:短期移动均线压制中期移动均线,中期移动均线压制长期移动均线,同时各个时期的均线也要依次上升,简单代码化之后应该写成:

if (self.sma_30 > self.sma_45 > self.sma_60) and \(self.sma_30[-1] > self.sma_30[0]) and \(self.sma_45[-1] > self.sma_45[0]) and \(self.sma_60[-1] > self.sma_60[0]):

         但是这样依然会带来影响,过于严苛的策略条件一方面很可能没有符合的标的,另一方面即使有符合的标的,能够处于如此严苛条件下的时期也不会很长,为了追求完美的交易策略只会损失掉更多的收益。如此我们暂且放宽要求与范围,来制定买入策略。

# >0:5天均线由零值以下上穿10天均线;<0:反之同理

self.sma_bs1 = self.sma_5 - self.sma_10  

# >0:20天均线由零值以下上穿30天均线;<0:反之同理
self.sma_bs2 = self.sma_20 - self.sma_30  

=======================================================

① self.sma_bs2[-1] < 0 < self.sma_bs2[0]   ->  20日均线上穿30日均线
② self.sma_20[-1] < self.sma_20[0]             -> 20日均线呈上升趋势
③ self.accdeosc[-2] < self.accdeosc[-1] < self.accdeosc[0]        -> 连续两天下跌的能量变弱或连续两天上涨的能量变强

        当满足以下三点,就是进场买入的时机:① 20天均线上穿30天均线;② 20天均线呈上升趋势;③ 连续两天下跌的能量变弱或连续两天上涨的能量变强;

2.2.3 卖出策略

        看到这里,如果有小伙伴说,卖出策略就仿照买入策略来制定呗:当行情出现下降趋势就卖出;如果这样操作可要出大事了!真的要等到行情出现下降趋势,很可能股价都已经跌到谷底了,那要如何制定卖出策略呢?在制定卖出策略之前,要清楚我们的目的是什么,很显然是要盈利,要让我们手中的筹码来给我们赚钱,那么如何才能有盈利呢?

        正如2.2节刚开始所说的,卖出价格高于买入价格即可(不考虑其他费用),这就是卖出操作的其中一种:止盈;当然第二种卖出操作就是止损,本节主要针对第一种卖出操作进行策略规划。

        在卖出之前,先让策略自己记录当前趋势的能量,如下,每当后一天能量小于前一天能量,那么计数器就+1:

if self.accdeosc[-1] > self.accdeosc[0]:self.count += 1

        当同时满足下列四个条件,则卖出;

① self.dataclose[0] < self.sma_20
② self.dataclose[-1] < self.sma_20    -> ①和②:连续两天的收盘价低于20日均线
③ self.count >= 3    -> 连续三天上涨的能量变弱或连续下跌的能量变强
④ self.sma_5 < self.sma_10 or self.sma_5 < self.sma_20    -> 五天均线在10天或20天均线之下

        当然,同时满足四个条件再执行卖出操作难免会太过绝对,而且可能会出现第一天刚买入就开始下跌,来不及止损,到第二天再卖出就已经亏损的情况,这时就需要对策略进行相应的优化了。 

三、实例“000001.SZ 平安银行”的简单SMA量化策略回测

        如图3.1所示为平安银行2022年1月1日至今的SMA量化策略的回测结果,自上而下:

第一栏(‘Broker’——(券商)经纪人/代理人,此处的券商相当于你的代理人,由你的代理人代替你进行交易操作)表示券商手中的现金和股票总价值,红色线表示券商手中的现金余量,蓝色线表示券商手中现金和手中持股的总价值;

第二栏(‘Trades - Net Profit/Loss’——交易净利润/亏损)展示的就是量化交易策略执行的两次买卖操作,蓝色点表示该次操作获得利润,红色点表示该次操作亏损;

第三栏就是K线和成交量主体以及各类移动平均线,绿色^表示买入K线,红色v表示卖出K线;

第四栏是ACCDE(加速/减速振荡器)指标,用来辅助进行策略买卖;

第五栏是RSI(相对强度指数)指标,同样用来辅助进行策略买卖;

图3.1 平安银行的量化回测结果

        经历两年多,该量化策略只进行了两次买卖操作,没有丰厚的盈利也没有造成大幅亏损,从K线图来看,可是存在不少可交易的买卖点的,但是该策略却没有如愿的进行,由此也可见固定的策略依然不能够很好的匹配个股,看来简单的指标还是有局限性,后续会再尝试不同的指标来制定不同的量化策略。至此,简单的SMA量化策略回测结束,以下附带一些其他的个股通过该策略所得的回测结果。

附:多种个股的SMA量化策略回测结果

盈利实例

附1 GSYH
附2 HKWS

亏损实例

附3 ZXZQ
附4 NDSD
附5 HWJ

以上结果均可自行复现,代码见1.1节中的项目。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1534880.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

转置卷积与反卷积的区分

transposed convolution&#xff08;转置卷积&#xff09;和deconvolution&#xff08;反卷积&#xff09;是两个完全不同的概念。 deconvolution为“inverse of convolution”、“inverse filter”&#xff0c;翻译为反卷积、解卷积。在信号处理中&#xff0c;反卷积是指从卷积…

Golang协程泄漏定位和排查

Golang协程泄漏定位和排查 1 场景&#xff1a;无缓冲channel写阻塞2 排查和定位思路2.1 Golang pprof2.2 协程数监控2.3 操作系统内存泄漏 参考 1 场景&#xff1a;无缓冲channel写阻塞 package mainimport ("log""net/http"_ "net/http/pprof"…

JavaScript --函数的作用域(全局和局部)

全局作用域 全局作用域&#xff0c;就算不在一个script标签也能调用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta nam…

【win工具】win安装flameshot并设置截图快捷键

1.下载flameshot软件2.windows端配置flameshot快捷键3.取消win自带截图快捷键 1.下载flameshot软件 https://flameshot.org/#download installer版本为安装包 portable版本为免安装版 2.windows端配置flameshot快捷键 https://cloud.tencent.com/developer/article/2114952 W…

第三方软件测评机构分享:软件性能测试的测试方法和内容

软件性能测试是对软件系统在特定负载和条件下的性能进行评估的过程。它旨在确定软件的响应时间、稳定性、资源消耗及其可扩展性&#xff0c;以确保其在实际环境中能够满足用户的需求。通过性能测试&#xff0c;开发团队能够发现潜在的瓶颈问题&#xff0c;优化应用程序架构&…

Spring3-IoC1-IoC容器、基于xml管理bean

目录 IoC容器 概述 依赖注入 IoC容器在Spring中的实现 基于xml管理bean 获取bean 依赖注入 setter注入 构造器注入 特殊值处理 字面量赋值 null值 xml实体 CDATA节 特殊类型属性注入 对象类型属性注入 方式一&#xff1a;引用外部bean 方式二&#xff1a;内部…

基于OpenSSL的密码管理系统-应用密码学课程报告

第1章 概要设计 1.1 设计目的 本研究旨在设计并实现一个基于OpenSSL的密码管理系统&#xff0c;该系统具备密钥对的生成、密钥上传、密钥的核对、身份认证、文件与邮件的加密和解密、数字签名及数字证书管理等常用功能。研究的意义主要体现在以下几个方面&#xff1a; 提升网…

M3U8是什么,如何解析下载

M3U8是什么&#xff1f;如何解析下载 M3U8是苹果公司推出的视频播放标准&#xff0c;准确来说是一种索引文件&#xff0c;使用M3U8文件实际上是通过它来解析对应的放在服务器上的视频网络地址&#xff0c;从而实现在线播放。M3U8文件使用UTF-8字符编码。M3U8是一种常见的流媒体…

互联网巨头的默契

​转载&#xff1a;树龙谈 作者&#xff1a;贺树龙 2024年的第二季度财报&#xff0c;大部分互联网公司都已经发布了。 分析已上市、最值钱的10家中国互联网公司的财报&#xff0c;不难发现这些相似之处&#xff1a; 1.它们的营收增长比较乏力&#xff1b; 2.它们的净利润增长…

工作流技术(WorkFlow)

什么是工作流 1.使用编程语言完成一套固定的审批流程 例如请假审批流程 订单配送流程 入职&#xff0c;辞职审批流程 2.使用场景 业务类&#xff1a;合同审批流程、订单处理流程、出入库审批流程等。 行政类&#xff1a;请假流程、出差流程、用车流程、办公用品申请流程…

dedecms(四种webshell姿势)

步骤一&#xff0c;登录网站 步骤二&#xff0c;进入后台 账号密码同为admin 姿势一&#xff0c;通过文件管理器上传WebShell 登陆到后台点击 【核心】--》【文件式管理器】【文件上传】 将准备好的一句话代码上传...OK 1.我们先创建一个1.php上传 2.上传之后我们双击1.php 3…

还有人认为C++容器是线程安全的吗?

C标准库中的容器&#xff08;如std::vector, std::list, std::map等&#xff09;本身不是线程安全的、不是线程安全的、不是线程安全的&#xff0c;重要的事情讲三遍。这意味着如果你在多线程环境中同时访问&#xff08;读或写&#xff09;同一个容器实例&#xff0c;而没有进行…

【二叉树的最大深度】带你理解递归奥妙!

&#x1f680;个人主页&#xff1a;一颗小谷粒 &#x1f680;所属专栏&#xff1a;力扣刷题 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1.1 题目要求 ​&#x1f4a5;1.2 算法思路 &#x1f4a5;1.3 图解分析 &#x1…

elementui组件el-upload实现批量文件上传

el-upload组件上传文件时&#xff0c;每传一个文件会调一次接口&#xff0c;所以当上传多个文件的时候&#xff0c;有 n 个文件就要调 n 次接口。 刚好之前工作中遇到使用el-upload组件批量上传文件的需求&#xff0c;来看看怎么实现。 思路&#xff1a; 1.取消组件的自动上…

Springboot项目总结

1.为了调用写在其他包里面的类的方法 但是不使用new来实现调用这个类里面的方法&#xff0c;这个时候我们就需要将这个类注入到ioc容器里面&#xff0c;通过ioc容器来实现自动生成一个对象。 对ioc容器的理解&#xff1a;自动将一个对象实现new. 考察了and 和 or组合使用&…

[docker]入门

本文章主要讲述的是&#xff0c;docker基本实现原理&#xff0c;docker概念的解释&#xff0c;docker的使用场景以及docker打包与部署的应用。 文章中docker所运行的系统&#xff1a;CentOS Linux release 7.9.2009 (Core) 目录 docker是什么&#xff0c;什么时候需要去使用 …

房产销售系统:SpringBoot技术优势分析

第三章 系统分析 3.1 系统设计目标 房产销售系统主要是为了用户方便对房源信息管理、房源类型管理、房子户型管理、交易订单管理、预约看房管理、评价管理等信息进行查询&#xff0c;也是为了更好的让管理员进行更好存储所有数据信息及快速方便的检索功能&#xff0c;对系统的各…

5.安卓逆向-java面向对象

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 上一个内容&#xff1a;4.安卓逆向-常用数据结构java语言中的集合 之前的内容写了java语言常用的数据结构&#xff08…

OpenAI o1:AI领域的“草莓”革命,华人科学家贡献卓越

最近&#xff0c;科技界的热门明星“草莓”频繁出现在大家的视线中。9月11号&#xff0c;The Information报道称&#xff1a;OpenAI计划在未来两周内推出一款更智能、更昂贵、更谨慎的AI模型&#xff01;网友们对此消息持怀疑态度&#xff0c;认为类似消息屡见不鲜&#xff0c;…

创新数字生态:智慧园区的益处与影响

智慧园区是一种利用先进信息技术、智能设备和数据分析手段来提升管理效率、改善居住体验、节约资源以及推动可持续发展的新型城市发展模式。其好处和影响不仅局限于提高工作效率&#xff0c;还涉及社会、生态、经济等多个方面的积极影响。 好处 智能化管理优势: 智慧园区能够实…