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()
代码的详细分析
-
导入必要的库:backtrader和yfinance。
-
定义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. 绘制回测结果图表。
该代码的主要功能
-
使用RSI指标生成买卖信号,当RSI低于超卖阈值时买入,高于超买阈值时卖出。
-
在买入时,根据可用资金计算买入数量,以最大化利用资金。
-
在订单执行时,打印详细的交易信息,包括买入/卖出日期、价格、成本、佣金等。
-
使用Backtrader的内置分析器计算并打印回测指标,如年化收益率、夏普比率和最大回撤等。
-
绘制回测结果图表,直观展示策略的表现。
运行的结果怎么样呢?
执行结果:
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策略的表现进行以下分析:
-
最终投资组合价值为114408.26美元,高于初始投资的100000美元,表明该策略取得了正收益。
-
年化收益率为3.43%,这个收益率相对较低,可能是因为苹果股价在回测期内上涨幅度有限所致。
-
夏普比率为0.28,较低,表明该策略的收益率相对于承受的风险来说不太理想。一般认为,夏普比率大于1才算是好的投资策略。
-
最大回撤为19.71%,持续时间达208个交易日,这说明在某些阶段该策略遭受了较大的资金损失,抗风险能力不太理想。
总的来说,这个基于RSI的简单交易策略,虽然最终取得了正收益,但收益率水平一般,风险较高。其主要问题在于:
-
单纯依赖RSI指标进行交易决策,缺乏其他辅助指标判断,难以完全捕捉市场时机。
-
缺乏风险控制和止损机制,在遇到剧烈行情时容易遭受重大损失。
-
没有针对不同市场状况进行策略调整和优化。
因此,为了提高该策略的效果,我们可以考虑:
-
增加其他技术指标和基本面分析,综合多种因素做出交易决策。
-
设置合理的止损和止盈位,控制单笔交易风险。
-
根据市场波动率、趋势等情况动态调整策略参数。
-
尝试对不同的时间周期、股票品种进行优化和测试。
-
研究先进的机器学习算法,探索更高级的量化策略。