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

qmt 平台如何通过 get_financial_data 获取历史财务报表进行多因子选股?

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

问题描述

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

Title: qmt 财务数据接口进阶:用 get_financial_data 深度选股

Question: qmt 怎么通过 get_financial_data 获取历史财务报表进行多因子选股?

解决方案

qmt 平台如何通过 get_financial_data 获取历史财务报表进行多因子选股?

在量化投资中,基本面分析与多因子选股是构建长期稳健策略的核心。QMT(Quantitative Trading System)平台提供了强大的财务数据接口 ContextInfo.get_financial_data(),支持投资者获取 A 股上市公司的历史财务报表(资产负债表、利润表、现金流量表、主要财务指标等),从而实现深度的基本面多因子选股。


一、get_financial_data 接口详解

QMT 提供了两种调用财务数据的方法,分别适用于多股批量查询单股逐 K 线回测查询

1. 用法一:多股批量时间段查询(推荐用于选股)

ContextInfo.get_financial_data(fieldList, stockList, startDate, endDate, report_type='announce_time')
  • fieldList: 财报字段列表。格式为 表名.字段名,例如 ['ASHAREBALANCESHEET.fix_assets', 'ASHAREINCOME.net_profit_incl_min_int_inc']
  • stockList: 股票代码列表,例如 ['600000.SH', '000001.SZ']
  • startDate / endDate: 开始与结束日期,格式为 'YYYYMMDD'
  • report_type: 报表时间类型。可选 'announce_time'(按公告期,默认)或 'report_time'(按报告期)。
    • 注:按公告期取数能有效避免未来函数。例如,某公司 4 月 26 日发布年报,在 4 月 26 日前获取的数据仍为上一期财报。

2. 用法二:单股单 bar 查询(适用于逐 K 线回测)

ContextInfo.get_financial_data(tabname, colname, market, code, report_type='report_time', barpos)

二、常用财务数据表及字段对照

进行多因子选股时,最常用的财务表和字段如下:

表名 (tabname) 中文字段 国信英文字段 (colname) 选股因子应用
ASHAREBALANCESHEET (资产负债表) 资产总计
固定资产
tot_assets
fix_assets
资产规模因子
ASHAREINCOME (利润表) 净利润
营业收入
net_profit_incl_min_int_inc
revenue_inc
盈利能力与成长因子
ASHARECASHFLOW (现金流量表) 经营活动产生的现金流量净额 net_cash_flows_oper_act 收益质量与现金流因子
CAPITALSTRUCTURE (股本表) 总股本 total_capital 股本规模因子
PERSHAREINDEX (主要指标表) 每股净资产
净资产收益率
s_fa_bps
du_return_on_equity
估值与 ROE 核心因子

三、实战:多因子选股策略 Python 源码

以下是一个完整的 QMT 选股策略示例。该策略在 init 中设定股票池,在 handlebar 中通过 get_financial_data 获取历史财务数据,筛选出 ROE(净资产收益率) > 10%资产负债率 < 60% 的优质股票,并进行等权重买入。

#coding:gbk
import pandas as pd

def init(ContextInfo):
    # 1. 设置基准与股票池(以沪深300成分股为例)
    ContextInfo.benchmark = '000300.SH'
    # 获取沪深300当前成分股
    ContextInfo.universe = ContextInfo.get_stock_list_in_sector('沪深300')
    ContextInfo.set_universe(ContextInfo.universe)
    
    # 设置初始资金与账号
    ContextInfo.capital = 1000000
    ContextInfo.account = '6000000248' # 请替换为您的实际账号
    ContextInfo.set_account(ContextInfo.account)
    
    # 设定选股周期(如每月初运行,这里用定时器或在bar中判断)
    print("策略初始化完成,基础股票池数量:", len(ContextInfo.universe))

def handlebar(ContextInfo):
    # 仅在最后一根 K 线的最后一个 tick 执行选股逻辑,避免历史回测重复计算
    if not ContextInfo.is_last_bar():
        return
        
    print("开始进行基本面多因子选股...")
    
    # 2. 确定查询的时间范围(取最近一期的财务数据)
    # 获取当前 bar 的时间戳并转为日期格式
    bar_time = timetag_to_datetime(ContextInfo.get_bar_timetag(ContextInfo.barpos), '%Y%m%d')
    start_date = str(int(bar_time) - 10000) # 往前推一年,确保能覆盖到最新财报
    end_date = bar_time
    
    # 3. 定义筛选因子字段
    # 净资产收益率 (ROE), 资产负债比率 (Gear Ratio)
    fields = ['PERSHAREINDEX.du_return_on_equity', 'PERSHAREINDEX.gear_ratio']
    stock_list = ContextInfo.universe
    
    # 4. 获取财务数据
    try:
        financial_data = ContextInfo.get_financial_data(fields, stock_list, start_date, end_date, report_type='announce_time')
    except Exception as e:
        print("获取财务数据失败:", e)
        return
        
    # 5. 解析数据并筛选股票
    selected_stocks = []
    
    for stock in stock_list:
        if stock in financial_data:
            df = financial_data[stock]
            if not df.empty:
                # 获取最新的一条财报记录
                latest_record = df.iloc[-1]
                roe = latest_record.get('PERSHAREINDEX.du_return_on_equity', 0)
                gear_ratio = latest_record.get('PERSHAREINDEX.gear_ratio', 100)
                
                # 因子筛选条件:ROE > 10% 且 资产负债率 < 60%
                if roe > 10.0 and gear_ratio < 60.0:
                    selected_stocks.append(stock)
                    
    print(f"筛选完成!符合条件的股票数量: {len(selected_stocks)} / {len(stock_list)}")
    print("选股列表:", selected_stocks)
    
    # 6. 执行交易:等权重配置买入
    if len(selected_stocks) > 0:
        # 先平仓不在选股列表中的持仓
        positions = get_trade_detail_data(ContextInfo.account, 'STOCK', 'POSITION')
        for pos in positions:
            if pos.m_strInstrumentID not in selected_stocks and pos.m_nCanUseVolume > 0:
                order_shares(pos.m_strInstrumentID, -pos.m_nCanUseVolume, 'LATEST', ContextInfo, ContextInfo.account)
                
        # 买入目标股票
        target_percent = 0.95 / len(selected_stocks) # 预留5%资金防滑点
        for stock in selected_stocks:
            order_target_percent(stock, target_percent, 'LATEST', ContextInfo, ContextInfo.account)

四、注意事项与避坑指南

  1. 数据补充: 在运行基本面选股策略前,务必通过 QMT 客户端的 “操作 -> 数据管理 -> 补充数据 -> 财务数据” 下载完整的历史财务数据,否则 get_financial_data 将返回空值。
  2. 未来函数预防: 选股时,report_type 建议使用默认的 'announce_time'(公告日期)。如果使用 'report_time'(报告期),回测时会使用尚未公开的财务数据,导致回测结果失真(即未来函数误差)。
  3. 停牌股处理: 结合 ContextInfo.is_suspended_stock() 剔除停牌股票,避免下单失败。