3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化交易中,多周期共振策略能有效过滤假突破信号。通过大周期(如日线)判断市场整体趋势和超买超卖状态,再结合小周期(如 5 分钟线)寻找精准的入场点,可以大幅提升策略的胜率与盈亏比。
本文将详细介绍如何在 QMT(迅投 Python API) 中使用 ContextInfo.get_market_data_ex 接口获取跨周期数据,并构建一个日线 KDJ 与 5 分钟 MACD 共振突破系统。
大周期(日线)趋势过滤:
小周期(5 分钟)精准触发:
出场机制:
在 QMT 中实现多周期共振,关键在于使用 ContextInfo.get_market_data_ex 接口动态提取非主图周期的数据:
period='1d':指定获取日线历史数据。period='5m':指定获取 5 分钟历史数据。subscribe=True:实时订阅多周期行情推送。请在 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
get_market_data_ex 接口前,请确保在 QMT 客户端的【数据管理】中已经下载了对应品种的日线和 5 分钟历史数据。handlebar 频繁驱动时可能会增加计算开销,建议添加 ContextInfo.is_last_bar() 或 is_new_bar() 进行执行频率过滤。