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

QMT 平台如何使用 ext_data_rank 构建截面多因子打分策略?(附 Python 代码)

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

问题描述

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

Title: QMT 扩展数据应用:结合 ext_data_rank 构建截面多因子打分模型

Question: 如何利用 QMT 的 ext_data_rank 函数对全市场股票的自定义指标进行截面排名打分?

解决方案

QMT 扩展数据应用:结合 ext_data_rank 构建截面多因子打分模型

在量化多因子选股策略中,**截面排名(Cross-Sectional Ranking)**是评估全市场股票相对优劣的常用手段。QMT(迅投/国信 QMT)提供了强大的扩展数据引用接口,允许开发者通过预先计算或导入自定义技术指标/因子,并在运行期实现全市场股票的快速排名。


一、核心 API 接口解析

QMT 提供了两个关键函数来处理扩展数据及其截面排名:

1. ext_data

  • 用法ext_data(extdataname, stockcode, deviation, ContextInfo)
  • 释义:获取指定股票在当前 Bar 或偏移 Bar 上的扩展数据数值。
  • 参数
    • extdataname (string):客户端中定义的扩展数据名称。
    • stockcode (string):股票代码(格式如 '600000.SH')。
    • deviation (number):K线偏移量(0 表示当前 Bar,-1 表示上一 Bar)。
    • ContextInfo:策略全局上下文环境对象。

2. ext_data_rank

  • 用法ext_data_rank(extdataname, stockcode, deviation, ContextInfo)
  • 释义:获取引用的扩展数据数值在全市场所有品种中的截面排名
  • 返回值:number(排名序号,数值越小代表排名越靠前)。

二、实现截面多因子打分的步骤

  1. 定义扩展数据:在 QMT 客户端的扩展数据管理中添加自定义指标(例如名为 'mycci''my_factor' 的扩展数据)。
  2. 设置股票池:在策略的 init 函数中,通过 ContextInfo.set_universe() 设定全市场或目标板块的股票池。
  3. 截面排名与打分:在 handlebar 遍历股票池,调用 ext_data_rank 获取每只股票的截面排名,并计算多因子综合打分。
  4. 调仓交易:对多因子总分进行排序,挑选Top股票进行买入。

三、策略示例代码

以下示例展示了如何在 QMT 中结合扩展数据排名接口 ext_data_rank 提取因子排名,并根据排名构建截面打分选股逻辑:

#coding:gbk

def init(ContextInfo):
    # 1. 设定选股股票池(例如沪深300)
    stock_list = ContextInfo.get_stock_list_in_sector('沪深300')
    ContextInfo.set_universe(stock_list)
    
    # 2. 绑定资金账号
    ContextInfo.account_id = '6000000248'
    ContextInfo.set_account(ContextInfo.account_id)
    
    # 设置调仓持仓数
    ContextInfo.top_n = 10

def handlebar(ContextInfo):
    # 仅在最新 K 线执行打分与调仓
    if not ContextInfo.is_last_bar():
        return
        
    universe = ContextInfo.get_universe()
    factor_scores = {}
    
    # 遍历股票池,获取扩展数据截面排名并打分
    for stock in universe:
        # 获取扩展数据排名 (假设扩展数据名为 'mycci')
        rank = ext_data_rank('mycci', stock, 0, ContextInfo)
        
        # 若排名有效(大于0),进行记录(排名越小,得分越高)
        if rank > 0:
            factor_scores[stock] = rank
            
    if not factor_scores:
        print("未能获取到有效的扩展数据排名")
        return
        
    # 根据排名升序排序,取排名最靠前的前 Top N 股票
    sorted_stocks = sorted(factor_scores.items(), key=lambda x: x[1])
    target_stocks = [stk for stk, r in sorted_stocks[:ContextInfo.top_n]]
    
    print(f"截面打分选出的目标股票: {target_stocks}")
    
    # 简单调仓示例:使用 order_target_percent 调整至目标比例
    weight = 1.0 / ContextInfo.top_n
    for stock in target_stocks:
        order_target_percent(stock, weight, 'LATEST', 0, ContextInfo, ContextInfo.account_id)

四、注意事项与最佳实践

  1. 扩展数据补充:在使用 ext_dataext_data_rank 前,需确保客户端中的扩展数据已经计算并补充了最新的历史数据。
  2. 偏差与偏移量(deviation):实时交易时偏移量通常设为 0;若需防范未来函数或在历史 Bar 上回测,建议设为 -1 获取前一收盘周期的计算值。
  3. 全市场排名计算量ext_data_rank 会计算全市场的截面排名,为了提高运行效率,建议放在 ContextInfo.is_last_bar() 判定内或配合定时器 run_time 触发。