量化交易入门(三十八)CCI指标Python实现和回测

今天我们先单纯用CCI指标来完成策略的编写,后续我们会改进这个策略,将CCI指标和前面讲到的MACD和RSI相结合来优化,看看我们优化后的效果会不会更好。

一、量化策略

CCI指标在量化交易中的策略:

在以下情况下生成买入信号:

  • 当 CCI 指标的值低于下限(self.params.lower)并且在上一根K线上低于下限时,生成买入信号。

在以下情况下生成卖出信号:

  • 当 CCI 指标的值高于上限(self.params.upper)并且在上一根K线上高于上限时,生成卖出信号。

策略的目的是在 CCI 指标的值低于下限时买入,以获得较低的价格,并在 CCI 指标的值高于上限时卖出,以获得较高的价格,从而实现利润。

二、代码实现

 我们基于CCI指标使用苹果股票2020年1月1日到2023年12月30日的历史数据进行回测。以下是完整的代码:

import backtrader as bt
import yfinance as yfclass CCIStrategy(bt.Strategy):params = (('period', 20),('upper', 100),('lower', -100),)def __init__(self):self.cci = bt.indicators.CCI(self.data, period=self.params.period)def next(self):if not self.position:if self.cci[-1] < self.params.lower and self.cci[0] >= self.params.lower:commission_info = self.broker.getcommissioninfo(self.data)cash = self.broker.get_cash()size = int(cash / (self.data.close[0] * (1 + commission_info.p.commission)))self.order = self.buy(size=size)print(f'BUY: {size} shares')else:if self.cci[-1] > self.params.upper and self.cci[0] <= self.params.upper:self.order = self.close()print(f'SELL: {self.position.size} shares')def notify_order(self, order):if order.status in [order.Submitted, order.Accepted]:returnif 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.valueprofit = order.executed.value - order.created.size * order.created.priceprofit_percent = (profit / cost) * 100print(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(CCIStrategy)# 设置佣金为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()

三、代码解析

这段代码是一个使用 backtrader 库进行交易策略回测的 Python 脚本,并使用 yfinance 库获取历史金融数据。它具体实现了基于商品渠道指数(CCI)指标的交易策略。让我们来逐部分解析这些代码:

引入库

import backtrader as bt
import yfinance as yf
  • backtrader: 一个用于回测交易算法的 Python 库。
  • yfinance: 用于从 Yahoo 财经下载金融数据。

定义策略:CCIStrategy

这个类继承自 bt.Strategy,并使用 CCI 指标定义交易策略。

  • params: 一个元组,定义策略参数 - CCI 周期,以及上下阈值。
  • __init__: 初始化方法,在这里使用价格数据和指定的周期实例化 CCI 指标。
  • next: 对于每个新的数据点,都会调用此方法。它包含了基于CCI值穿越定义阈值执行买入和卖出订单的逻辑。

交易逻辑

  • 买入条件:如果没有开仓,并且CCI值从低于下阈值穿越到上面,则下达买入订单。
  • 卖出条件:如果有开仓,并且CCI值从高于上阈值穿越到下面,则平仓(卖出订单)。

订单通知

  • notify_order: 处理有关订单的通知(例如,当订单被提交、接受、完成或拒绝时)。它会打印有关执行订单的详细信息,包括执行价格、成本、佣金和利润。

设置并运行回测

  • 创建一个 Cerebro 引擎实例,并设置初始资本。
  • 使用 yfinance 获取苹果公司(AAPL)从2020年1月1日到2023年12月30日的历史数据,并添加到 Cerebro 引擎中。
  • 将 CCIStrategy 添加到 Cerebro 中进行回测。
  • 设置交易佣金为0.1%。
  • 添加分析器,用于评估策略性能,包括回报率、夏普比率和最大回撤。
  • 运行回测,并打印最终的投资组合价值以及性能指标(年化回报率、夏普比率和最大回撤)。

绘制结果

最后,调用 cerebro.plot() 来视觉上审查交易策略在回测期间的表现。

这段脚本提供了一个结构化方法来评估基于 CCI 指标的交易策略,包括交易的实际方面,如佣金和订单执行逻辑。

四、策略运行结果及解读

执行的结果:
Starting Portfolio Value: 100000.00 
Final Portfolio Value: 110402.49
Annualized Return: 2.51%
Sharpe Ratio: 0.18
Max Drawdown: 22.65%
Max Drawdown Period: 441

哈哈,这个结果免强还行,最终结果没有亏钱,让我们逐项分析这些结果:

初始和最终投资组合价值

  • 初始投资组合价值: 100,000.00
  • 最终投资组合价值: 110,402.49

这意味着在回测期间,投资组合价值从 100,000 增加到了 110,402.49,实现了约 10.4% 的增长。这表明策略在整个回测期间是盈利的。

年化回报率

  • 年化回报率: 2.51%

年化回报率是将投资收益率调整为一年期的标准度量,便于与其他投资或策略进行比较。2.51% 的年化回报率意味着,如果以相同的市场条件和策略表现,投资者可以期待每年获得约 2.51% 的回报。

夏普比率

  • 夏普比率: 0.18

夏普比率是衡量风险调整后回报的指标,计算为超过无风险回报率的投资回报与投资的标准差(风险)之比。夏普比率越高,表示每承受一单位风险,能获得更多的超额回报。0.18 的夏普比率较低,表明策略产生的每单位风险调整后回报较少,或者说策略的风险相对于回报来说较高。

最大回撤

  • 最大回撤: 22.65%
  • 最大回撤期间: 441

最大回撤是指投资组合在选定的时期内从峰值跌到谷底的最大跌幅,是衡量投资风险的一项重要指标。22.65% 的最大回撤意味着在最糟糕的情况下,投资组合的价值可能会从峰值暂时性下降约 22.65%。这是一个相对较大的回撤,表明策略在回测期间承受了较高的风险。

最大回撤期间 441,意味着最大回撤发生在一个相对较长的时间框架内,这可能表明策略在这段时间内遇到了持续的不利市场条件。

结论

这个策略在回测期间实现了正收益,但年化回报率较低,且承担了较高的最大回撤风险。夏普比率也表明该策略的风险调整后回报不是特别高。因此,尽管策略是盈利的,投资者应该谨慎考虑与其他策略相比较时的风险与收益。

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

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

相关文章

预处理指令——一些比较少见的概念

前言&#xff1a;预处理是我们的c语言源代码成为可执行程序的第一个步骤。而宏和预处理指令都是在这个阶段完成。本节内容就是关于宏和预处理指令相关知识点的解析。 目录 宏 预定义符号 #define定义常量 #define定义符号 #define定义宏 带副作用的宏参数 宏的替换规则…

基于SSM的“超市管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“超市管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能设计图 首页 后台管理登录页面 采购查询管理 采购员登录…

配置 施耐德 modbusTCP 分布式IO子站 RPA0100

1. 总体步骤 2. 软件组态&#xff1a;在 Unity Pro 软件中创建编辑 PRA 模块工程 2.1 新建项目 模块箱硬件型号如下 点击 Unity Pro 软件左上方【新建】按钮&#xff0c;选择正确的 DIO 模块型号、背板型号 2.2 模块组态 2.2.1 拖拽添加模块 双击【配置】菜单下的【0&…

关于loop( ) 阻塞和非阻塞探究

一、SIR的补充 在上几篇博客中&#xff0c;有朋友私信问我&#xff0c;在ticker函数程序和中断服务程序&#xff08;ISR&#xff09;中写 物联网请求报错。怎么回事&#xff0c;在此解释。控制台如下 1.1解释 在使用 Ticker 函数和中断服务程序&#xff08;ISR&#xff09;时…

开源简单方便功能强大的Devops工具:Goploy

Goploy&#xff1a;加速您的DevOps旅程&#xff0c;拥抱无缝部署——选择Goploy&#xff0c;让您从繁琐的发布与回滚中解放出来&#xff0c;尽享高效、智能与便捷的自动化部署力量&#xff01; - 精选真开源&#xff0c;释放新价值。 概览 现在大部分流行的发布工具功能虽然强…

Leetcode-2810-故障键盘-c++

题目详见https://leetcode.cn/problems/faulty-keyboard/ 题解 这道题的关键是如何合理地使用STL&#xff0c;毕竟是一道简单题。 之前常用到的Vector容器是单向开口的连续内存空间 deque则是一种双向开口的连续线性空间&#xff0c;又称双端动态数组。所谓的双向开口&#x…

bugku-web-速度要快

发现phpsessid 从上述提示 提示发送post请求&#xff0c;并且带有参数margin 发送后发现报文头部有一个字段叫flag&#xff0c;但好像每一次flag都不一样 构建Python脚本 request requests.Session()data {margin:find, } for i in range(50):html request.post(urlhttp:/…

2024年04月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2024年04月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…

如何借助Idea创建多模块的SpringBoot项目

目录 1.1、前言1.2、开发环境1.3、项目多模块结构1.4、新建父工程1.5、创建子模块1.6、编辑父工程的pom.xml文件 1.1、前言 springmvc项目&#xff0c;一般会把项目分成多个包:controler、service、dao、utl等&#xff0c;但是随着项目的复杂性提高&#xff0c;想复用其他一个模…

mkcert生成ssl证书+nginx部署局域网内的https服务访问问题

文章目录 mkcert生成ssl证书nginx部署局域网内的https服务访问问题1、下载mkcert查看自己的电脑是arm还是amd架构 2、安装mkcert3、测试mkcert是否安装成功4、查看CA证书存放位置5、打开windows的证书控制台6、生成自签证书,可供局域网内使用其他主机访问以下是nginx部署https服…

idea Springboot 电影推荐系统LayUI框架开发协同过滤算法web结构java编程计算机网页

一、源码特点 springboot 电影推荐系统是一套完善的完整信息系统&#xff0c;结合mvc框架和LayUI框架完成本系统springboot dao bean 采用协同过滤算法进行推荐 &#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&…

书生·浦语大模型-第二节课笔记/作业

笔记 实验一 cli-demo import torch from transformers import AutoTokenizer, AutoModelForCausalLMmodel_name_or_path "../models"tokenizer AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_codeTrue, device_mapcuda:0) model AutoModelF…

