量化交易入门(二十六)RSI指标实现,能盈利吗?

RSI的理论学完了,我们接着用苹果股票的历史数据来回测一下,看看这个指标靠不靠谱。

示例代码
  • import backtrader as bt
    import yfinance as yf
    
    # 定义RSI策略
    class RSIStrategy(bt.Strategy):
        params = (
            ('rsi_period', 14),
            ('rsi_upper', 70),
            ('rsi_lower', 30),
        )
    
        def __init__(self):
            self.rsi = bt.indicators.RSI(self.data.close, period=self.params.rsi_period)
    
    
        def next(self):
            if not self.position:
                if self.rsi < self.params.rsi_lower:
                    commission_info = self.broker.getcommissioninfo(self.data)
                    cash = self.broker.get_cash() - commission_info.getsize(1, self.data.close[0])
                    size = cash // self.data.close[0]
                    self.buy(size=size)
                    print(f'BUY: {size} shares')
            else:
                if self.rsi > self.params.rsi_upper:
                    size = self.position.size
                    self.close(size=size)
                    print(f'SELL: {size} shares')
    
    
        
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                return
    
            if order.status in [order.Completed]:
                if order.isbuy():
                    print(f'BUY executed at {self.data.num2date(order.executed.dt).date()}, Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f}, Comm: {order.executed.comm:.2f}')
                elif order.issell():
                    cost = order.executed.value
                    profit = order.executed.value - order.created.size * order.created.price
                    profit_percent = (profit / cost) * 100
                    print(f'SELL executed at {self.data.num2date(order.executed.dt).date()}, Price: {order.executed.price:.2f}, Cost: {cost:.2f}, Profit: {profit:.2f}, Profit %: {profit_percent:.2f}%')
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                print('Order Canceled/Margin/Rejected')    
    
    
    
    # 创建Cerebro引擎
    cerebro = bt.Cerebro()
    
    # 设置初始资金
    cerebro.broker.setcash(100000.0)
    
    # 下载苹果股票数据
    data = yf.download('AAPL', '2020-01-01', '2023-12-30')
    data = data.dropna()
    
    # 将数据添加到Cerebro引擎中
    data = bt.feeds.PandasData(dataname=data)
    cerebro.adddata(data)
    
    # 添加MACD策略
    cerebro.addstrategy(RSIStrategy)
    
    # 设置佣金为0.1%
    cerebro.broker.setcommission(commission=0.001)
    
    # 添加分析指标
    cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
    
    # 运行回测
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    results = cerebro.run()
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
    # 获取回测结果
    strat = results[0]
    returns = strat.analyzers.returns.get_analysis()
    sharpe = strat.analyzers.sharpe.get_analysis()
    drawdown = strat.analyzers.drawdown.get_analysis()
    
    # 打印回测指标
    print('Annualized Return: %.2f%%' % (returns['rnorm100']))
    print('Sharpe Ratio: %.2f' % (sharpe['sharperatio']))
    print('Max Drawdown: %.2f%%' % (drawdown['max']['drawdown']))
    print('Max Drawdown Period: %s' % (drawdown['max']['len']))
    
    
    # 绘制回测结果
    cerebro.plot()
代码的详细分析
  1. 导入必要的库:backtrader和yfinance。

  2. 定义RSIStrategy类,继承自bt.Strategy:

  • 定义RSI指标的参数:计算周期(rsi_period)、超买阈值(rsi_upper)和超卖阈值(rsi_lower)。
  • 在__init__方法中,创建RSI指标实例。
  • 在next方法中,根据RSI指标的值生成买卖信号:
    • 如果当前没有持仓,且RSI低于超卖阈值,则计算可用资金并买入相应数量的股票。
    • 如果当前有持仓,且RSI高于超买阈值,则卖出所有持仓。
  • 在notify_order方法中,处理订单执行情况:
    • 如果订单状态为Submitted或Accepted,不做任何操作。
    • 如果订单状态为Completed,打印买入或卖出的详细信息,包括执行日期、价格、成本、佣金等。
    • 如果订单状态为Canceled、Margin或Rejected,打印相应的信息。

     3. 创建Cerebro引擎实例。

     4. 设置初始资金为100000美元。

     5.  从Yahoo Finance下载苹果股票的历史数据,时间范围为2020年1月1日至2023年12月30日,并将数据添加到Cerebro引擎中。

    6. 将RSIStrategy添加到Cerebro引擎中。

    7. 设置交易佣金为0.1%。

    8.  添加分析指标:Returns(回报率)、SharpeRatio(夏普比率)和DrawDown(回撤)。

    9.  运行回测,并打印回测前后的资金情况。

   10. 获取回测结果,并打印年化收益率、夏普比率、最大回撤和最大回撤期。

   11. 绘制回测结果图表。

