
2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含300篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!
"现在是买入还是卖出的好时机?"——这是每个交易者每天都会面对的灵魂拷问。
主观交易最大的敌人不是市场,而是情绪。恐惧和贪婪会让我们在该买的时候犹豫,在该卖的时候死扛。为了克服这一问题,越来越多的交易者转向系统化策略——用一套客观的规则来决定买卖时机,让代码替你执行纪律。
本文将带你从零开始,用 Python 构建一个基于 3 个经典技术指标的交易策略,并通过回测验证它在历史数据上的表现。即使你不做交易,这也是一个绝佳的 Python 数据分析实战项目。
注意:本文中的策略仅作为学习用途,用于演示如何创建和测试交易策略,不建议直接用于实盘交易。
一个好的量化策略通常会组合多个不相关的指标,从不同维度过滤市场噪音。本文的策略选用了以下三个指标,分别覆盖趋势、动量、波动率三个维度。
SMA 通过平滑价格数据来判断资产的运动方向。
RSI 衡量价格变动的速度和幅度,数值在 0 到 100 之间波动。
ATR 通过衡量一段时间内价格波动的范围来量化市场波动率。
买入条件:50 日 SMA 上穿 200 日 SMA(金叉出现),且 RSI 低于 70。
卖出条件:50 日 SMA 下穿 200 日 SMA(死叉出现),或 RSI 超过 85(极端超买)。
pip install yfinance pandas pandas_ta backtesting这里用到了 4 个核心库:
import yfinance as yf
import pandas_ta as ta
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
class IndicatorStrategy(Strategy):
# 定义策略参数
sma_fast = 50 # 快速均线周期
sma_slow = 200 # 慢速均线周期
rsi_window = 14 # RSI 计算周期
def init(self):
# 使用 pandas_ta 预计算各项指标
close = self.data.Close
# 计算 50 日简单移动平均线
self.sma1 = self.I(ta.sma, close, self.sma_fast)
# 计算 200 日简单移动平均线
self.sma2 = self.I(ta.sma, close, self.sma_slow)
# 计算 14 日 RSI 指标
self.rsi = self.I(ta.rsi, close, self.rsi_window)
def next(self):
# 买入逻辑:金叉出现且 RSI 未超买
if crossover(self.sma1, self.sma2) and self.rsi < 70:
self.buy()
# 卖出逻辑:死叉出现或 RSI 极端超买
elif crossover(self.sma2, self.sma1) or self.rsi > 85:
self.position.close()代码解读:
init() 方法在回测开始前执行,用于预计算所有技术指标。next() 方法在每根 K 线上被调用,根据当前指标值判断是否买入或卖出。crossover(a, b) 函数检测序列 a 是否刚刚上穿序列 b。# 1. 下载苹果公司(AAPL)2020-2025 年的历史数据
df = yf.download("AAPL", start="2020-01-01", end="2025-01-01")
# 2. 创建回测实例,初始资金 10000 美元,手续费 0.2%
bt = Backtest(df, IndicatorStrategy, cash=10000, commission=.002)
# 3. 运行回测
stats = bt.run()
# 4. 输出回测结果
print(stats)运行代码后,你会看到一份详细的回测报告。以下是几个关键指标的含义:
夏普比率衡量的是每承受一单位风险所获得的超额收益。数值越高,说明策略的收益效率越好。一般来说,夏普比率大于 1 就算不错,大于 2 则属于优秀。
最大回撤是账户从峰值到谷底的最大跌幅。这是衡量资金风险最直观的指标。例如,回测报告中最大回撤为 -15.65%,意味着在最糟糕的时期,账户曾从最高点下跌约 15.65%。
胜率是盈利交易占总交易次数的比例。但光看胜率不够,还需要结合平均盈利和平均亏损的比例来判断策略的可持续性。一个胜率 40% 但盈亏比 3:1 的策略,可能比胜率 70% 但盈亏比 1:1 的策略更赚钱。
回测只是对历史的模拟,距离实盘交易还有不小的距离。以下是几个需要注意的陷阱:
在真实市场中,订单不一定能在信号价格成交,尤其是在高波动或低成交量的股票上。回测通常假设以收盘价完美成交,这在实盘中几乎不可能。
反复调参让策略完美匹配历史数据,往往只是"记住了过去",而非发现了可重复的规律。这样的策略上线后大概率会失效。
如果只对当前仍然上市的明星股票做回测,就忽略了那些已经退市的失败公司,从而人为地美化了回测结果。
以下是可以直接运行的完整代码:
import yfinance as yf
import pandas_ta as ta
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
class IndicatorStrategy(Strategy):
"""
基于 SMA 金叉/死叉 + RSI 过滤的交易策略
"""
sma_fast = 50 # 快速均线周期
sma_slow = 200 # 慢速均线周期
rsi_window = 14 # RSI 计算周期
def init(self):
"""初始化:预计算技术指标"""
close = self.data.Close
# 计算快速和慢速简单移动平均线
self.sma1 = self.I(ta.sma, close, self.sma_fast)
self.sma2 = self.I(ta.sma, close, self.sma_slow)
# 计算 RSI 指标
self.rsi = self.I(ta.rsi, close, self.rsi_window)
def next(self):
"""逐根 K 线执行交易逻辑"""
# 买入条件:50 日均线上穿 200 日均线(金叉),且 RSI < 70
if crossover(self.sma1, self.sma2) and self.rsi < 70:
self.buy()
# 卖出条件:200 日均线上穿 50 日均线(死叉),或 RSI > 85
elif crossover(self.sma2, self.sma1) or self.rsi > 85:
self.position.close()
# ===== 主程序 =====
# 1. 下载苹果公司 5 年历史数据
df = yf.download("AAPL", start="2020-01-01", end="2025-01-01")
# 2. 初始化回测引擎(初始资金 10000 美元,手续费 0.2%)
bt = Backtest(df, IndicatorStrategy, cash=10000, commission=.002)
# 3. 运行回测并打印结果
stats = bt.run()
print(stats)
# 4.(可选)绘制回测图表
bt.plot()本文通过一个完整的 Python 案例,演示了如何构建一个基于 SMA、RSI 和 ATR 三个技术指标的量化交易策略,并使用 backtesting 库在历史数据上进行回测验证。
核心要点回顾:
量化交易的目标不是保证盈利,而是让你从"凭感觉猜"变成"基于数据和概率做决策"。希望本文能帮助你迈出量化交易学习的第一步。
加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取本文完整研究解析、代码实现细节。
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用