🚀 AI 一键生成 qmt 策略代码
立即体验

QMT 平台如何实现跨周期 KDJ 与 MACD 共振策略?(附 Python 完整源码)

qmt | 发布时间: 2026/8/1
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: QMT 多周期策略:日线 KDJ 与 5 分钟 MACD 共振突破系统

Question: 如何在 QMT 中实现跨周期的 KDJ 和 MACD 信号共振交易?

解决方案

QMT 多周期策略:日线 KDJ 与 5 分钟 MACD 共振突破系统

在量化交易中,多周期共振策略能有效过滤假突破信号。通过大周期(如日线)判断市场整体趋势和超买超卖状态,再结合小周期(如 5 分钟线)寻找精准的入场点,可以大幅提升策略的胜率与盈亏比。

本文将详细介绍如何在 QMT(迅投 Python API) 中使用 ContextInfo.get_market_data_ex 接口获取跨周期数据,并构建一个日线 KDJ 与 5 分钟 MACD 共振突破系统


一、策略逻辑设计

  1. 大周期(日线)趋势过滤

    • 计算日线周期的 KDJ 指标(推荐参数 9, 3, 3)。
    • 当日线 J 值 < 20 且上穿 K 值(或处于超卖区底背离/金叉阶段)时,判定大周期看多条件成立。
  2. 小周期(5 分钟)精准触发

    • 主图运行周期设置为 5分钟
    • 计算 5 分钟周期的 MACD 指标(常规参数 12, 26, 9)。
    • 当大周期看多条件成立时,若 5 分钟线发生 MACD 金叉(DIF 上穿 DEA),则触发买入信号。
  3. 出场机制

    • 5 分钟 MACD 死叉或达到固定止盈止损点位时平仓出场。

二、QMT 核心 API 接口说明

在 QMT 中实现多周期共振,关键在于使用 ContextInfo.get_market_data_ex 接口动态提取非主图周期的数据:

  • period='1d':指定获取日线历史数据。
  • period='5m':指定获取 5 分钟历史数据。
  • subscribe=True:实时订阅多周期行情推送。

三、QMT 策略完整代码实现

请在 QMT 策略编辑器中直接复制以下 Python 代码并进行回测或实盘:

#encoding:gbk
import numpy as np
import pandas as pd
import talib

def init(ContextInfo):
    # 设置标的与资金账号
    ContextInfo.s = '600000.SH'
    ContextInfo.set_universe([ContextInfo.s])
    ContextInfo.account = '6000000248'
    ContextInfo.set_account(ContextInfo.account)
    
    # 策略全局变量控制
    ContextInfo.hold = False
    print("策略初始化完成:日线KDJ + 5分钟MACD共振系统")

def get_kdj(df_close, df_high, df_low, n=9, m1=3, m2=3):
    """计算 KDJ 指标"""
    low_list = df_low.rolling(window=n, min_periods=n).min()
    high_list = df_high.rolling(window=n, min_periods=n).max()
    rsv = (df_close - low_list) / (high_list - low_list) * 100
    rsv = rsv.fillna(0)
    
    k = rsv.ewm(com=m1-1, adjust=False).mean()
    d = k.ewm(com=m2-1, adjust=False).mean()
    j = 3 * k - 2 * d
    return k, d, j

def handlebar(ContextInfo):
    # 仅在最新 bar 上执行交易逻辑
    if not ContextInfo.is_last_bar():
        return
        
    stock = ContextInfo.s
    
    # 1. 获取日线历史数据并计算 KDJ
    daily_data = ContextInfo.get_market_data_ex(
        fields=['open', 'high', 'low', 'close'],
        stock_code=[stock],
        period='1d',
        count=30,
        subscribe=True
    )
    df_daily = daily_data[stock]
    if len(df_daily) < 15:
        return
        
    k_daily, d_daily, j_daily = get_kdj(df_daily['close'], df_daily['high'], df_daily['low'])
    # 日线多头条件:J值低于30且金叉(J>K)
    day_bullish = (j_daily.iloc[-1] < 30) or (j_daily.iloc[-1] > k_daily.iloc[-1] and j_daily.iloc[-2] <= k_daily.iloc[-2])
    
    # 2. 获取 5 分钟历史数据并计算 MACD
    m5_data = ContextInfo.get_market_data_ex(
        fields=['close'],
        stock_code=[stock],
        period='5m',
        count=60,
        subscribe=True
    )
    df_m5 = m5_data[stock]
    if len(df_m5) < 35:
        return
        
    macd_dif, macd_dea, macd_hist = talib.MACD(df_m5['close'].values, fastperiod=12, slowperiod=26, signalperiod=9)
    
    # 5分钟 MACD 金叉与死叉条件
    m5_gold_cross = macd_dif[-1] > macd_dea[-1] and macd_dif[-2] <= macd_dea[-2]
    m5_dead_cross = macd_dif[-1] < macd_dea[-1] and macd_dif[-2] >= macd_dea[-2]
    
    # 3. 交易信号决策
    # 买入条件:日线看多 + 5分钟MACD金叉 + 未持仓
    if day_bullish and m5_gold_cross and not ContextInfo.hold:
        print(f"[触发买入] 日线KDJ共振 5分钟MACD金叉,标的:{stock}")
        # 最新价买入 1000 股
        passorder(23, 1101, ContextInfo.account, stock, 5, -1, 1000, '多周期共振', 1, stock, ContextInfo)
        ContextInfo.hold = True
        
    # 卖出条件:5分钟MACD死叉 + 已持仓
    elif m5_dead_cross and ContextInfo.hold:
        print(f"[触发卖出] 5分钟MACD死叉平仓,标的:{stock}")
        # 最新价卖出平仓
        passorder(24, 1101, ContextInfo.account, stock, 5, -1, 1000, '多周期共振', 1, stock, ContextInfo)
        ContextInfo.hold = False

四、总结与风险提示

  1. 数据补充:在使用 get_market_data_ex 接口前,请确保在 QMT 客户端的【数据管理】中已经下载了对应品种的日线和 5 分钟历史数据。
  2. 执行效率:多周期计算在 handlebar 频繁驱动时可能会增加计算开销,建议添加 ContextInfo.is_last_bar()is_new_bar() 进行执行频率过滤。
  3. 滑点与手续费:短线周期交易频繁,需在 QMT 回测面板中合理设置滑点与手续费以评估真实收益。