该代码的主要功能
  1. 使用RSI指标生成买卖信号,当RSI低于超卖阈值时买入,高于超买阈值时卖出。

  2. 在买入时,根据可用资金计算买入数量,以最大化利用资金。

  3. 在订单执行时,打印详细的交易信息,包括买入/卖出日期、价格、成本、佣金等。

  4. 使用Backtrader的内置分析器计算并打印回测指标,如年化收益率、夏普比率和最大回撤等。

  5. 绘制回测结果图表,直观展示策略的表现。

运行的结果怎么样呢?

    

执行结果:
Starting Portfolio Value: 10000.00 
Final Portfolio Value: 114408.26
Annualized Return: 3.43%
Sharpe Ratio: 0.28
Max Drawdown: 19.71%
Max Drawdown Period: 208

根据回测结果,我们可以对该RSI策略的表现进行以下分析:

  1. 最终投资组合价值为114408.26美元,高于初始投资的100000美元,表明该策略取得了正收益。

  2. 年化收益率为3.43%,这个收益率相对较低,可能是因为苹果股价在回测期内上涨幅度有限所致。

  3. 夏普比率为0.28,较低,表明该策略的收益率相对于承受的风险来说不太理想。一般认为,夏普比率大于1才算是好的投资策略。

  4. 最大回撤为19.71%,持续时间达208个交易日,这说明在某些阶段该策略遭受了较大的资金损失,抗风险能力不太理想。

总的来说,这个基于RSI的简单交易策略,虽然最终取得了正收益,但收益率水平一般,风险较高。其主要问题在于:

  1. 单纯依赖RSI指标进行交易决策,缺乏其他辅助指标判断,难以完全捕捉市场时机。

  2. 缺乏风险控制和止损机制,在遇到剧烈行情时容易遭受重大损失。

  3. 没有针对不同市场状况进行策略调整和优化。

因此,为了提高该策略的效果,我们可以考虑:

  1. 增加其他技术指标和基本面分析,综合多种因素做出交易决策。

  2. 设置合理的止损和止盈位,控制单笔交易风险。

  3. 根据市场波动率、趋势等情况动态调整策略参数。

  4. 尝试对不同的时间周期、股票品种进行优化和测试。

  5. 研究先进的机器学习算法,探索更高级的量化策略。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新手体验OceanBase社区版V4.2:离线部署单节点集群

本文源自OceanBase用户的分享 先简单总结如下&#xff1a; 1.本文适合初学者体验OceanBase社区版 v4.2.2 2.仅需准备一台配置为2C/8G的Linux虚拟机 3.通过离线方式安装&#xff0c;以便更直观地了解安装过程 一、Linux系统准备 在宿主机(即你的windows PC电脑)上安装vbox软…

李宏毅【生成式AI导论 2024】第5讲 让语言模型彼此合作,把一个人活成一个团队

GPD4,它也有非常强大的能力。但是GPT4如果跟其他的语言模型合作,他们其实可以发挥1加1大于二的力量。 为什么要让模型合作? 那怎么让模型彼此合作呢?有很多不同的方式。一个可能性是假设你现在手边就有一堆语言模型,他们可能有不同的能力使用,他们可能有不同的成本局来…

如何将几个长度相同的列表并列组合在一起(附:zip函数使用出错原因:巨坑~)

Python中列表对象使用很方便&#xff0c;用Python编程时&#xff0c;经常会遇到将多个长度相同的列表是针对某一组特定对象的&#xff0c;如何能方便的把这些列表组合起来一起使用呢&#xff1f;ZIP()函数可以方便的解决这个问题。 一、将几个长度相同的列表并列组合 例如&am…

