🚀 AI 一键生成 qmt 策略代码

QMT 策略编辑器中的参数优化功能如何使用?

qmt | 发布时间: 2025/12/17
以下内容由 EasyQuant 生成。

问题描述

我的策略里有很多参数,比如均线周期,怎么能自动测试不同的参数组合,找到效果最好的那一组?

解决方案

在 QMT 平台中,要测试不同的参数组合(如均线周期)以找到最优解,通常不需要编写复杂的循环代码来反复运行回测。QMT 客户端内置了**参数优化(Optimization)**功能,可以直接在界面上设置参数的范围和步长,系统会自动遍历所有组合并给出绩效对比。

以下是实现参数优化的具体步骤和代码示例。

核心步骤

  1. 代码编写:在策略代码的全局位置(通常是文件开头)定义变量,作为你的策略参数。
  2. 界面设置:在 QMT 策略编辑器的右侧或下方的“参数设置”面板中,找到对应的变量名,设置其最小值最大值步长
  3. 运行优化:点击编辑器工具栏上的“优化”按钮(通常在“回测”按钮旁边),系统将自动运行多次回测并生成结果列表。

策略代码示例

下面是一个基于双均线策略的完整代码示例。在这个例子中,SHORT_PERIOD(短期均线)和 LONG_PERIOD(长期均线)就是需要优化的参数。

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

# ==============================================================================
# 策略参数定义 (供参数优化面板调用)
# 在QMT界面的【参数设置】面板中,可以设置这些变量的 最小值、最大值 和 步长
# 例如:SHORT_PERIOD 最小5,最大20,步长5; LONG_PERIOD 最小30,最大60,步长10
# ==============================================================================
SHORT_PERIOD = 5   # 短期均线周期默认值
LONG_PERIOD = 20   # 长期均线周期默认值

def init(ContextInfo):
    # 设置账号 (请替换为您的实际账号)
    ContextInfo.accid = '6000000000'
    ContextInfo.set_account(ContextInfo.accid)
    
    # 设置股票池 (示例使用 沪深300 ETF)
    ContextInfo.set_universe(['510300.SH'])
    
    # 设置回测参数 (仅回测模式有效)
    ContextInfo.set_commission(0, [0.0001, 0.0001, 0.0003, 0.0003, 0, 5]) # 设置费率
    ContextInfo.capital = 1000000 # 初始资金

def handlebar(ContextInfo):
    # 获取当前K线位置
    index = ContextInfo.barpos
    
    # 获取当前图表的股票代码
    stock_code = ContextInfo.get_universe()[0]
    
    # 获取历史行情数据
    # 注意:获取的数据长度要足够计算长期均线,这里取 LONG_PERIOD + 5 根
    # period='1d' 表示日线,根据实际运行周期调整
    data = ContextInfo.get_market_data_ex(
        ['close'], 
        [stock_code], 
        period='1d', 
        count=LONG_PERIOD + 5, 
        dividend_type='front'
    )
    
    # 如果数据获取失败或长度不足,直接返回
    if stock_code not in data or len(data[stock_code]) < LONG_PERIOD:
        return
        
    # 提取收盘价序列
    close_prices = data[stock_code]['close']
    
    # 计算均线
    # 使用 pandas 的 rolling().mean() 计算移动平均
    ma_short = close_prices.rolling(window=SHORT_PERIOD).mean()
    ma_long = close_prices.rolling(window=LONG_PERIOD).mean()
    
    # 获取最新的均线值 (当前K线) 和 上一根K线的均线值
    # iloc[-1] 为最新值,iloc[-2] 为上一个值
    current_short = ma_short.iloc[-1]
    current_long = ma_long.iloc[-1]
    prev_short = ma_short.iloc[-2]
    prev_long = ma_long.iloc[-2]
    
    # 获取当前持仓
    positions = get_trade_detail_data(ContextInfo.accid, 'stock', 'position')
    current_vol = 0
    for pos in positions:
        if pos.m_strInstrumentID + '.' + pos.m_strExchangeID == stock_code:
            current_vol = pos.m_nVolume
            break

    # ==========================================================================
    # 交易逻辑:金叉买入,死叉卖出
    # ==========================================================================
    
    # 金叉:短期均线上穿长期均线
    is_golden_cross = (prev_short <= prev_long) and (current_short > current_long)
    
    # 死叉:短期均线下穿长期均线
    is_death_cross = (prev_short >= prev_long) and (current_short < current_long)
    
    # 执行交易
    if is_golden_cross and current_vol == 0:
        # 全仓买入
        print(f"产生金叉信号: 短期{SHORT_PERIOD} > 长期{LONG_PERIOD},买入")
        order_target_percent(stock_code, 1.0, "fix", close_prices.iloc[-1], ContextInfo, ContextInfo.accid)
        
    elif is_death_cross and current_vol > 0:
        # 清仓卖出
        print(f"产生死叉信号: 短期{SHORT_PERIOD} < 长期{LONG_PERIOD},卖出")
        order_target_percent(stock_code, 0.0, "fix", close_prices.iloc[-1], ContextInfo, ContextInfo.accid)

如何在 QMT 界面操作优化

  1. 保存代码:将上述代码复制到 QMT 的策略编辑器中并保存。
  2. 打开参数面板:在策略编辑器的右侧(或底部,取决于布局),找到**“参数”“参数设置”**标签页。
  3. 识别参数:系统会自动识别代码中的全局变量 SHORT_PERIODLONG_PERIOD 并显示在列表中。
  4. 设置范围
    • 选中 SHORT_PERIOD,设置:
      • 最小:5
      • 最大:15
      • 步长:5
      • (这意味着系统会测试 5, 10, 15 三种情况)
    • 选中 LONG_PERIOD,设置:
      • 最小:20
      • 最大:60
      • 步长:20
      • (这意味着系统会测试 20, 40, 60 三种情况)
  5. 运行优化
    • 点击工具栏上的**“优化”**按钮(注意不是“回测”)。
    • 系统会遍历所有组合(例如 3x3=9 种组合)。
  6. 查看结果
    • 优化完成后,会弹出一个结果列表,显示每一组参数对应的年化收益率夏普比率最大回撤等指标。
    • 你可以点击表头(如“年化收益率”)进行排序,从而找到表现最好的一组参数。

Q&A

Q: 为什么我在参数面板里看不到我的变量?
A: 确保变量是在函数外部(全局作用域)定义的,并且赋了初始值(如 MA = 5)。如果变量定义在 inithandlebar 函数内部,QMT 无法将其识别为可调节参数。

Q: 步长(Step)是什么意思?
A: 步长决定了参数遍历的密度。例如范围是 10 到 20,步长为 2,则测试的参数为 10, 12, 14, 16, 18, 20。步长越小,测试的组合越多,计算时间越长。

Q: 优化结果中的“夏普比率”高好还是低好?
A: 夏普比率(Sharpe Ratio)越高越好。它代表了策略在承担单位风险下获得的超额回报。通常在选择参数时,不仅要看收益率,还要看夏普比率和最大回撤,以防止过拟合。