当前位置:首页>python>用 Python 打造交易策略:3 个指标实现自动化交易回测

用 Python 打造交易策略:3 个指标实现自动化交易回测

  • 2026-08-22 08:49:38
用 Python 打造交易策略:3 个指标实现自动化交易回测

2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含300篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!

引言

"现在是买入还是卖出的好时机?"——这是每个交易者每天都会面对的灵魂拷问。

主观交易最大的敌人不是市场,而是情绪。恐惧和贪婪会让我们在该买的时候犹豫,在该卖的时候死扛。为了克服这一问题,越来越多的交易者转向系统化策略——用一套客观的规则来决定买卖时机,让代码替你执行纪律。

本文将带你从零开始,用 Python 构建一个基于 3 个经典技术指标的交易策略,并通过回测验证它在历史数据上的表现。即使你不做交易,这也是一个绝佳的 Python 数据分析实战项目。

注意:本文中的策略仅作为学习用途,用于演示如何创建和测试交易策略,不建议直接用于实盘交易。

一、策略架构:三大指标各司其职

一个好的量化策略通常会组合多个不相关的指标,从不同维度过滤市场噪音。本文的策略选用了以下三个指标,分别覆盖趋势、动量、波动率三个维度。

1. 趋势识别:简单移动平均线(SMA)

SMA 通过平滑价格数据来判断资产的运动方向。

  • • 参数设定:使用 50 日(快线)和 200 日(慢线)双均线。
  • • 核心逻辑:当 50 日均线上穿 200 日均线时,形成"金叉"(Golden Cross),意味着长期趋势转为看涨。

2. 动量过滤:相对强弱指标(RSI)

RSI 衡量价格变动的速度和幅度,数值在 0 到 100 之间波动。

  • • 核心逻辑:当 RSI 超过 70 时,市场可能已经过热。我们要求在买入时 RSI 低于 70,确保上涨还有"跑动空间"。

3. 波动率评估:平均真实波幅(ATR)

ATR 通过衡量一段时间内价格波动的范围来量化市场波动率。

  • • 核心逻辑:ATR 用于计算动态止损位。波动率越高,止损范围应越宽,避免被正常的价格"抖动"误触出局。

二、交易规则

买入条件:50 日 SMA 上穿 200 日 SMA(金叉出现),且 RSI 低于 70。

卖出条件:50 日 SMA 下穿 200 日 SMA(死叉出现),或 RSI 超过 85(极端超买)。

三、Python 实战:从安装到回测

第 1 步:安装依赖库

pip install yfinance pandas pandas_ta backtesting

这里用到了 4 个核心库:

  • • yfinance:从 Yahoo Finance 获取历史行情数据
  • • pandas:数据处理
  • • pandas_ta:计算技术指标
  • • backtesting:策略回测框架

第 2 步:编写策略代码

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。

第 3 步:加载数据并运行回测

# 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. 风险调整收益(Sharpe Ratio)

夏普比率衡量的是每承受一单位风险所获得的超额收益。数值越高,说明策略的收益效率越好。一般来说,夏普比率大于 1 就算不错,大于 2 则属于优秀。

2. 最大回撤(Maximum Drawdown)

最大回撤是账户从峰值到谷底的最大跌幅。这是衡量资金风险最直观的指标。例如,回测报告中最大回撤为 -15.65%,意味着在最糟糕的时期,账户曾从最高点下跌约 15.65%。

3. 胜率与盈亏比(Win Rate vs. Risk/Reward)

胜率是盈利交易占总交易次数的比例。但光看胜率不够,还需要结合平均盈利和平均亏损的比例来判断策略的可持续性。一个胜率 40% 但盈亏比 3:1 的策略,可能比胜率 70% 但盈亏比 1:1 的策略更赚钱。

五、回测的局限性

回测只是对历史的模拟,距离实盘交易还有不小的距离。以下是几个需要注意的陷阱:

1. 滑点与流动性

在真实市场中,订单不一定能在信号价格成交,尤其是在高波动或低成交量的股票上。回测通常假设以收盘价完美成交,这在实盘中几乎不可能。

2. 过拟合(曲线拟合)

反复调参让策略完美匹配历史数据,往往只是"记住了过去",而非发现了可重复的规律。这样的策略上线后大概率会失效。

3. 幸存者偏差

如果只对当前仍然上市的明星股票做回测,就忽略了那些已经退市的失败公司,从而人为地美化了回测结果。

六、完整代码

以下是可以直接运行的完整代码:

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 库在历史数据上进行回测验证。

核心要点回顾:

  1. 1. 策略设计:组合趋势(SMA)、动量(RSI)、波动率(ATR)三个维度的指标,让它们各司其职,互相配合。
  2. 2. 回测验证:通过历史数据模拟交易,获取夏普比率、最大回撤、胜率等关键指标,用数据而非直觉来评估策略好坏。
  3. 3. 保持清醒:回测表现好不代表实盘就能赚钱。滑点、过拟合、幸存者偏差等问题都需要认真对待。

量化交易的目标不是保证盈利,而是让你从"凭感觉猜"变成"基于数据和概率做决策"。希望本文能帮助你迈出量化交易学习的第一步。

参考文章

加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取本文完整研究解析、代码实现细节。

财经数据与量化投研知识社区

2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:

  1. 1. 双典系统赋能:获赠《财经数据宝典》与《量化投研宝典》完整文档,凝练多年实战经验,构建系统化知识框架;
  2. 2. 量化因子日更教程(2026重磅新增):每日更新「量化因子专题教程」,配套完整可运行代码与实战案例,深度拆解因子构建、回测与优化全流程;
  3. 3. 量化文章专题教程库:300+篇星球独有高质量教程式文章,系统覆盖策略开发、因子研究、风险管理等核心领域,内容基本每日更新,并配套精选学习资料与实战参考;
  4. 4. PyBroker实战课程:赠送《PyBroker-入门及实战》视频课程,手把手教学,快速掌握量化策略开发技能;
  5. 5. 财经数据支持:定期更新国内外财经数据,为策略研发提供精准、可靠的数据基础;
  6. 6. 顶尖学者与行业专家分享:年度邀请学术界博士与业界资深专家开展前沿论文精讲与实战案例分享,不少于4场,直击研究前沿与产业实践;
    专家直连答疑:与核心开发者及领域专家实时互动,高效解决投研实战难题;
  7. 7. 专业社群与专属福利:加入高质量交流社群,获取课程折扣及更多独家资源。

星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!

好文推荐

1. 用 Python 打造股票预测系统:Transformer 模型教程(一)

2. 用 Python 打造股票预测系统:Transformer 模型教程(二)

3. 用 Python 打造股票预测系统:Transformer 模型教程(三)

4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)

5. 揭秘隐马尔可夫模型:因子投资的制胜武器

6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用

7. 金融 AI 助手:FinGPT 让你轻松掌握市场分析

8. 量化交易秘籍:为什么专业交易员都在用对数收益率?

9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解

10. 掌握金融波动率模型:完整 Python 实现指南

最新文章

随机文章