![]()
01
多品种 RSI 量化回测系统
在量化投资的世界里,“回测”是连接交易灵感与实盘获利之间最重要的桥梁。很多初学者掌握了基础的 Python 语法,却苦于不知道如何将策略逻辑转化为可视化的回测报告。
今天,我们将通过三份依次进阶的代码示例,详细拆解如何使用 Python 最流行的回测框架 Backtrader,结合 Tushare 数据源,搭建一个支持多品种并行、自定义资金分析且拥有专业图表展示的量化系统。
在开始之前,我们需要认识一下支撑这个系统的“四驾马车”:
Backtrader: Python 界的量化回测“瑞士军刀”,功能强大且灵活。
Tushare: 免费且好用的金融数据接口,为策略提供“燃料”。
Pandas: 数据处理神器,用于清洗和准备行情数据。
Matplotlib: 绘图库,负责将枯燥的数据转化为直观的资金曲线。
策略逻辑:反直觉的 RSI 动量策略
通常教科书上的 RSI(相对强弱指标)用法是“高抛低吸”(>70 卖出,<30 买入)。但本代码采用了动量突破的逻辑:
买入信号:当 RSI > 70 且当前无持仓时,买入。
逻辑:认为市场进入强势上涨区间,追涨。
卖出信号:当 RSI < 30 且持有仓位时,卖出。
逻辑:认为市场趋势彻底反转,止损或止盈离场。
这个策略不再博取震荡收益,而是试图捕捉强劲的单边趋势。
代码拆解
1. 数据的准备与清洗
量化的第一步是获取高质量数据。代码中定义了三个主要指数:中证500、中证1000、创业板指。代码展示了如何处理多只股票/指数。Backtrader 允许同时加载多个数据源(Data Feeds),这对于测试投资组合策略至关重要。
cerebro.adddata(data_feed, name=name) # 加载到回测引擎2. 策略引擎的实现
这是整个系统的“大脑”。我们在 MultiAssetRSIStrategy 类中定义交易规则。
self.sell(data=data, size=100) zip(self.datas, self.rsi_indicators)的写法非常 Pythonic,优雅地实现了多品种的循环遍历,互不干扰。
3. 独家定制:资金分析器 (Analyzer)
Backtrader 自带的绘图虽然方便,但无法灵活定制。为了画出类似基金净值的曲线,代码中手写了一个 CashValueAnalyzer。
self.cash_values.append(current_value)4. 专业级可视化 (Visualization)
代码最精彩的部分在于最后的绘图优化。为了解决 Matplotlib 默认日期显示杂乱的问题,代码使用了专业的 Locator 和 Formatter。
图表优化细节:
中文字体支持:配置
SimHei等字体,彻底解决乱码。主/副刻度分离:
主刻度:显示年份(如 2015, 2016),不仅清晰而且不拥挤。
副刻度:显示季度/月份,提供细节参考。
ax.xaxis.set_minor_locator(MonthLocator(interval=3)) # 每季度一个副刻度运行效果展示,当你运行这段代码时,你将看到两部分输出: 1. 终端输出,清晰的资金变动情况:
![]()
2. 可视化图表
你会得到一张包含两部分的专业图表:
Backtrader 原生图:展示K线、买卖点信号(三角形图标)以及 RSI 指标的走势。
![]()
独立资金曲线图:这是一张蓝色的折线图,X轴的时间刻度非常整洁(例如只显示年份),你可以清晰地看到策略在 2015 年牛市是否抓住了机会,或者在 2018 年熊市是否控制住了回撤。
![]()
02
专业级 Python 量化系统:风控、复利与绩效评估
在上小节文章中,我们搭建了一个基础的多品种 RSI 策略框架。今天,我们将给这个引擎装上“涡轮增压”和“安全气囊”。
我们将解决新手最容易忽略的两个问题:“买多少?”(仓位管理)和“怎么输得少?”(风控指标)。我们将把这个“玩具级”的回测脚本升级为“实战入门级”的量化系统。
我们将重点进行以下 4项硬核升级:
仓位管理 (Position Sizing):从傻瓜式的“固定买100股”升级为“按资金比例下单”(例如每次使用20%资金),让复利效应发挥作用。
风险控制 (Risk Management):新增移动止损 (Trailing Stop) 逻辑。在趋势策略中,止损比止盈更重要,能保住胜利果实。
交易日志 (Logging System):增加详细的订单打印功能,让你清楚看到每一笔买卖的价格、费用和盈亏,拒绝“黑箱操作”。
专业绩效评估 (Performance Metrics):除了看最终资金,我们还要计算 夏普比率 (Sharpe Ratio) 和 最大回撤 (Max Drawdown),这才是专业机构评价策略的核心指标。
升级代码:
plt.show()1. 动态仓位管理 (Smart Sizing)
旧版本每次只买 100 股,这在资金量大时毫无意义。
代码:
cerebro.addsizer(bt.sizers.PercentSizer, percents=20)原理:无论你现在有 100 万还是 200 万,每次开仓都动用总资金的 20%。这能实现**“赢了加仓,输了减仓”**的复利效果。
不再是黑箱。我们在策略中增加了 notify_order 和 notify_trade 方法。
效果:终端会打印如下信息,这让你能精确核对每一笔交易是否符合预期,排查 Bug 必备。
RSI 策略最大的弱点是“钝化”(指标在高位一直不下来,或者暴跌时指标虽低但价格还在跌)。
逻辑:我们在
next方法中加入了一个简单的止损逻辑:if data.close[0] < stop_price。意义:假设买入后价格下跌超过 5%(
stop_loss_dist),强制平仓。这能防止单次交易造成毁灭性打击。
光看赚了多少钱是不够的,如果赚 50% 却经历过 40% 的回撤,那这个策略很难坚持。
夏普比率 (Sharpe Ratio):衡量性价比。大于 1 是良好,大于 2 是优秀。
最大回撤 (Max Drawdown):历史上最惨的一次跌幅。代码会在最后打印:
最大回撤: 15.30%,让你对风险心知肚明。
我们在绘图中增加了一个“盈亏区域填充”功能:
绿色背景区域:代表当前资金高于初始资金(赚钱)。
红色背景区域:代表当前资金低于初始资金(亏钱)。
这种视觉反馈能让你一眼看出策略在哪些年份表现挣扎,哪些年份在躺赚。
![]()
![]()
03
再次升级:添加趋势过滤与基准对比系统
在上一版本中,我们加入了仓位管理和止损。但在实战中,单纯的 RSI 动量策略有一个致命弱点:在长期熊市中,RSI 也会偶尔突破 70,诱骗你进场,然后价格继续暴跌。
这一次,我们将把系统升级为“基金经理级”。我们将引入两个量化交易中的核心概念:
趋势过滤 (Trend Filtering):解决 RSI 在熊市中频繁“假突破”导致亏损的痛点。
基准对比 (Benchmark Comparison):不跟大盘比收益的策略都是耍流氓。我们将把策略净值与“沪深300”的走势画在同一张图上,一目了然地看到你是否跑赢了市场。
SMA 趋势过滤:只有当价格位于 200 日均线之上(牛市区域)时,才允许开仓。这叫“顺大势,逆小势”。
基准对比可视化:自动下载沪深300数据,模拟“买入持有”策略,与你的策略净值同台竞技。
plt.show()深度解析升级内容
1. 增加系统过滤条件
新手死于追高,老手死于抄底,高手死于震荡。 RSI 策略最大的坑在于:在熊市反弹(Dead Cat Bounce)时,RSI 很容易突破 70,发出买入信号,然后市场继续暴跌。
代码逻辑:
if rsi > 70 and current_price > sma_filter白话解释:这就像是在说,“我只在天气晴朗(价格在200日均线之上)的时候,才去冲浪(RSI 突破)”。
效果:这会大幅减少交易次数,可能会让你错过一些机会,但能帮你躲过 2018 年或 2022 年那种持续阴跌的“绞肉机”行情。
很多策略号称“年化 20%”,结果一看那年大盘涨了 30%。这种策略是没有价值的,不如直接买指数 ETF。
实现方式:我们在绘图部分,引入了
hs300(沪深300) 数据,并将其初始资金也归一化为 100 万。可视化创新:
红色阴影区:表示你的策略跑赢了大盘。这是你作为量化交易员存在的意义。
灰色阴影区:表示策略跑输了大盘。这时候你需要反思策略逻辑。
代码中将资金分配逻辑调整为:
cerebro.addsizer(bt.sizers.PercentSizer, percents=45)因为我们有两个标的(创业板 + 中证500),如果设为 50%,当资金稍微有一点波动或产生佣金时,第二只股票可能因为资金不足(Cash < 50%)而无法买入。设为 45% 是一个安全的工程实践技巧。
运行结果
![]()
![]()
至此,我们的系统已经具备了 择时(RSI)、过滤(均线)、风控(止损)和 归因分析(Benchmark)等功能 。
最后的说明:
文中代码与条件设定均为示例载体,核心目标在于传递解决问题的方法论——建议聚焦于思路的理解与迁移,而非局限于示例结果本身。在掌握基础方法后,可结合自身思考对代码进行迭代优化,构建更健壮、高效的量化策略,真正实现从“理解”到构建策略”的进阶。
如您想获取文章完整代码,请关注数量技术宅公众号,后台回复关键词:组合测试
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.