🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

聚宽(JoinQuant)均线策略回测无交易、收益为0的常见原因及解决方案

joinquant | 发布时间: 2026/6/24
以下内容由 EasyQuant 生成。

问题描述

均线策略回测收益为0,求帮忙看一下问题所在。

刚开始学量化,模仿别人做均线策略的时候,用聚宽回测,但收益显示为0。是我的代码出现了什么问题吗?求大神帮助!

我的策略思路是当均线MA13-MA60的值大于MA60*偏离度时,就买入ETF。

但看了一下交易记录,也没有任何交易。苦恼中

解决方案

你好!在量化交易的起步阶段,遇到回测收益为0、没有任何交易记录是非常常见的现象。这通常意味着策略的买入条件在整个回测期间从未被触发,或者代码在获取数据/下单时存在逻辑漏洞

针对你的“MA13与MA60偏离度”策略,以下是几个最常见的排查点,并在文末为你提供了一份可以直接运行的完整源码。

🔍 常见原因排查清单

  1. 标的代码(ETF)后缀错误
    在聚宽中,标的代码必须带有市场后缀。例如,沪深300ETF的代码是 510300.XSHG(上交所),而不是单纯的 510300。如果代码写错,order 函数会静默失败或报错,导致无交易。
  2. 历史数据获取长度不足
    你要计算 MA60,就必须在 attribute_historyhistory 函数中,将获取的天数(count)设置为至少 60。如果只获取了 13 天的数据去求 MA60,计算出的均线是错误的,会导致逻辑判断失效。
  3. 偏离度阈值设置过高
    你的条件是 MA13 - MA60 > MA60 * 偏离度。如果你的偏离度设置成了 5(代表500%)而不是 0.05(代表5%),那么这个条件在现实中几乎永远不可能成立,自然就不会有任何买入操作。
  4. 没有处理卖出逻辑
    如果只写了买入条件,没有写卖出条件,或者卖出条件写错了,资金买完一次后就被占用,后续也不会再有交易记录(虽然这通常会有一笔买入,但如果连买入都没有,请重点检查前三点)。

💻 完整的 ETF 均线偏离度策略源码

为了帮你快速跑通策略,我为你编写了一份标准的、基于沪深300ETF(510300.XSHG)的均线偏离度策略代码。你可以直接复制到聚宽的策略编辑页面进行回测:

# 导入聚宽函数库
import jqdata

def initialize(context):
    # 1. 设定要交易的标的:沪深300ETF
    g.security = '510300.XSHG'
    
    # 2. 设定沪深300指数作为基准
    set_benchmark('000300.XSHG')
    
    # 3. 开启动态复权模式(真实价格),强烈建议开启
    set_option('use_real_price', True)
    
    # 4. 设定偏离度阈值,例如 0.02 表示 2%
    g.deviation_rate = 0.02
    
    # 5. 过滤掉order系列API产生的比info级别低的log,保持日志清爽
    log.set_level('order', 'info')

# 每个单位时间(按天回测则每天调用一次)调用一次
def handle_data(context, data):
    security = g.security
    
    # 获取股票过去60天的收盘价数据
    # 注意:这里 count 必须填 60,否则无法准确计算 MA60
    close_data = attribute_history(security, 60, '1d', ['close'])
    
    # 容错处理:如果获取的数据不足60天,则跳过本次循环
    if len(close_data) < 60:
        return
        
    # 计算 MA13 和 MA60
    # 取最后13天的收盘价算平均值
    MA13 = close_data['close'][-13:].mean()
    # 取全部60天的收盘价算平均值
    MA60 = close_data['close'].mean()
    
    # 取得当前的可用现金
    cash = context.portfolio.available_cash
    # 取得当前该标的的持仓量(可卖出的数量)
    current_position = context.portfolio.positions[security].closeable_amount

    # 核心策略逻辑:
    # 买入条件:MA13 - MA60 的值大于 MA60 * 偏离度
    if (MA13 - MA60) > (MA60 * g.deviation_rate):
        # 并且账户有可用资金
        if cash > 0:
            # 用所有可用资金买入
            order_value(security, cash)
            # 打印日志,方便在回测结果中查看为什么买入
            log.info("【买入】MA13: %.2f, MA60: %.2f, 满足偏离度条件" % (MA13, MA60))
            
    # 卖出条件:当 MA13 跌破 MA60 时(死叉),清仓止盈/止损
    elif MA13 < MA60:
        # 并且当前持有该标的
        if current_position > 0:
            # 目标持仓设为0,即全部卖出
            order_target(security, 0)
            # 打印日志
            log.info("【卖出】MA13: %.2f 跌破 MA60: %.2f, 清仓" % (MA13, MA60))

💡 新手调试小技巧

如果你以后再遇到“不交易”的情况,最有效的排查方法是多用 log.info() 打印变量。例如,在 if 判断之前加上一句:
log.info("当前MA13: %s, 当前MA60: %s, 目标阈值: %s" % (MA13, MA60, MA60 * g.deviation_rate))

这样在回测日志中,你就能清楚地看到每天计算出来的均线数值是多少,为什么没有满足你的 if 条件,从而快速定位是公式写错了,还是参数设置得太苛刻了。祝你量化学习顺利!