QMT策略交易系统——策略函数交易完全教程

PTD 阅读:5 2026-07-17 09:18:02 评论:0

QMT极速策略交易系统——策略函数交易完全教程

本教程从零开始,以“每日定时自动委托国债逆回购”为切入点,带你逐步掌握QMT中策略函数交易的核心技能。

一、开启策略函数交易——从定时国债逆回购开始

1.1 为什么从国债逆回购开始?

国债逆回购是策略函数交易的最佳入门案例,原因有2:

  • 逻辑简单:就是每天收盘前把闲置资金以“卖出”方式借出
  • 实用性强:每天自动操作,不用再手动惦记

1.2 在QMT中创建Python策略

第一步:进入模型研究界面

打开QMT客户端,点击顶部菜单栏的“模型研究”,进入策略编写环境。

第二步:新建Python策略

点击“新建模型”按钮,在弹出的选项中选择“Python模型”。系统会打开「模型编辑器」,这是QMT专门为策略开发者设计的集成开发环境。

第三步:编写定时逆回购策略代码

在模型编辑器中输入以下完整代码:

# -*- coding: UTF-8 -*-
import time
from datetime import datetime

def init(ContextInfo):
    """初始化函数——策略启动时执行一次"""
    # 设置你的资金账号(替换为实际账号)
    ContextInfo.account = '你的资金账号'
    # 设置逆回购品种(以204001为例,1天期沪市逆回购)
    ContextInfo.repo_code = '204001.SH'
    # 设置每日执行时间(下午14:50)
    ContextInfo.run_time = '14:50'
    # 设置最低参与金额(逆回购门槛1000元)
    ContextInfo.min_amount = 1000
    # 设置预留资金(保留部分资金备用,如新股缴款)
    ContextInfo.reserve_amount = 0
    
    # 注册定时任务
    ContextInfo.run_time("daily_repo", "1d", ContextInfo.run_time)

