🚀 AI 一键生成 qmt 策略代码

QMT 策略优化教程:如何利用平台功能进行参数寻优?

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

问题描述

我写好了一个交易策略,但是不知道哪些参数效果最好,如何对策略进行参数优化?

解决方案

在 QMT (Quant Trader) 平台中,对策略进行参数优化(Parameter Optimization)是一个内置的核心功能。它允许你设定参数的变化范围,系统会自动遍历所有组合进行回测,并生成一份绩效对比报告,帮助你找到表现最好的参数组。

以下是在 QMT 中进行参数优化的详细步骤和代码示例:

QMT 参数优化流程

1. 编写策略代码(引用变量)

在 Python 代码中,你不需要硬编码具体的数值(例如 ma_period = 5),而是直接使用变量名。这些变量名稍后将在 QMT 的界面中定义。

示例策略代码:
这是一个简单的双均线策略,我们需要优化快线周期 (fast_period) 和慢线周期 (slow_period)。

# -*- coding: gbk -*-

def init(ContextInfo):
    # 策略初始化
    # 注意:fast_period 和 slow_period 这两个变量不需要在这里定义具体数值
    # 它们将由 QMT 界面上的“参数设置”面板传入
    ContextInfo.set_account('你的资金账号') 
    
def handlebar(ContextInfo):
    # 获取当前主图品种
    stock_code = ContextInfo.stockcode + '.' + ContextInfo.market
    
    # 获取历史行情数据 (使用 get_market_data_ex 接口)
    # 注意:为了计算均线,我们需要获取足够长的数据,这里取 slow_period + 10 条
    # 在实际优化时,slow_period 是动态变化的,这里取一个安全的最大值或动态获取
    # 为演示方便,假设最大周期不超过 60
    data = ContextInfo.get_market_data_ex(
        ['close'], 
        [stock_code], 
        period=ContextInfo.period, 
        count=100, 
        dividend_type='front'
    )
    
    if stock_code not in data:
        return
        
    close_prices = data[stock_code]['close']
    
    if len(close_prices) < slow_period:
        return

    # 计算均线
    # fast_period 和 slow_period 是全局变量,直接使用
    ma_fast = close_prices.rolling(fast_period).mean().iloc[-1]
    ma_slow = close_prices.rolling(slow_period).mean().iloc[-1]
    
    # 获取当前持仓
    positions = ContextInfo.get_trade_detail_data(ContextInfo.accid, 'stock', 'position')
    current_vol = 0
    for pos in positions:
        if pos.m_strInstrumentID == stock_code:
            current_vol = pos.m_nVolume
            break

    # 交易逻辑:金叉买入,死叉卖出
    if ma_fast > ma_slow and current_vol == 0:
        # 全仓买入
        order_target_percent(stock_code, 1.0, "FIX", -1, ContextInfo, ContextInfo.accid)
        print(f"买入: 快线{fast_period} > 慢线{slow_period}")
        
    elif ma_fast < ma_slow and current_vol > 0:
        # 清仓卖出
        order_target_percent(stock_code, 0.0, "FIX", -1, ContextInfo, ContextInfo.accid)
        print(f"卖出: 快线{fast_period} < 慢线{slow_period}")

2. 在界面设置参数范围

编写完代码后,不要直接点击运行,请关注编辑器右侧(或下方)的 【参数设置】 面板。

你需要在这里添加你在代码中使用的变量名,并设置优化的范围:

  1. 参数名:填写代码中的变量名,例如 fast_period
  2. 最新值:这是默认值,用于单次运行或回测。
  3. 最小:优化遍历的起始值(例如 5)。
  4. 最大:优化遍历的结束值(例如 20)。
  5. 步长:每次增加的数值(例如 5)。

设置示例:

参数名 最新值 最小 最大 步长 含义
fast_period 5 5 20 5 将遍历: 5, 10, 15, 20
slow_period 20 30 60 10 将遍历: 30, 40, 50, 60

系统会计算所有组合(笛卡尔积)。在这个例子中,组合数为 4 (fast) * 4 (slow) = 16 种组合。

3. 补充数据

非常重要:在进行优化之前,必须确保本地有足够的数据。

  • 点击客户端顶部的菜单 【数据管理】
  • 选择你需要回测的品种(如沪深300成分股)和周期(如日线)。
  • 下载对应时间段的历史数据。如果不补充数据,回测和优化将无法进行或结果不准确。

4. 运行优化

  1. 在策略编辑器顶部工具栏,找到 【优化】 按钮(通常在【回测】按钮旁边)。
  2. 点击后,系统会弹出一个进度条,开始在后台快速运行这 16 次回测。

5. 分析优化结果

优化完成后,会弹出一个 【评测结果】 窗口(或叫优化报告)。

  • 表格展示:每一行代表一组参数组合(例如 fast=5, slow=30)。
  • 绩效指标:列出该组合对应的 年化收益率夏普比率最大回撤胜率 等。
  • 排序筛选:你可以点击表头,例如点击“夏普比率”,将结果从高到低排序,从而找出风险收益比最好的参数组合。
  • 应用参数:选中你满意的某一行,通常可以右键选择“应用参数”,系统会将这组最优参数填回【参数设置】的“最新值”中。

注意事项

  1. 全局变量机制:QMT 的参数优化机制是将界面上定义的参数名作为 Python 的全局变量注入到策略中。因此,在代码中直接使用变量名即可,无需在 init 中声明 global(读取时)。
  2. 避免过度拟合 (Overfitting)
    • 不要为了追求最高的收益率而选择极其怪异的参数组合。
    • 好的参数通常具有参数平原特征,即最优参数周边的参数表现也应该不错。如果 MA(5, 30) 表现极好,但 MA(5, 29)MA(5, 31) 表现极差,这通常是过拟合,实盘中不可靠。
  3. 计算量控制
    • 组合数量 = 参数A步数 × 参数B步数 × ...
    • 如果参数过多或步长过小,计算量会呈指数级增长,导致优化时间过长。建议先用大步长锁定范围,再用小步长精细搜索。
  4. 数据引用:在 handlebar 中获取数据时,count(获取的数据长度)应确保大于参数的最大值,否则会导致指标计算在某些大参数下因数据不足而返回 NaN

Q&A

Q: 为什么我在代码里写了 fast_period = 10,优化功能就不起作用了?
A: 如果你在代码中显式赋值了 fast_period = 10,那么无论界面上传入什么参数,代码执行时都会被你的赋值语句覆盖。请删除代码中的赋值语句,或者仅在 try...except 块中设置默认值以防本地调试报错,但在 QMT 界面中必须配置同名参数。

Q: 优化结果中的“夏普比率”和“年化收益”哪个更重要?
A: 这取决于你的风险偏好。通常建议优先关注 夏普比率 (Sharpe Ratio)最大回撤 (Max Drawdown)。高收益如果伴随着巨大的回撤(例如腰斩),在实盘中往往难以坚持。夏普比率高意味着单位风险下的收益更高,策略更稳健。

Q: 可以优化止损止盈的比例吗?
A: 可以。只要将止损比例(如 stop_loss_rate)和止盈比例(如 take_profit_rate)作为变量写入代码逻辑,并在参数面板中设置范围(例如 0.05 到 0.15,步长 0.01),即可进行优化。