【Cadence Allegro】如何差分对走线

一、创建espice模型 shift+F2或者“Analyze-Model Assigment”创建espice模型,这个操作是为了让差分线路里的串接电阻(或电感电容)变为xnet类型方便准确等长走线。 Cadence Allegro Xnet的创建详细教程 - 知乎Cadence Allegro Xnet的创建详细教程Xnet是指在无源器件的两端,…

【Go】十四、封装、继承

文章目录 1、封装2、继承3、继承的注意点 1、封装 隐藏实现细节保证数据安全&#xff08;控制变量或方法的访问范围&#xff0c;private&#xff09; Go中实现封装&#xff1a; 结构体、字段的首字母小写&#xff08;Java的private&#xff09;提供一个工厂模式函数&#xf…

微服务管理(完整)

前言&#xff1a; 分享一篇学微服务管理的过程 一&#xff0c;etcd入门 1&#xff0c;简介 1.1&#xff0c;etcd是什么 etcd是CoreOS团队于2013年6月发起的开源项目&#xff0c;它的目标是构建一个高可用的分布式键值(key-value)数据库。 官网上的一段描述&#xff1a; A…

Tomcat调优总结(Tomcat自身优化、Linux内核优化、JVM优化)

Tomcat自身的调优是针对conf/server.xml中的几个参数的调优设置。首先是对这几个参数的含义要有深刻而清楚的理解。以tomcat8.5为例&#xff0c;讲解参数。 同时也得认识到一点&#xff0c;tomcat调优也受制于linux内核。linux内核对tcp连接也有几个参数可以调优。 因此我们可…