def daily_repo(ContextInfo):
    """定时执行逆回购的函数"""
    # 1. 获取当前时间,判断是否在工作日交易时段
    now = datetime.now()
    if now.weekday() >= 5:  # 周六(5)、周日(6)不执行
        return
    
    # 2. 获取账户可用资金
    account_info = ContextInfo.get_account_info()
    available = account_info.get('可用金额', 0)
    
    # 3. 判断资金是否满足条件
    if available <= ContextInfo.reserve_amount + ContextInfo.min_amount:
        print(f"可用资金{available}不足,跳过逆回购")
        return
    
    # 4. 计算实际下单金额(取整到1000的整数倍)
    trade_amount = int((available - ContextInfo.reserve_amount) // 1000 * 1000)
    if trade_amount <= 0:
        return
    
    # 5. 获取实时行情,判断收益率是否达到阈值(可选)
    # 获取当前逆回购的实时价格(即年化收益率)
    tick = ContextInfo.get_full_tick([ContextInfo.repo_code])
    if ContextInfo.repo_code in tick:
        current_rate = tick[ContextInfo.repo_code]['lastPrice']
        # 如果收益率低于2%,暂不操作(可根据需要调整)
        if current_rate < 2.0:
            print(f"当前收益率{current_rate}%低于阈值2%,暂不操作")
            return
    
    # 6. 执行逆回购卖出(核心下单操作)
    # 逆回购是“卖出”操作,下单类型为24(股票卖出)
    # 数量单位为“张”,1000元=10张
    volume = trade_amount // 1000 * 10
    
    result = passorder(
        24,                      # opType: 24=卖出
        1101,                    # orderType: 下单方式
        ContextInfo.account,     # accountid: 资金账号
        ContextInfo.repo_code,   # orderCode: 证券代码
        5,                       # prType: 5=最新价
        -1,                      # price: -1表示按prType取价
        volume,                  # volume: 数量
        '逆回购',                # strategyName: 策略名称
        2,                       # quickTrade: 2=立即下单
        '',                      # userOrderId: 用户自定义ID
        ContextInfo              # ContextInfo对象
    )
    
    if result == 0:
        print(f"逆回购下单成功:{trade_amount}元,收益率{current_rate}%")
    else:
        print(f"逆回购下单失败,错误码:{result}")

def handlebar(ContextInfo):
    """行情驱动函数——每根K线或每个tick触发"""
    # 本策略采用定时驱动,handlebar中无需额外逻辑
    pass

1.3 策略参数说明

参数 说明 取值示例
逆回购代码 沪市以204开头,深市以1318开头 204001.SH(1天期沪市)、131810.SZ(1天期深市)
执行时间 建议14:30 -15:00之间 14:50
最低金额 沪市10万元起,深市1000元起 根据实际调整
收益率阈值 低于此值不操作 年化2%

1.4 在QMT中运行策略

第一步:设置基本信息

在模型编辑器中,填写策略名称(如“定时逆回购”)、选择默认周期(日线)、默认品种(任意)。

第二步:编译策略

点击“编译”按钮,检查代码是否有语法错误。编译成功后系统会自动保存。

第三步:添加到模型交易

编译成功后,点击“转到实盘交易”按钮,或切换到“模型交易”界面,点击“新建模拟交易”,选择刚才创建的策略。

第四步:选择运行模式

  • 模拟盘:不产生真实交易,仅测试逻辑
  • 实盘:产生真实交易信号,发送至柜台

第五步:启动策略

点击“启动”按钮,策略即开始运行。到设定时间(如14:50),策略会自动检查资金并执行逆回购。

二、QMT策略开发基础框架

2.1 策略的三种运行机制

QMT中Python策略有三种运行方式:

运行方式 触发机制 适用场景
逐K驱动 每根K线结束时触发handlebar() 技术指标策略、均线策略
定时任务 设定固定时间触发run_time() 定时调仓、逆回购、收盘检查
订阅推送 行情变化时实时推送 高频交易、事件驱动策略

2.2 策略的标准代码结构

def init(ContextInfo):
    """
    初始化函数——策略启动时执行一次
    用途:设置参数、注册定时任务、订阅行情
    """
    # 设置交易参数
    ContextInfo.account = '资金账号'
    # 注册定时任务
    ContextInfo.run_time("函数名", "周期", "执行时间")
    # 订阅行情
    ContextInfo.subscribe_quote(['股票代码'])

def handlebar(ContextInfo):
    """
    行情驱动函数——每根K线或每个tick触发
    用途:执行交易逻辑、条件判断
    """
    # 获取行情数据
    # 执行条件判断
    # 调用下单函数

def 自定义定时函数(ContextInfo):
    """
    定时任务函数——在设定时间触发
    用途:定时执行的操作
    """
    # 执行定时任务

2.3 关键概念说明

  • init() :整个策略生命周期只执行一次,适合做初始化设置
  • handlebar() :每收到一个行情数据就会调用一次,是策略的核心执行入口
  • ContextInfo:贯穿整个策略的上下文对象,用于存储状态和调用API

三、核心交易函数——passorder详解

passorder是QMT中最核心的综合下单函数,支持股票、期货、期权、ETF申赎、融资融券等所有交易品种。

3.1 函数完整语法

passorder(opType, orderType, accountid, orderCode, prType, price, volume, 
          strategyName, quickTrade, userOrderId, ContextInfo)

3.2 参数详解

参数1:opType(操作类型)

说明 适用场景
23 买入 股票、ETF、可转债买入
24 卖出 股票、ETF、可转债卖出
27 融资买入 融资融券交易
28 融券卖出 融资融券交易
29 买券还券 融资融券交易
30 直接还券 融资融券交易
31 卖券还款 融资融券交易
32 直接还款 融资融券交易
48 买入开仓 股票期权
49 卖出平仓 股票期权
50 卖出开仓 股票期权
51 买入平仓 股票期权
86 LOF申购 基金
87 LOF赎回 基金
92 新股申购 新股

参数2:orderType(下单方式)

常用值 1101,代表单股、单账号、普通、股/手方式下单。

参数3:accountid(资金账号)

填写你的交易资金账号,字符串格式。

参数4:orderCode(证券代码)

格式为“代码.市场”,如 '600000.SH''000001.SZ'

参数5:prType(报价类型)

说明
3 指定价(需填写price参数)
5 最新价
11 指定价(同3)
42 最优五档即成剩撤(沪市)
43 最优五档即成剩转(沪市)
44 对手最优价(深市)
45 本方最优价(深市)

参数6:price(委托价格)

  • prType=311时,填写具体价格
  • prType=5时,填-1表示取最新价
  • 对于市价单,通常填0

参数7:volume(委托数量)

  • 股票:单位为“股”,100股整数倍
  • 逆回购:单位为“张”,10张=1000元
  • 期货:单位为“手”
  • 期权:单位为“张”

参数8:strategyName(策略名称)

自定义策略名称,用于标识不同策略的下单来源,可选参数。

参数9:quickTrade(快速交易模式)

说明
0 K线走完下单(默认)
1 立即下单
2 立即下单+实时反馈

重点:如果希望策略触发后立刻发出委托,务必设置quickTrade=2

参数10:userOrderId(用户自定义委托ID)

用于外部系统追踪订单,可选参数。

参数11:ContextInfo

策略上下文对象,必填。

3.3 passorder使用示例

示例1:以最新价买入100股

passorder(23, 1101, '6000000201', '600000.SH', 5, -1, 100, 
          '测试买入', 2, '', ContextInfo)

示例2:指定价卖出

passorder(24, 1101, account, '000001.SZ', 3, 10.50, 1000,
          '指定价卖出', 2, '', ContextInfo)

示例3:逆回购卖出(10万元)

passorder(24, 1101, account, '204001.SH', 5, -1, 1000,
          '逆回购', 2, '', ContextInfo)

四、行情数据获取函数

4.1 get_market_data——获取历史行情数据

语法

ContextInfo.get_market_data(fields, stock_code, period, start_time, end_time, 
                            count, skip_paused, dividend_type)

参数说明

参数 说明 示例
fields 要获取的字段列表 ['close','open','high','low','volume']
stock_code 股票代码列表 ['600000.SH','000001.SZ']
period K线周期 '1d'(日线)、'1m'(分钟)
start_time 开始时间 '20240101'
end_time 结束时间 '20241231'
count 获取数量 100
skip_paused 是否跳过停牌 True/False

示例

# 获取最近100根日K线的收盘价
df = ContextInfo.get_market_data(
    ['close'], 
    ['600000.SH'], 
    '1d', 
    count=100
)

4.2 get_full_tick——获取实时行情(全推数据)

语法

ContextInfo.get_full_tick(stock_list)

示例

# 获取多只股票的实时行情
tick_data = ContextInfo.get_full_tick(['600000.SH', '000001.SZ'])
for code, data in tick_data.items():
    print(f"{code}: 最新价={data['lastPrice']}, 涨跌幅={data['pctChg']}")

返回数据包含:lastPrice(最新价)、open(开盘价)、high(最高价)、low(最低价)、volume(成交量)、amount(成交额)、pctChg(涨跌幅)等。

4.3 subscribe_quote——订阅行情数据

用于持续接收特定股票的实时行情推送。

示例

# 在init中订阅
ContextInfo.subscribe_quote(['600000.SH', '000001.SZ'])

# 在handlebar中获取订阅的数据
data = ContextInfo.get_subscribe_quote(['600000.SH'])

五、查询函数

5.1 账户资金查询

# 获取账户信息
account_info = ContextInfo.get_account_info()
# 返回:可用金额、总资产、市值、冻结金额等
available = account_info.get('可用金额', 0)

5.2 持仓查询

# 获取当前持仓
positions = ContextInfo.get_positions()
for pos in positions:
    print(f"{pos['证券代码']}: {pos['可用数量']}股, 成本价{pos['成本价']}")

5.3 委托查询

# 获取当日委托
orders = ContextInfo.get_orders()
for order in orders:
    print(f"委托{order['合同编号']}: {order['证券代码']}, "
          f"状态{order['委托状态']}, 已成交{order['成交数量']}")

5.4 成交查询

# 获取当日成交
deals = ContextInfo.get_deals()
for deal in deals:
    print(f"成交{deal['成交编号']}: {deal['证券代码']}, "
          f"价格{deal['成交价格']}, 数量{deal['成交数量']}")

六、撤单函数

6.1 按合同编号撤单

# 撤销指定委托
ContextInfo.cancel_order('合同编号', '市场代码')

6.2 批量撤单

# 撤销所有未成交委托
orders = ContextInfo.get_orders()
for order in orders:
    if order['委托状态'] == '已报' or order['委托状态'] == '部成':
        ContextInfo.cancel_order(order['合同编号'], order['交易市场'])

七、函数参数字典速查

7.1 opType(操作类型)速查

代码 操作 代码 操作
23 股票买入 24 股票卖出
27 融资买入 28 融券卖出
29 买券还券 30 直接还券
31 卖券还款 32 直接还款
48 期权买入开仓 49 期权卖出平仓
50 期权卖出开仓 51 期权买入平仓
86 LOF申购 87 LOF赎回
92 新股申购

7.2 prType(报价类型)速查

代码 说明
3 / 11 指定价
5 最新价
42 最优五档即成剩撤(沪市)
43 最优五档即成剩转(沪市)
44 对手最优价(深市)
45 本方最优价(深市)
46 即时成交剩余撤销(深市)
47 最优五档即成剩撤(深市)
48 全额成交或撤(深市)

7.3 quickTrade(快速交易)速查

说明
0 K线走完下单(默认)
1 立即下单
2 立即下单+实时反馈

八、完整策略模板

以下是一个完整的策略模板,涵盖初始化、行情获取、条件判断和下单:

# -*- coding: UTF-8 -*-

def init(ContextInfo):
    """初始化"""
    # 设置账号
    ContextInfo.account = '你的资金账号'
    # 设置股票池
    ContextInfo.stocks = ['600000.SH', '000001.SZ']
    # 设置参数
    ContextInfo.ma_short = 5
    ContextInfo.ma_long = 20
    # 订阅行情
    ContextInfo.subscribe_quote(ContextInfo.stocks)

def handlebar(ContextInfo):
    """主逻辑"""
    # 只在最后一根K线执行(避免重复触发)
    if not ContextInfo.is_last_bar():
        return
    
    # 获取行情
    for stock in ContextInfo.stocks:
        # 获取历史数据计算均线
        df = ContextInfo.get_market_data(
            ['close'], [stock], '1d', count=ContextInfo.ma_long + 1
        )
        if df is None or len(df) < ContextInfo.ma_long:
            continue
        
        closes = df['close'].values
        ma_short = sum(closes[-ContextInfo.ma_short:]) / ContextInfo.ma_short
        ma_long = sum(closes[-ContextInfo.ma_long:]) / ContextInfo.ma_long
        
        # 判断买卖信号
        if ma_short > ma_long and not ContextInfo.has_position(stock):
            # 金叉买入
            passorder(23, 1101, ContextInfo.account, stock, 5, -1, 100,
                     '均线金叉买入', 2, '', ContextInfo)
        elif ma_short < ma_long and ContextInfo.has_position(stock):
            # 死叉卖出
            pos = ContextInfo.get_position(stock)
            if pos and pos['可用数量'] > 0:
                passorder(24, 1101, ContextInfo.account, stock, 5, -1, 
                         pos['可用数量'], '均线死叉卖出', 2, '', ContextInfo)

九、常见问题与注意事项

9.1 策略运行前提

  1. 下载Python库:首次使用需在“模型研究”界面点击下载Python库
  2. 添加资金账号:需在管理端将账号加入白名单
  3. 数据准备:回测前建议先补充历史数据

9.2 常见错误

错误现象 可能原因 解决方法
逆回购报100009错误 代码格式或市场代码错误 确认使用204001.SH格式
passorder无响应 quickTrade未设为2 设置quickTrade=2
账号相关错误 账号未添加或未登录 检查账号管理中的登录状态

9.3 重要提醒

  • 模拟盘先行:正式实盘前,务必在模拟盘充分测试
  • 注意风险:量化交易存在风险,策略需谨慎设计
  • 监控运行:策略启动后应定期检查运行状态和日志输出

本文由 海星量化研究所 作者提供,转载请保留链接和署名!网址:https://qmt.hxquant.com/?id=75

声明

1.本站原创文章,转载需注明文章作者来源。 2.如果文章内容涉及版权问题,请联系我们删除,向本站投稿文章可能会经我们编辑修改。 3.本站对信息准确性或完整性不作保证,亦不对因使用该等信息而引发或可能引发的损失承担任何责任。

搜索
排行榜
关注我们

扫码开通QMT/ptrade