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

news2024/11/18 4:00:06

版权声明:本文为博主原创文章,如需转载请贴上原博文链接:基于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 = None
        self.buyprice = None
        self.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 = 0
        self.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 += 1
            if 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.coloradmin.cn/o/2136234.html

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

相关文章

加速开发体验:为 Android Studio 设置国内镜像源

Android Studio 是由 JetBrains 开发的一个官方 IDE&#xff0c;用于 Android 应用开发。由于网络原因&#xff0c;直接从 Google 的服务器下载可能会比较慢或者不稳定。幸运的是&#xff0c;我们可以通过配置国内镜像源来加速下载和更新。 文章目录 &#x1f4af; 修改 Gradle…

网络工程师学习笔记——网络互连与互联网

互联网的定义 由多个网络相互连接组成更大的网络称为互联网 常见的网络设备&#xff08;是网络拓扑结构和网络的基础&#xff09; 物理层 中继器&#xff08;是将传输的信号进行放大&#xff0c;延长传输的距离&#xff09;&#xff0c;集线器也是这样&#xff0c;但是有更多…

【828华为云征文|全面指南:使用华为云Flexus X部署私人图床】

文章目录 华为云Flexus X实例介绍图床功能介绍部署自己的图床准备工作服务器环境确认宝塔软件商店简单图床一键部署域名解析简单图床安装向导页安装环境检测网站基础配置 访问图床登录页使用图床功能验证效果 总结 华为云Flexus X实例介绍 华为云Flexus云服务是专为中小企业和…

Android系统dumpsys命令详解

