3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
实现日线和分钟线共振(Multi-timeframe Resonance)的交易策略,核心逻辑是**“大周期定方向,小周期找买点”**。
以下是完整的 Python 策略代码。请在 QMT 的策略编辑器中新建一个 Python 策略,将代码复制进去。
注意:
ContextInfo.account_id 替换为您真实的资金账号。# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
"""
初始化函数,设定策略参数和变量
"""
# 1. 设置资金账号 (请修改为您自己的账号)
ContextInfo.account_id = '6000000000'
ContextInfo.account_type = 'STOCK' # 股票账号
ContextInfo.set_account(ContextInfo.account_id)
# 2. 设置股票池 (示例:平安银行)
ContextInfo.stock_code = '000001.SZ'
ContextInfo.set_universe([ContextInfo.stock_code])
# 3. 策略参数设置
# 日线参数
ContextInfo.day_period = '1d'
ContextInfo.day_ma_len = 20 # 日线趋势均线
# 分钟线参数 (主图运行周期建议设为 5m)
ContextInfo.min_period = '5m' # 策略运行周期
ContextInfo.min_ma_fast = 5 # 分钟快线
ContextInfo.min_ma_slow = 10 # 分钟慢线
# 交易数量
ContextInfo.trade_vol = 100 # 每次交易100股
def get_position(ContextInfo, stock_code):
"""
获取当前持仓数量的辅助函数
"""
try:
# 获取持仓对象列表
positions = get_trade_detail_data(ContextInfo.account_id, ContextInfo.account_type, 'POSITION')
for pos in positions:
if pos.m_strInstrumentID + '.' + pos.m_strExchangeID == stock_code:
return pos.m_nVolume
except Exception as e:
print("获取持仓失败: ", e)
return 0
def handlebar(ContextInfo):
"""
K线运行逻辑,每根K线(或Tick)调用一次
"""
# 获取当前正在处理的股票代码
stock = ContextInfo.stock_code
# ----------------------------------------------------------------
# 第一步:获取日线数据,判断大趋势 (大周期)
# ----------------------------------------------------------------
# 获取足够计算MA20的日线数据
# 注意:dividend_type='front' 为前复权,确保价格连续
day_data_map = ContextInfo.get_market_data_ex(
['close'],
[stock],
period=ContextInfo.day_period,
count=ContextInfo.day_ma_len + 5,
dividend_type='front',
fill_data=True,
subscribe=True
)
if stock not in day_data_map:
return # 数据未准备好
df_day = day_data_map[stock]
if len(df_day) < ContextInfo.day_ma_len:
return # 数据长度不足
# 计算日线 MA20
day_ma = df_day['close'].rolling(window=ContextInfo.day_ma_len).mean()
# 获取最新的日线收盘价和均线值
# 注意:盘中运行时,iloc[-1] 是包含当天实时数据的(动态复盘)
current_day_close = df_day['close'].iloc[-1]
current_day_ma = day_ma.iloc[-1]
# 判断日线趋势:收盘价 > MA20 为多头趋势
is_day_bullish = current_day_close > current_day_ma
# ----------------------------------------------------------------
# 第二步:获取分钟线数据,寻找买卖点 (小周期)
# ----------------------------------------------------------------
# 获取分钟线数据
min_data_map = ContextInfo.get_market_data_ex(
['close'],
[stock],
period=ContextInfo.min_period,
count=ContextInfo.min_ma_slow + 5,
dividend_type='front',
fill_data=True,
subscribe=True
)
if stock not in min_data_map:
return
df_min = min_data_map[stock]
if len(df_min) < ContextInfo.min_ma_slow:
return
# 计算分钟线均线
min_ma_fast = df_min['close'].rolling(window=ContextInfo.min_ma_fast).mean()
min_ma_slow = df_min['close'].rolling(window=ContextInfo.min_ma_slow).mean()
# 获取当前和上一根K线的均线值,用于判断交叉
curr_fast = min_ma_fast.iloc[-1]
curr_slow = min_ma_slow.iloc[-1]
prev_fast = min_ma_fast.iloc[-2]
prev_slow = min_ma_slow.iloc[-2]
# 判断金叉:快线上穿慢线
is_golden_cross = (prev_fast <= prev_slow) and (curr_fast > curr_slow)
# 判断死叉:快线下穿慢线
is_death_cross = (prev_fast >= prev_slow) and (curr_fast < curr_slow)
# ----------------------------------------------------------------
# 第三步:交易执行逻辑 (共振判断)
# ----------------------------------------------------------------
# 获取当前持仓
current_pos = get_position(ContextInfo, stock)
# 1. 买入逻辑:日线多头趋势 + 分钟线金叉 + 当前无持仓
if is_day_bullish and is_golden_cross and current_pos == 0:
print(f"【买入信号】{stock} 日线趋势向上,5分钟金叉。价格: {df_min['close'].iloc[-1]}")
# 23: 买入, 1101: 单股单账号, 5: 最新价
passorder(23, 1101, ContextInfo.account_id, stock, 5, -1, ContextInfo.trade_vol, ContextInfo)
# 2. 卖出逻辑:分钟线死叉 + 当前有持仓 (止盈/止损)
# 注:这里只看小周期死叉离场,也可以加上日线转空的条件
elif is_death_cross and current_pos > 0:
print(f"【卖出信号】{stock} 5分钟死叉。价格: {df_min['close'].iloc[-1]}")
# 24: 卖出, 1101: 单股单账号, 5: 最新价
passorder(24, 1101, ContextInfo.account_id, stock, 5, -1, current_pos, ContextInfo)
# 调试信息输出 (可选)
if ContextInfo.is_last_bar():
print(f"监控中: {stock} | 日线多头: {is_day_bullish} | 5分快线: {curr_fast:.2f} | 5分慢线: {curr_slow:.2f}")
跨周期数据获取 (get_market_data_ex):
get_market_data_ex 接口非常强大,允许你在同一个策略中请求不同周期的数据。period=ContextInfo.day_period ('1d') 和 period=ContextInfo.min_period ('5m') 的数据。共振逻辑实现:
is_day_bullish 锁定了大方向。只有当它为 True 时,代码才会进入买入判断逻辑。is_golden_cross 提供了精确的进场时机。if is_day_bullish and is_golden_cross: 实现了共振。交易执行 (passorder):
passorder 函数。opType=23 代表股票买入,24 代表股票卖出。prType=5 代表使用最新价下单(实盘中可能需要考虑滑点或使用对手价 prType=14)。持仓检查:
get_position 辅助函数,通过 get_trade_detail_data 接口查询当前账户的实际持仓。ContextInfo.account_id 填写正确。Q: 为什么不在日线周期上运行这个策略?
A: 如果在日线周期上运行,handlebar 每天只会在收盘时调用一次。这样你就无法捕捉到盘中 5 分钟级别的金叉买点,失去了“共振”中利用小周期优化进场点的意义。
Q: 如何让日线趋势判断更稳定,不随盘中价格波动而变化?
A: 当前代码使用的是当日实时价格与 MA20 比较。如果你希望趋势判断更保守,可以使用昨日的收盘数据。修改代码如下:
# 使用倒数第二根K线(昨日)的数据
prev_day_close = df_day['close'].iloc[-2]
prev_day_ma = day_ma.iloc[-2]
is_day_bullish = prev_day_close > prev_day_ma
Q: get_market_data_ex 和 get_market_data 有什么区别?
A: get_market_data_ex 是 QMT 推荐的新版接口,返回的数据结构更清晰(字典包含 DataFrame),且支持更丰富的参数(如复权方式、停牌填充等),在处理多股、多周期数据时更稳定。