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

本文介绍了如何使用CCI指标编写量化交易策略,通过在特定条件下产生买入和卖出信号,结合Python库backtrader和yfinance进行苹果股票的回测。策略在回测中取得正收益,但年化回报率低,风险较高,需进一步优化.
摘要由CSDN通过智能技术生成

今天我们先单纯用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 yf

class 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]:
            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(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,意味着最大回撤发生在一个相对较长的时间框架内,这可能表明策略在这段时间内遇到了持续的不利市场条件。

结论

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

  • 14
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder加油!

感谢您的认可和支持!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值