文章目录 1. dumpsys 的工作原理2. 基本使用方法执行 dumpsys限制 dumpsys 的输出 3. 常见的 dumpsys 服务1. Activity Manager (activity)2. Battery Service (battery)3. Window Manager (window)4. Package Manager (package)5. Power Manager (power)6. Media DRM (media.d…

supermap icilent3d for cesium加载地形并夸大地形

先看效果图 这是没有夸张之前的都江堰 这是夸大五倍后的都江堰 下面展示代码 主要就是加载supermaponline的skt地形然后夸大 <template><div class"PartOneBox"><div id"cesiumContainer"></div></div> </template>…

【高等数学学习记录】函数

【高等数学&学习记录】函数 从事测绘工作多年&#xff0c;深刻感受到基础知识的重要及自身在这方面的短板。 为此&#xff0c;打算重温测绘工作所需基础知识。练好基本功&#xff0c;为测绘工作赋能。 1 知识点 1.1 函数 设数集 D ⊂ R D\subset R D⊂R&#xff0c;称映射…

MOS管和三极管有什么区别?

MOS管是基于金属-氧化物-半导体结构的场效应晶体管&#xff0c;它的控制电压作用于氧化物层&#xff0c;通过调节栅极电势来控制源漏电流。MOS管是FET中的一种&#xff0c;现主要用增强型MOS管&#xff0c;分为PMOS和NMOS。 MOS管的三个极分别是G(栅极)&#xff0c;D(漏极)&…

企业文件防泄密软件有哪些?|十款主流文件防泄密解决方案

在数据泄露事件频发的今天&#xff0c;企业对文件防泄密解决方案的需求日益增加。选择适合的文件防泄密工具对于保护敏感信息、维护企业声誉和合规性至关重要。本文将盘点十款主流文件防泄密解决方案&#xff0c;帮助企业了解各方案的特点和优势&#xff0c;从而做出明智的选择…

注解(Java程序的一种特殊“注释”,用于工具处理的标注)

1.使用注解 a.含义 i.注解是放在类&#xff0c;字段&#xff0c;方法&#xff0c;参数前的一种特殊“注释”。 ii.注释会被编译器直接忽略&#xff0c;注解则可以被编译器打包带进class文件&#xff0c;因此&#xff0c;注解是一种用于标注的“元数据”。 iii…

链路聚合(Link Aggregation)

链路聚合&#xff08;Link Aggregation&#xff09;&#xff0c;也被称为端口聚合&#xff08;Port Aggregation&#xff09;、捆绑&#xff08;Bonding&#xff09;或团队&#xff08;Teaming&#xff09;&#xff0c;是一种将多个网络接口结合成一个逻辑接口&#xff0c;以提…

网页模板该怎么选

选择网页模板是建立一个成功网站的关键步骤之一。一个合适的网页模板可以提高用户体验&#xff0c;提升网站的专业度&#xff0c;并使内容更易于阅读。在选择网页模板时&#xff0c;需要考虑多个因素&#xff0c;包括网站类型、目标受众、内容类型以及个人品味。以下是一些建议…

【时时三省】(C语言基础)指针进阶 例题7

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 二维数组 第一个a 因为它有12个元素 每个元素占4个字节 所以就打印48 第二个a&#xff3b;0&#xff3d;&#xff3b;0&#xff3d; 表示是第一行第一个元素 所…

35岁嫌老,65嫌年轻,程序员还有路子吗?

如今&#xff0c;延迟退休的概念越来越被人们所接受和认同。35岁嫌老&#xff0c;65嫌年轻成为了当下社会的新趋势。然而&#xff0c;对于那些本来就存在着35岁危机的程序员们来说&#xff0c;如何应对这一挑战&#xff0c;迎接新的职业生涯呢&#xff1f; 在这篇文章中&#…

出处不详 投篮

目录 投篮题目描述背景输入输出数据范围 题解解法 打赏 投篮 题目描述 背景 现在你得到了一个可以阻拦投篮的宝物&#xff0c;它会在投球后把篮球传送回运动员手上&#xff0c;但是宝物的成功率和篮球在空中运动的时间有关&#xff0c;并且在特定的时间点成功的几率是固定的…

大势智慧与山东省国土测绘院签署战略合作协议

9月6日&#xff0c;山东省国土测绘院&#xff08;后简称山东院&#xff09;与武汉大势智慧科技有限公司&#xff08;后简称大势智慧&#xff09;签署战略合作协议。 山东院院长田中原、卫星应用中心主任相恒茂、基础测绘中心主任魏国忠、卫星应用中心高级工程师张奇伟&#xf…

S32G EB tresos AutoCore下载和激活方法

文章目录 1. 下载1.1 EB tresos AutoCore下载1.2 EB激活工具&#xff08;EB_Client_License_Administrator&#xff09;下载 2 安装3 激活4 展示 本文将介绍EB tresos的AutoCore&#xff08;CP BSW配置工具&#xff09;和MCAL驱动安装包的下载、安装和激活方法。 更多AUTOSAR C…

lightdm , xrandr , startx 桌面管理器,窗口管理器

问题&#xff1a; 了解这几个的含义。 显示服务器 这个不是很明白 显示管理器&#xff0c; 知道就行了&#xff0c;也不是很明白。 窗口管理器。 桌面管理器。 这个其实就是 桌面环境了&#xff0c; 我们的板卡上使用的是xface 。 这个 xface 是一个集合&#xff0c;这里面…

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

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

计算左边(比自己小的元素)的最长距离

前言&#xff1a;一般做的题目都是使用单调栈来求出距离这个点最近的那个比这个数大或小的元素&#xff0c;但是如果是需要找到最远的那个元素呢&#xff1f;我们可以用到类似逆序对的思路&#xff0c;我们先进行排序从小到大&#xff0c;接着我们先处理左边&#xff0c;每次维…

RSTP/MSTP 笔记和配置实验

RSTP: Rapid Spanning Tree Protocol &#xff08;802.1w&#xff09; 一、问题: Why RSTP 可以快速切换&#xff1f; 1、端口角色增加: 两种到五种 从 STP 的两种角色: DP&#xff1a;Designated Port RP&#xff1a;Root Port 增加到了五种角色&#…