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

为什么量化交易中少见纯 MACD 0轴上二次金叉策略?(附 JoinQuant 源码)

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

问题描述

为什么没人做macd0轴上二次金叉的策略?

看网上很多都在说macd 0轴上二次金叉是买入的黄金时期,为什么没有人做这个策略,太简单?还是这个策略不靠谱??

解决方案

其实并不是没有人做,而是纯粹依赖“MACD 0轴上二次金叉”作为单一买入信号的量化策略,在实盘和长期回测中往往表现不佳。网上流传的“黄金买点”更多是基于人工看盘时的“幸存者偏差”(人们往往只记住成功的案例,而忽略了失败的案例)。

在量化交易中,这个策略存在以下几个致命的弱点:

1. 为什么纯 MACD 二次金叉策略“不靠谱”?

  • 严重的滞后性:MACD 本质上是基于均线(EMA)的衍生指标。当“0轴上二次金叉”形成时,往往意味着价格已经经历了一波上涨(第一次金叉)、一波回调(死叉),然后再次上涨(二次金叉)。此时买入,往往买在阶段性高点,容易成为“接盘侠”。
  • 震荡市的“绞肉机”:MACD 是典型的趋势跟踪指标。在明显的单边上涨行情中,它表现极好;但在震荡市中,DIF 和 DEA 会在 0 轴附近频繁交叉(假突破),导致策略频繁买卖,产生大量的滑点和手续费,造成连续亏损(俗称“来回打脸”)。
  • 单因子的局限性:现代量化交易早已过了“一个技术指标打天下”的时代。纯量价指标缺乏对公司基本面、宏观环境和市场情绪的考量,胜率通常很难超过 50%。
  • “二次”的定义模糊:在量化代码中,如何定义“二次”?两次金叉之间间隔多少天算有效?回调幅度多大算有效?这些参数的微调会导致策略结果天差地别(过拟合风险极高)。

2. 如何在 JoinQuant 中实现该策略?

虽然纯策略不完美,但我们可以将其作为一个基础信号进行测试。以下是在 JoinQuant 平台实现“MACD 0轴上金叉”的基础框架(为了简化,这里以0轴上金叉为例,二次金叉需要引入更复杂的状态记录):

# 导入聚宽函数库
import jqdata
import talib
import numpy as np

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 股票类每笔交易时的手续费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 设定要操作的股票池(例如:平安银行)
    g.security = '000001.XSHE'
    
    # 运行函数
    run_daily(market_open, time='09:30')

def market_open(context):
    security = g.security
    
    # 获取过去 40 天的收盘价数据来计算 MACD
    # MACD 默认参数为 12, 26, 9,需要足够的数据预热
    close_data = attribute_history(security, 60, '1d', ['close'], df=False)
    close_prices = close_data['close']
    
    if len(close_prices) < 60:
        return
        
    # 使用 talib 计算 MACD
    macd, macdsignal, macdhist = talib.MACD(close_prices, fastperiod=12, slowperiod=26, signalperiod=9)
    
    # 获取昨日和前日的 DIF (macd) 和 DEA (macdsignal)
    dif_yesterday = macd[-1]
    dea_yesterday = macdsignal[-1]
    dif_before_yesterday = macd[-2]
    dea_before_yesterday = macdsignal[-2]
    
    # 判断条件:
    # 1. 0轴之上:昨日 DIF > 0 且 DEA > 0
    # 2. 金叉:前日 DIF < DEA,昨日 DIF > DEA
    is_above_zero = (dif_yesterday > 0) and (dea_yesterday > 0)
    is_golden_cross = (dif_before_yesterday < dea_before_yesterday) and (dif_yesterday > dea_yesterday)
    
    # 取得当前的现金
    cash = context.portfolio.available_cash
    current_position = context.portfolio.positions[security].closeable_amount
    
    # 买入逻辑
    if is_above_zero and is_golden_cross and cash > 0:
        order_value(security, cash)
        log.info("MACD 0轴上金叉,买入 %s" % security)
        
    # 卖出逻辑:死叉卖出
    is_dead_cross = (dif_before_yesterday > dea_before_yesterday) and (dif_yesterday < dea_yesterday)
    if is_dead_cross and current_position > 0:
        order_target(security, 0)
        log.info("MACD 死叉,卖出 %s" % security)

3. 策略优化建议

如果你想把这个思路做成一个能赚钱的策略,必须进行多因子叠加和过滤:

  1. 叠加基本面过滤:不要在所有股票上找金叉。先用基本面因子(如 ROE > 15%,净利润增长率 > 20%)筛选出一个优质股票池,然后再在这些好股票里找 MACD 买点。
  2. 结合大盘环境:只有在沪深300或中证500处于多头趋势(如指数在20日均线之上)时,才允许触发买入信号。震荡市或熊市直接空仓。
  3. 引入成交量确认:金叉发生时,必须伴随成交量的显著放大(如当日成交量是过去5日均量的1.5倍以上),以过滤假突破。
  4. 严格的止损止盈:技术指标策略必须配以严格的止损(如跌破买入价的 8% 无条件止损)和移动止盈,以控制最大回撤。