3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
开盘区间突破(Opening Range Breakout,简称 ORB)是一种经典的日内交易策略。其核心逻辑是在开盘前 N 分钟(如前 30 分钟)确定股票或期货的价格波动区间(最高价与最低价),当后续价格突破该区间上轨时买入做多,突破下轨时卖出平仓或做空,并在收盘前强制平仓规避隔夜风险。
本文将指导您如何在 QMT(迅投量化交易平台)中使用 Python 编写并运行一个完整的 ORB 日内突破策略。
high_range 与最低价 low_range。high_range 且当前无持仓时,以对手价或最新价买入。请在 QMT【策略开发】-【新建模型】中选择 Python 策略,并粘贴以下代码:
#encoding:gbk
import time
import datetime
def init(ContextInfo):
# 1. 设置订阅与标的
ContextInfo.stock = ContextInfo.stockcode if ContextInfo.stockcode else '600000.SH'
ContextInfo.set_universe([ContextInfo.stock])
# 2. 设置交易账号
ContextInfo.account = '6000000058' # 请替换为您的资金账号
ContextInfo.set_account(ContextInfo.account)
# 3. 策略全局参数定义
ContextInfo.trade_volume = 1000 # 每次交易股数
ContextInfo.has_traded_today = False # 当日是否已触发交易
ContextInfo.high_range = None # 开盘区间上轨
ContextInfo.low_range = None # 开盘区间下轨
print(f"策略初始化完成,交易标的: {ContextInfo.stock}")
def handlebar(ContextInfo):
# 获取当前 K 线的时间戳并转换为 HHMMSS 格式
timetag = ContextInfo.get_bar_timetag(ContextInfo.barpos)
bar_time_str = timetag_to_datetime(timetag, '%H%M%S')
time_int = int(bar_time_str)
# 每天开盘重置交易状态
if time_int == 93100:
ContextInfo.has_traded_today = False
ContextInfo.high_range = None
ContextInfo.low_range = None
# 1. 确定开盘区间 (09:30 - 10:00)
if 93000 <= time_int <= 100000:
# 获取今天开盘到当前bar的分钟线数据
df = ContextInfo.get_market_data(['high', 'low'], stock_code=[ContextInfo.stock], period='1m', count=30)
if not df.empty:
ContextInfo.high_range = df['high'].max()
ContextInfo.low_range = df['low'].min()
return
# 若未成功计算出开盘区间,跳过后续逻辑
if ContextInfo.high_range is None or ContextInfo.low_range is None:
return
# 获取最新价格
full_tick = ContextInfo.get_full_tick([ContextInfo.stock])
if ContextInfo.stock not in full_tick:
return
last_price = full_tick[ContextInfo.stock]['lastPrice']
# 2. 突破区间 - 买入信号 (10:00 - 14:50 期间)
if 100000 < time_int < 145000 and not ContextInfo.has_traded_today:
if last_price > ContextInfo.high_range:
print(f"[{bar_time_str}] 价格突破上轨({ContextInfo.high_range}),触发买入信号!最新价: {last_price}")
# 使用 passorder 发送买入委托(股票买入,指定股数)
passorder(23, 1101, ContextInfo.account, ContextInfo.stock, 5, -1, ContextInfo.trade_volume, 'ORB_Breakout', 1, 'buy_signal', ContextInfo)
ContextInfo.has_traded_today = True
# 3. 日内离场与止损逻辑
# (A) 跌破下轨止损
if 100000 < time_int < 145000 and ContextInfo.has_traded_today:
if last_price < ContextInfo.low_range:
print(f"[{bar_time_str}] 价格跌破下轨({ContextInfo.low_range}),触发止损平仓!")
passorder(24, 1101, ContextInfo.account, ContextInfo.stock, 5, -1, ContextInfo.trade_volume, 'ORB_StopLoss', 1, 'sell_signal', ContextInfo)
ContextInfo.has_traded_today = False
# (B) 尾盘强平清仓 (14:55 后强制平仓避开隔夜风险)
if time_int >= 145500:
pos_list = get_trade_detail_data(ContextInfo.account, 'STOCK', 'POSITION')
for pos in pos_list:
if pos.m_strInstrumentID == ContextInfo.stock and pos.m_nCanUseVolume > 0:
print(f"[{bar_time_str}] 尾盘定时平仓,卖出可用持仓: {pos.m_nCanUseVolume}")
passorder(24, 1101, ContextInfo.account, ContextInfo.stock, 5, -1, pos.m_nCanUseVolume, 'ORB_CloseDay', 1, 'close_day', ContextInfo)
ContextInfo.get_full_tick():获取当前最新盘口分笔数据,适用于盘中计算最新价。passorder():QMT 核心综合下单函数。
opType=23:股票买入;opType=24:股票卖出。orderType=1101:单股单账号按股/手方式下单。prType=5:以最新价(Latest Price)下单。quickTrade=1:开启快速交易,无需等待当前 Bar 完全走完即可即时触发委托。get_trade_detail_data():查询当前资金账号的实际持仓(POSITION),确保尾盘平仓准确执行。m_nCanUseVolume 可用数量。