量化交易入门(三十八)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.hqwc.cn/news/585865.html

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

相关文章

Qt元对象系统

第二章Qt元对象系统 文章目录 第二章Qt元对象系统1.什么是元对象&#xff1f;2.元对象系统组成3.信号与槽信号和槽的本质绑定信号与槽自定义槽定义槽函数必须遵循一下规则槽函数的类型自定义槽案例 自定义信号自定义信号需要遵循以下规则信号和槽重载二义性问题 4.内存管理1. 简…

C++ | Leetcode C++题解之第6题Z字形变换

题目&#xff1a; 题解&#xff1a; class Solution { public:string convert(string s, int numRows) {int n s.length(), r numRows;if (r 1 || r > n) {return s;}string ans;int t r * 2 - 2;for (int i 0; i < r; i) { // 枚举矩阵的行for (int j 0; j i &l…

GDC回顾与MAU前瞻丨Flat Ads开启开发者流量变现新篇章

3月18日-22日,全球游戏行业最具规模、最有影响力的盛会——GDC 2024 在美国旧金山 Moscone Convention Center 成功举办,Flat Ads作为参展商亮相GDC大会,向全球游戏开发者展示我们的最新技术与服务。此次Flat Ads团队不仅洞察了行业最前沿的技术和发展趋势,同时也与诸多一线开发…

GWO-CNN-BiLSTM多输入回归预测|灰狼群算法优化的卷积-双向长短期神经网络|Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&…

电梯四种事故检测YOLOV8

电梯四种事故检测&#xff0c;采用YOLOV8训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV调用&#xff0c;支持C/PYTHON/ANDORID开发 电梯四种事故检测YOLOV8

海康威视(老版本)录像机+(新版本)摄像头 不兼容的解决方案

一、适用场景 1、海康威视的硬盘录像机使用多年&#xff0c;增加新版本的摄像头&#xff0c;原投资沿用&#xff1b; 2、监控网络第一期工程与第二期工程相隔的时间长&#xff0c;摄像头更新换代快&#xff1b; 3、企业或单位自己动手建监控网络&#xff1b; 4、上级主管部门要…

高性能威廉希尔产品特点低代码开发平台

高性能低代码是唯一一种使您能够构建复杂的、战略性的、任务关键型的消费者和内部软件的低代码类别。 它在提供端到端应用程序开发和更新方面没有限制&#xff0c;没有额外的许可&#xff0c;没有可扩展性问题&#xff0c;也没有更新的数据“重做”&#xff0c;当你从部门应用程…

vue3源码解析——ref和reactive定义响应式的区别

ref 和 reactive 是 Vue 3.0 中用于定义响应式数据的两个新 API。它们有以下区别&#xff1a; ref 定义单个响应式数据 数据类型可以是任意类型。它通常用于定义原始数据类型为响应式数据。返回一个响应式对象&#xff0c;该对象包含一个 .value 属性&#xff0c;可用于获取和设…

Python学习从0到1 day20 第二阶段 面向对象 ② 封装

缘分 朝生暮死犹如露水 —— 24.4.1 学习目标&#xff1a; 1.理解封装的概念 2.掌握私有成员的使用 一、面向对象三大特性&#xff1a; 面向对象编程&#xff0c;是许多编程语言都支持的一种编程思想 简单理解是&#xff1a;基于模板&#xff08;类&#xff09;去创建实体&…

leetcode刷题-字符串

目录 1、Reverse String 反转字符串 2、Reverse String II 反转字符串II 3、Reverse Words in a String 翻转字符串里的单词 4、Find the Index of the FirstOccurrence in a String 实现 strStr() KMP算法 next数组如何建立 模式串和字符串匹配 5、Repeated Substring…

数据结构与算法实验6——队的应用

一、实验目的 队列的应用&#xff0c;结合应用实例&#xff0c;深入理解和掌握队列。 二、实验软硬件要求 1、VC 6.0 三、实验预习 队列基本操作 四、实验内容&#xff08;实验步骤、测试数据等&#xff09; 1、队列基本操作。请选择循环队列结构或链式队列结构实现队列…

nginx | nginx反向代理/负载均衡/缓存

文章目录 一、Nginx 反向代理1.1 nginx 文件结构1.2 默认的nginx配置文件1.3 实践中的 nginx.conf 二、Nginx 负载均衡2.1 热备负载均衡2.2 轮询负责均衡2.3 加权轮询负载规则2.4 ip_hash 负载均衡2.5 对特定资源实现负载均衡2.6 对不同域名实现负载均衡2.7 实现带有URL重写的负…