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

如何在 qmt 中开发跨周期(日线+15分钟线)MACD 与 RSI 信号过滤策略?

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

问题描述

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

Title: qmt 多周期共振:跨周期 MACD 与 RSI 信号过滤策略开发

Question: 如何使用 qmt 编写日线与 15 分钟线共振的技术指标策略?

解决方案

qmt 多周期共振:跨周期 MACD 与 RSI 信号过滤策略开发

在量化交易中,“多周期共振”是一种非常经典且有效的交易思想。大周期(如日线)决定整体趋势方向,小周期(如 15 分钟线)寻找精准的择时入场点。利用 QMT(迅投量化)平台的 Python API,我们可以非常高效地获取不同周期的数据并进行跨周期信号过滤。


策略逻辑设计

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

    • 当日线 MACD 的 DIF 线大于 DEA 线(金叉状态或多头区域),判定主趋势为多头,仅允许做多。
    • 当日线 MACD 的 DIF 线小于 DEA 线(死叉状态或空头区域),判定主趋势为空头,仅允许做空或平仓。
  2. 小周期择时触发(15 分钟级别)

    • 买入信号:日线处于多头趋势 + 15 分钟 RSI 处于超卖区(如 RSI < 30)后反弹上穿 30。
    • 卖出信号:15 分钟 RSI 处于超买区(如 RSI > 70)或日线趋势转空时平仓。

QMT 核心 API 说明

  • ContextInfo.get_market_data_ex():获取跨周期历史行情数据的核心 API。通过设置 period='1d' 获取日线数据,设置 period='15m' 获取 15 分钟数据。
  • passorder():QMT 下单核心函数,用于执行实际交易指令。

完整 Python 策略代码

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

def init(ContextInfo):
    # 设定交易标的
    ContextInfo.symbol = '600000.SH'
    ContextInfo.set_universe([ContextInfo.symbol])
    
    # 设置账号
    ContextInfo.account = '6000000248'
    ContextInfo.set_account(ContextInfo.account)
    
    # 策略参数设置
    ContextInfo.rsi_period = 14
    ContextInfo.rsi_oversold = 30
    ContextInfo.rsi_overbought = 70
    
    print("策略初始化完成:跨周期多信号共振策略")

def handlebar(ContextInfo):
    # 仅在最新 Bar 或者是关键 tick 上运算,加速历史运行
    index = ContextInfo.barpos
    realtime = ContextInfo.get_bar_timetag(index)
    
    stock = ContextInfo.symbol
    
    # 1. 获取日线数据(用于计算日线 MACD)
    df_day = ContextInfo.get_market_data_ex(
        fields=['close'], 
        stock_code=[stock], 
        period='1d', 
        count=100, 
        subscribe=False
    )[stock]
    
    if len(df_day) < 35:
        return
    
    # 计算日线 MACD (12, 26, 9)
    exp1 = df_day['close'].ewm(span=12, adjust=False).mean()
    exp2 = df_day['close'].ewm(span=26, adjust=False).mean()
    macd_dif = exp1 - exp2
    macd_dea = macd_dif.ewm(span=9, adjust=False).mean()
    
    # 日线主趋势判定:DIF > DEA 为多头趋势
    day_bullish = macd_dif.iloc[-1] > macd_dea.iloc[-1]
    
    # 2. 获取 15 分钟线数据(用于计算 15M RSI)
    df_15m = ContextInfo.get_market_data_ex(
        fields=['close'], 
        stock_code=[stock], 
        period='15m', 
        count=100, 
        subscribe=False
    )[stock]
    
    if len(df_15m) < ContextInfo.rsi_period + 1:
        return
    
    # 计算 15分钟 RSI
    close_diff = df_15m['close'].diff()
    gain = (close_diff.where(close_diff > 0, 0)).rolling(window=ContextInfo.rsi_period).mean()
    loss = (-close_diff.where(close_diff < 0, 0)).rolling(window=ContextInfo.rsi_period).mean()
    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    
    current_rsi = rsi.iloc[-1]
    prev_rsi = rsi.iloc[-2]
    
    # 3. 交易逻辑判断与下单执行
    # 获取当前持仓
    pos_list = get_trade_detail_data(ContextInfo.account, 'STOCK', 'POSITION')
    current_pos = 0
    for pos in pos_list:
        if pos.m_strInstrumentID == stock.split('.')[0]:
            current_pos = pos.m_nCanUseVolume
            break
            
    # 多头买入条件:日线MACD看多 + 15M RSI从超卖区向上穿过 30
    if day_bullish and prev_rsi < ContextInfo.rsi_oversold and current_rsi >= ContextInfo.rsi_oversold:
        if current_pos == 0:
            print(f"[买入信号] 日线看多,15m RSI上穿超卖区 ({current_rsi:.2f}),执行买入")
            # 最新价买入 1000 股
            passorder(23, 1101, ContextInfo.account, stock, 5, -1, 1000, '多周期共振策略', 1, 'buy_rsi', ContextInfo)
            
    # 平仓条件:15M RSI进入超买区(>70) 或 日线MACD转空
    elif current_pos > 0 and (current_rsi > ContextInfo.rsi_overbought or not day_bullish):
        print(f"[卖出信号] 触发平仓条件,RSI={current_rsi:.2f},日线趋势多头={day_bullish},执行平仓")
        passorder(24, 1101, ContextInfo.account, stock, 5, -1, current_pos, '多周期共振策略', 1, 'sell_rsi', ContextInfo)

策略开发注意事项

  1. 数据下载与补充:在使用 get_market_data_ex 接口获取历史 K 线前,请务必在客户端【数据管理】中补充完整目标股票的日线及 15 分钟线历史行情数据。
  2. 刷新间隔设置:跨周期策略建议设置在 15 分钟周期上运行,或使用 ContextInfo.run_time() 定时器进行驱动,避免频繁触发。
  3. 快捷下单参数:在实盘或模拟盘运行时,可以将 passorder 中的 quickTrade 参数设置为 1 以实现信号触发后立即下发委托。