量化交易入门(三十八)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 系统展示 系统功能设计图 首页 后台管理登录页面 采购查询管理 采购员登录…

linux正则表达式之[]

1.[]含义 linux正则表达式[]表示字符集合的重复特殊字符的符号。 2.样例 正则表达式[]样例 命令1&#xff1a; grep -n "p[wldn]" anaconda-ks.cfg #需要特别注意的是&#xff0c;在[ ]中“仅代表一个待搜索的字符”。命令1的意思是搜索含有(pw)或(pl)或(pd)或…

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

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

数据库设计-MySQL设计小册

前言 最近回顾了下MySQL相关的知识&#xff0c;比如索引、几大日志、事务、MVCC、SQL执行流程、Buffer Pool等等。理论知识看了一大堆&#xff0c;自然还是需要实践的&#xff0c;第一个反应就是数据库设计规范。项目开发中&#xff0c;数据库设计自然是重要的一环&#xff0c…

dotcpp题目 1020: [编程入门]猴子吃桃的问题

一、题目 题目描述 猴子吃桃问题。猴子第一天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不过瘾&#xff0c;又多吃了一个。 第二天早上又将剩下的桃子吃掉一半&#xff0c;又多吃一个。以后每天早上都吃了前一天剩下的一半零一个。 到第N天早上想再吃时&#xff0c…

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

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

ARM IHI0069F GIC architecture specification (6)

2.3 亲和路由 亲和路由是一种基于分层地址的方案&#xff0c;用于识别中断路由的特定PE节点。 对于 PE&#xff0c;AArch64 状态的亲和性值在 MPIDR_EL1 中定义&#xff0c;AArch32 状态的亲和性值在 MPIDR 中定义&#xff1a; • 关联路由是一个由四个8 位关联字段组成的32 位…

问题解决:gorm查询oracle库表,返回struct字段数据为空的问题

package model// 表对应的struct // github.com/cengsin/oracle v1.0.0 // gorm.io/gorm v1.21.16 // 注意&#xff1a;column:USERNAME字段必须大写&#xff08;oracle表中字段名大写&#xff09;&#xff0c;否则查询出的struct字段值会为空 type BBUser struct {Username …

开源简单方便功能强大的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…

Mongodb字段更新操作符$currentDate

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第54篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。 本文基于Mongodb的官方文档&#xff0c;整理了Mongodb字段更新操作符$currentDate的定义&#xff…

[数据结构]动态顺序表制作源码分享

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存 储。在数组上完成数据的增删查改。 顺序表一般可以分为&#xff1a; 1. 静态顺序表&#xff1a;使用定长数组存储元素 2. 动态顺序表&#xff1a;使用动态开辟的数组存储。…

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 如果您相…

websocket多级nginx代理

在使用多层Nginx代理时&#xff0c;WebSocket的连接可能会遇到一些问题&#xff0c;因为WebSocket连接是持久化的&#xff0c;它需要Upgrade头部来确认升级到WebSocket协议。在多层代理的情况下&#xff0c;每层代理可能会修改或丢失这个Upgrade头部信息。 为了确保WebSocket能…

深度学习训练过程中,常见的关键参数和概念讲解

深度学习训练过程中的关键参数和概念对于构建、理解和优化模型至关重要。以下是一些最常见的参数和概念&#xff0c;以及它们的简要解释&#xff1a; 1. 学习率&#xff08;Learning Rate&#xff09; 学习率是优化算法中最重要的参数之一&#xff0c;它控制着权重调整的幅度…

如何借助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服…

项目导出为jar遇到java.io.IOException: Problem reading font data

Maven项目导出为jar后运行测试&#xff0c;发现本地IDE可以运行的项目使用jar无法运行&#xff0c;出现 java.io.IOException: Problem reading font data网上搜索发现问题大都由于找不到对应的资源&#xff0c;经过最终调试问题解决&#xff0c;附代码&#xff1a; 【修改前…