🚀 AI 一键生成 qmt 策略代码

QMT API 教程:如何获取引用因子在全市场的排名数值?

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

问题描述

如何获取某个因子在所有股票中的排名?

解决方案

在 QMT (Quantitative Trading Platform) 中,获取某个因子在所有股票中的排名,主要有两种方式:

  1. 使用 API 直接获取(针对引用数据): 如果是系统内置的引用因子或扩展数据,可以使用 get_factor_rankext_data_rank
  2. 使用 Pandas 进行计算(推荐,更灵活): 获取所有股票的因子值,然后利用 Python 的 pandas 库进行排序和排名。这是量化策略中最常用的方法,因为它适用于任何自定义计算的因子。

以下是详细的说明和代码实现。

方法一:使用 Pandas 计算排名(推荐)

这种方法最通用。逻辑是:获取股票池 -> 获取因子数据 -> 转换为 DataFrame -> 使用 rank() 函数排名。

策略代码示例

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

def init(ContextInfo):
    # 1. 设置股票池,这里以沪深300为例,如果需要全市场,可使用 '沪深A股'
    # 注意:全市场股票数量较多,获取数据和计算耗时会增加
    ContextInfo.index_code = '000300.SH'
    ContextInfo.stock_list = ContextInfo.get_stock_list_in_sector('沪深300')
    print(f"股票池数量: {len(ContextInfo.stock_list)}")

def handlebar(ContextInfo):
    # 仅在最后一根K线运行,避免回测时每个bar都打印大量日志
    if not ContextInfo.is_last_bar():
        return

    # 2. 获取当前时间
    timetag = ContextInfo.get_bar_timetag(ContextInfo.barpos)
    date_str = timetag_to_datetime(timetag, '%Y%m%d')
    
    # 3. 定义要获取的因子
    # 这里以 "市盈率(PE)" 为例,因子库表名为 Valuation_and_Market_Cap
    factor_name = 'Valuation_and_Market_Cap.PE'
    field_list = [factor_name]
    
    # 4. 获取因子数据
    # 参数:字段列表, 股票列表, 开始时间, 结束时间
    # 当股票列表为多个,时间为1个点时,返回 DataFrame (index=代码, columns=字段)
    df_factor = ContextInfo.get_factor_data(field_list, ContextInfo.stock_list, date_str, date_str)
    
    # 检查数据是否为空
    if df_factor.empty:
        print(f"{date_str} 无因子数据")
        return

    # 5. 数据清洗与排名
    # 剔除空值 (NaN)
    df_factor.dropna(inplace=True)
    
    # 使用 pandas 的 rank 函数进行排名
    # ascending=True 表示升序(数值越小排名越靠前),False 表示降序
    # method='min' 表示如果有相同数值,取最小排名
    df_factor['rank_asc'] = df_factor[factor_name].rank(ascending=True, method='min')
    
    # 6. 打印结果
    print(f"--- {date_str} 因子排名示例 (PE 最小的前10名) ---")
    # 按排名排序并取前10
    top_10 = df_factor.sort_values('rank_asc').head(10)
    print(top_10)
    
    # 如果你想获取某只特定股票的排名,可以直接索引
    target_stock = '600000.SH'
    if target_stock in df_factor.index:
        rank = df_factor.loc[target_stock, 'rank_asc']
        val = df_factor.loc[target_stock, factor_name]
        print(f"股票 {target_stock} 的 PE 为 {val}, 排名为: {rank}")

方法二:使用 API 获取引用数据的排名

如果你使用的是通过“扩展数据”功能导入的数据,或者特定的引用因子,可以使用以下 API。这种方法通常用于获取单只股票的排名数值,若要获取全市场列表,仍需循环调用(效率较低)。

1. get_factor_rank (获取引用因子排名)

用于获取引用的因子数据在所有品种中的排名。

  • 用法: get_factor_rank(factorname, stockcode, deviation, ContextInfo)
  • 参数:
    • factorname: 因子名
    • stockcode: 股票代码
    • deviation: K线偏移(0为当前)

2. ext_data_rank (获取扩展数据排名)

用于获取用户自定义并导入的“扩展数据”的排名。

  • 用法: ext_data_rank(extdataname, stockcode, deviation, ContextInfo)
  • 参数:
    • extdataname: 扩展数据名称(在QMT客户端数据管理中定义的名称)
    • stockcode: 股票代码

代码片段示例:

# -*- coding: gbk -*-
def handlebar(ContextInfo):
    # 获取浦发银行在 'my_custom_factor' 这个扩展数据中的排名
    # 注意:前提是你已经在QMT客户端建立了名为 'my_custom_factor' 的扩展数据
    rank = ext_data_rank('my_custom_factor', '600000.SH', 0, ContextInfo)
    print(f"600000.SH 排名: {rank}")

总结

需求场景 推荐方法 优势
策略开发、选股 方法一 (Pandas) 速度快(向量化计算),灵活性高,可同时处理排序、筛选、分层。
简单指标引用 方法二 (API) 代码简短,直接获取单只股票结果。

Q&A

Q: get_factor_data 返回的数据格式是什么?
A: 当传入多个股票代码和单个时间点时,它返回一个 pandas.DataFrame,索引(Index)是股票代码,列(Columns)是因子名称。这非常适合直接进行 rank 操作。

Q: 如何处理因子数据中的 NaN (空值)?
A: 在排名之前,务必使用 df.dropna() 去除空值,或者使用 df.fillna() 填充默认值。否则 rank 函数可能会对 NaN 进行不符合预期的排序(默认 NaN 不参与排名或排在最后)。

Q: 如何实现行业内排名?
A: 可以先获取股票的行业分类数据,将其合并到 DataFrame 中,然后使用 df.groupby('行业')['因子'].rank() 进行分组排名。