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

如何在 QMT 平台实现日内开盘区间突破 (ORB) 交易策略?(附 Python 完整源码)

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

问题描述

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

Title: QMT 日内突破策略:基于 ORB (Opening Range Breakout) 的 Python 实现

Question: 如何在 QMT 中编写一个日内开盘区间突破 (ORB) 交易策略?

解决方案

如何在 QMT 中编写一个日内开盘区间突破 (ORB) 交易策略?

开盘区间突破(Opening Range Breakout,简称 ORB)是一种经典的日内交易策略。其核心逻辑是在开盘前 N 分钟(如前 30 分钟)确定股票或期货的价格波动区间(最高价与最低价),当后续价格突破该区间上轨时买入做多,突破下轨时卖出平仓或做空,并在收盘前强制平仓规避隔夜风险。

本文将指导您如何在 QMT(迅投量化交易平台)中使用 Python 编写并运行一个完整的 ORB 日内突破策略。


1. 策略核心逻辑设计

  1. 定义开盘区间:获取开盘前 30 分钟(即 09:30 - 10:00)的最高价 high_range 与最低价 low_range
  2. 生成交易信号
    • 突破做多:当 10:00 之后的最新价高于 high_range 且当前无持仓时,以对手价或最新价买入。
    • 移动止损 / 平仓:回落突破下轨或触及设定止损点时平仓。
  3. 日内平仓:尾盘(如 14:55)清仓所有日内头寸,不持有隔夜仓位。

2. QMT Python 策略完整源码

请在 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)

3. 关键函数与 API 说明

  • ContextInfo.get_full_tick():获取当前最新盘口分笔数据,适用于盘中计算最新价。
  • passorder():QMT 核心综合下单函数。
    • opType=23:股票买入;opType=24:股票卖出。
    • orderType=1101:单股单账号按股/手方式下单。
    • prType=5:以最新价(Latest Price)下单。
    • quickTrade=1:开启快速交易,无需等待当前 Bar 完全走完即可即时触发委托。
  • get_trade_detail_data():查询当前资金账号的实际持仓(POSITION),确保尾盘平仓准确执行。

4. 实盘与回测注意事项

  1. 数据准备:运行前请通过 QMT【数据管理】补充该标的对应的 1 分钟(1m)历史 Tick 与 K 线数据。
  2. 滑点与手续费:突破策略对交易成本敏感,建议在策略编辑器的【回测参数】中合理设置滑点与佣金(如万分之二.五)。
  3. T+1 规则限制:股票市场实行 T+1 交易,若是当日买入的股票,尾盘强平需确认持仓的 m_nCanUseVolume 可用数量。