java数据结构与算法刷题-----LeetCode695. 岛屿的最大面积

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 深度优先遍历2. 广度优先 1. 深度优先遍历 这不是找最短路径&…

蓝桥杯刷题第七天

这道题一开始看真的有点简单&#xff0c;但一开始跟着案例先入为主了&#xff0c;误以为是只有两个项目想着穷举完n个人&#xff0c;&#xff08;n1&#xff09;*&#xff08;n2&#xff09;/2种情况但后面发现项目不止两个&#xff0c;用链表来好像我也不会&#xff0c;用二维…

linux编辑器——vim使用方法

文章目录 linux编辑器——vim使用方法1. vim的基本概念2. vim的基本操作3. vim正常模式命令集4. vim末行模式命令集5. vim操作总结6.简单vim配置7.参考资料 linux编辑器——vim使用方法 vi/vim的区别简单点来说&#xff0c;它们都是多模式编辑器&#xff0c;不同的是vim是vi的…

泛域名站群,泛域名程序

泛域名站群是一种利用大量类似的泛域名来建立多个网站&#xff0c;并通过这些网站链接到主网站&#xff0c;以提升主网站的排名和流量的策略。泛域名站群通常包含大量的子域名&#xff0c;这些子域名指向不同的页面&#xff0c;但它们的内容大部分是重复或相似的&#xff0c;目…