2014年认证杯SPSSPRO杯数学建模B题(第二阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现&#xff1a; 图形&#xff08;或图像&#xff09;在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形&#xff0c;位图则使用像素来描述图像。一般来说&#…

3D产品可视化SaaS

“我们正在走向衰退吗&#xff1f;” “我们已经陷入衰退了吗&#xff1f;” “我们正在步入衰退。” 过去几个月占据头条的问题和陈述引发了关于市场对每个行业影响的讨论和激烈辩论。 特别是对于科技行业来说&#xff0c;过去几周一直很动荡&#xff0c;围绕费用、增长和裁…

1.8 python 模块 time、random、string、hashlib、os、re、json

ython之模块 一、模块的介绍 &#xff08;1&#xff09;python模块&#xff0c;是一个python文件&#xff0c;以一个.py文件&#xff0c;包含了python对象定义和pyhton语句 &#xff08;2&#xff09;python对象定义和python语句 &#xff08;3&#xff09;模块让你能够有逻辑地…

Tomcat 单机多实例一键安装

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

Linux安装redis(基于CentOS系统,Ubuntu也可参考)

前言&#xff1a;本文内容为实操记录&#xff0c;仅供参考&#xff01; 一、下载并解压Redis 1、执行下面的命令下载redis&#xff1a;wget https://download.redis.io/releases/redis-6.2.6.tar.gz 2、解压redis&#xff1a;tar xzf redis-6.2.6.tar.gz 3、移动redis目录&a…

D. Friends and Subsequences 线段树上二分

有个细节&#xff0c;就是query的时候的顺序&#xff0c;不注意到直接T飞&#xff0c;分析知道如果它只在一边的话你直接一边 可以保证复杂度 #include<iostream> #include<cstring> #include<algorithm>const int N 2e510; using namespace std; using ll…

MySQL 数据库的日志管理、备份与恢复

一. 数据库备份 1.数据备份的重要性 备份的主要目的是灾难恢复。 在生产环境中&#xff0c;数据的安全性至关重要。 任何数据的丢失都可能产生严重的后果。 造成数据丢失的原因&#xff1a; 程序错误人为,操作错误,运算错误,磁盘故障灾难&#xff08;如火灾、地震&#xff0…

比较AI编程工具Copilot、Tabnine、Codeium和CodeWhisperer

主流的几个AI智能编程代码助手包括Github Copilot、Codeium、Tabnine、Replit Ghostwriter和Amazon CodeWhisperer。 你可能已经尝试过其中的一些&#xff0c;也可能还在不断寻找最适合自己或公司使用的编程助手。但是&#xff0c;这些产品都会使用精选代码示例来实现自我宣传…

Vue挂载全局方法

简介&#xff1a;有时候&#xff0c;频繁调用的函数&#xff0c;我们需要把它挂载在全局的vue原型上&#xff0c;方便调用&#xff0c;具体怎么操作&#xff0c;这里来记录一下。 一、这里以本地存储的方法为例 var localStorage window.localStorage; const db {/** * 更新…

如何在 Mac Pro 上恢复丢失的数据?

无论您多么努力&#xff0c;几乎不可能永远不会无意中删除 Mac 上的文件。当您得知删除后清空了垃圾箱时&#xff0c;您的处境可能看起来很黯淡。不要灰心。我们将教您如何使用本机操作系统功能或数据恢复工具恢复丢失的数据。奇客数据恢复Mac版可帮助恢复已从 Mac Pro 计算机上…

npm救赎之道:探索--save与--save--dev的神秘力量!

目录 1. --save和--save-dev是什么&#xff1f;2. 区别与应用场景--save--save-dev 3. 生产环境与开发环境4. 实际应用示例--save--save-dev 5. 总结 在现代软件开发中&#xff0c;npm&#xff08;Node Package Manager&#xff09;扮演着不可或缺的角色&#xff0c;为开发者提…

Java八股文(JVM)

Java八股文のJVM JVM JVM 什么是Java虚拟机&#xff08;JVM&#xff09;&#xff1f; Java虚拟机是一个运行Java字节码的虚拟机。 它负责将Java程序翻译成机器代码并执行。 JVM的主要组成部分是什么&#xff1f; JVM包括以下组件&#xff1a; ● 类加载器&#xff08;ClassLoa…

HTTP状态 405 - 方法不允许

方法有问题。 用Post发的请求&#xff0c;然后用Put接收的。 大家也可以看看是不是有这种问题 <body><h1>HTTP状态 405 - 方法不允许</h1><hr class"line" /><p><b>类型</b> 状态报告</p><p><b>消息…

如何使用常用的苹果应用商店上架工具提高应用下载量

摘要 移动应用app上架是开发者关注的重要环节&#xff0c;但常常会面临审核不通过等问题。为帮助开发者顺利完成上架工作&#xff0c;各种辅助工具应运而生。本文探讨移动应用app上架原理、常见辅助工具功能及其作用&#xff0c;最终指出合理使用工具的重要性。 引言 移动应…

python(一)网络爬取

在爬取网页信息时&#xff0c;需要注意网页爬虫规范文件robots.txt eg:csdn的爬虫规范文件 csdn.net/robots.txt User-agent: 下面的Disallow规则适用于所有爬虫&#xff08;即所有用户代理&#xff09;。星号*是一个通配符&#xff0c;表示“所有”。 Disallow&…

Groovy结合Java在生产中的落地实战

Groovy简介 Groovy是用于Java虚拟机的一种敏捷的动态语言&#xff0c;是一种成熟的面向对象编程语言&#xff0c;又是一种纯粹的脚本语言。Groovy运行在JVM环境上&#xff0c;在语法上兼具java 语言和脚本语言特点&#xff0c;大大简化了语法。同时又具有闭包和动态语言中的其…

系统分析师-软件开发模型总结

前言 软件工程模型也称软件开发模型。它是指软件开发全部过程、活动和任务的结构框架&#xff0c;通过该模型能清晰、直观地表达软件开发全过程&#xff0c;明确地规定要完成的主要活动和任务&#xff0c;它奠定了软件项目工作的基础 一、瀑布模型&#xff08;Waterfall Model…