🚀 AI 一键生成 qmt 策略代码

QMT模型不交易怎么办?公式语言转Python策略指南

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

问题描述

为什么我这个模型不交易,请哪位高手能指出问题吗

VARIABLE:cj1=0,hszhishu=0,BBD=0,zhishu=0,tmp=0,tmpshort=0,buypoint=0,sellpoint=0,

profit=0,TestHolding=0,maxzhishu=0,huiche=0,maxhuiche=0,DCS=0,maxprofit=0,

maxDhuiche=0,Dhuiche=0,maxshortprofit=0,hs300bp=0,hstmp=0,TMPzhishu=0;

ORDERTYPE := 1101; // QMT 限价单类型

ACCOUNTID := '580000'; // 实际资金账号

ORDERCODE := STKLABEL(); // 当前标的代码

VOLUME := 5000; // 委托股数

limit_price := ((C-REF(C,1))/REF(C,1))=0.09; // 计算精确涨停价

// MACD 指标计算

DIFF := EMA(CLOSE,12) - EMA(CLOSE,26);

DEA := EMA(DIFF,9);

MACD1 := 2*(DIFF-DEA);

// 修正后的开仓条件

zt_price := ((C-REF(C,1))/REF(C,1))>=0.09; // 精确涨停价

volume_ratio := DYNAINFO(25)/vol; // QMT 量比参数为 17

bk := MACD1 > REF(MACD1,1)

AND REF(MACD1,1) > REF(MACD1,2) // MACD连续两日上升

AND volume\_ratio > 1 // 量比大于1

AND zt\_price // 当前是涨停状态

AND NOT(REF(zt\_price,1)) // 前一日未涨停

AND TIME >= 093000 AND TIME <= 205900 // 交易时间控制

AND TestHolding = 0; // 无现存持仓

// QMT 下单逻辑

IF bk THEN BEGIN;

TestHolding := 1; // 更新持仓状态

groupbuy(VOLUME);

END;

解决方案

QMT 模型不交易的核心原因分析

您提供的代码是一段典型的麦语言/VBA指标公式代码,而在 QMT(迅投极速量化交易平台)中,实现自动化交易和复杂策略回测的核心引擎是基于 Python 语言的。您的模型不交易,主要有以下几个致命问题:

1. 缺少 Python 策略的核心框架

根据 QMT API 文档,一个合法的 Python 策略必须包含两个核心函数:

  • init(ContextInfo):初始化函数,在策略启动时运行一次,用于设置账号、股票池等。
  • handlebar(ContextInfo):行情驱动函数,每根 K 线(或每个 Tick)运行一次,核心逻辑必须写在这里。
    您的代码完全没有这个框架,平台无法识别并执行。

2. 下单函数使用错误

代码中使用了 groupbuy(VOLUME); 进行下单。在 QMT Python API 中,标准的下单函数是 passorder(综合下单)或 order_lotsorder_value 等。QMT 并不识别 groupbuy 这个指令。

3. 数据获取与指标计算方式不兼容

在公式语言中,您可以直接使用 C 代表收盘价,REF(C,1) 代表昨日收盘价,MACD 可以直接调用。但在 QMT Python 环境中,您需要使用 ContextInfo.get_market_data()ContextInfo.get_history_data() 来获取历史数据,并使用 Python 库(如 pandastalib)来计算 MACD 指标。


如何将您的逻辑转换为 QMT Python 策略

为了让您的策略在 QMT 中正常运行,我们需要将您的逻辑(MACD连续两日上升 + 量比大于1 + 今日涨停且昨日未涨停)用 Python 重写。以下是一个基础的转换示例框架:

#coding:gbk
import pandas as pd
import numpy as np

def init(ContextInfo):
    # 设置交易账号
    ContextInfo.accountID = '580000'
    ContextInfo.set_account(ContextInfo.accountID)
    # 设置运行的股票池(以平安银行为例)
    ContextInfo.set_universe(['000001.SZ'])
    # 初始化持仓标记
    ContextInfo.TestHolding = 0

def handlebar(ContextInfo):
    # 获取当前运行的股票代码
    stock_code = ContextInfo.stockcode
    
    # 获取过去35天的日线数据(用于计算MACD)
    df = ContextInfo.get_market_data(['close', 'volume'], stock_code=[stock_code], period='1d', count=35)
    if df.empty or len(df) < 30:
        return
        
    close_prices = df['close']
    
    # 1. 计算 MACD (简易计算示例,实际建议引入 TA-Lib)
    exp1 = close_prices.ewm(span=12, adjust=False).mean()
    exp2 = close_prices.ewm(span=26, adjust=False).mean()
    macd_diff = exp1 - exp2
    macd_dea = macd_diff.ewm(span=9, adjust=False).mean()
    macd_hist = (macd_diff - macd_dea) * 2
    
    # 获取近三天的 MACD 柱
    macd_today = macd_hist.iloc[-1]
    macd_yest = macd_hist.iloc[-2]
    macd_yest2 = macd_hist.iloc[-3]
    
    # 2. 判断涨停逻辑 (简易判断:今日涨幅>=9.5%,昨日涨幅<9.5%)
    close_today = close_prices.iloc[-1]
    close_yest = close_prices.iloc[-2]
    close_yest2 = close_prices.iloc[-3]
    
    pct_today = (close_today - close_yest) / close_yest
    pct_yest = (close_yest - close_yest2) / close_yest2
    
    is_zt_today = pct_today >= 0.095
    is_zt_yest = pct_yest >= 0.095
    
    # 3. 获取量比 (此处用简易逻辑替代:今日成交量 / 过去5日均量)
    vol_today = df['volume'].iloc[-1]
    vol_ma5 = df['volume'].iloc[-6:-1].mean()
    volume_ratio = vol_today / vol_ma5 if vol_ma5 > 0 else 0
    
    # 4. 综合条件判断
    bk = (macd_today > macd_yest) and (macd_yest > macd_yest2) \
         and (volume_ratio > 1) \
         and is_zt_today \
         and not is_zt_yest \
         and ContextInfo.TestHolding == 0
         
    # 5. 执行下单
    if bk:
        # 使用 passorder 下单:23代表股票买入,1101代表单股单账号普通下单,11代表指定价
        passorder(23, 1101, ContextInfo.accountID, stock_code, 11, close_today, 5000, 'MyStrategy', 1, 'BuySignal', ContextInfo)
        ContextInfo.TestHolding = 1
        print(f"{stock_code} 触发买入信号,已发送委托!")

关键修改点说明:

  1. 引入 inithandlebar:这是 QMT 策略运行的基石。
  2. 数据获取:使用 ContextInfo.get_market_data 获取历史 K 线数据,返回的是 pandas.DataFrame 格式,方便进行向量化计算。
  3. 下单函数:替换为 QMT 标准的 passorder 函数。参数 23 表示股票买入,1101 表示普通股/手方式下单。
  4. 全局变量:将 TestHolding 等状态变量挂载到 ContextInfo 对象上,以便在不同的 K 线周期之间传递状态。

建议您在 QMT 的“策略编辑器”中新建一个 Python 模型,将上述代码粘贴进去,并在历史回测中进行调试,查看日志输出(print)以验证逻辑是否按预期触发。