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

QMT平台如何通过get_financial_data接口获取财务数据并构建杜邦分析选股模型?

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

问题描述

qmt 基本面选股:使用 get_financial_data 构建杜邦分析打分模型
如何通过 qmt 的 get_financial_data 接口获取净利润和总资产,并计算 ROE 建立杜邦选股模型?

解决方案

QMT基本面选股:使用get_financial_data构建杜邦分析打分模型

在量化投资中,基本面选股是构建长期稳健策略的重要基石。杜邦分析法(DuPont Analysis)通过将净资产收益率(ROE)拆解为产品净利率资产周转率权益乘数,能全面评估企业的盈利能力、营运能力和财务杠杆。

本文将指导您如何使用国信证券 QMT (Quantitative Trading System) Python API 中的 get_financial_data 接口获取核心财务数据,并构建一个简单的杜邦分析选股打分模型。


1. 核心财务指标与QMT字段对照

根据QMT API文档,我们需要从不同的财务报表中获取以下字段:

指标名称 英文表名.字段名 对应报表 说明
净利润 ASHAREINCOME.net_profit_incl_min_int_inc 利润表 包含少数股东损益的净利润
资产总计 ASHAREBALANCESHEET.tot_assets 资产负债表 期末总资产
所有者权益合计 ASHAREBALANCESHEET.total_equity 资产负债表 净资产
营业收入 ASHAREINCOME.revenue_inc 利润表 营业收入

2. QMT 财务数据获取接口介绍

QMT 提供了 ContextInfo.get_financial_data 接口,支持按**报告期(report_time)公告期(announce_time)**获取历史财务数据。

接口原型

ContextInfo.get_financial_data(fieldList, stockList, startDate, endDate, report_type='announce_time')
  • fieldList: 财报字段列表,格式为 表名.字段名
  • stockList: 股票代码列表,如 ['600000.SH', '000001.SZ']
  • startDate / endDate: 开始与结束日期,格式如 '20230101'
  • report_type: 默认为 'announce_time'(按公告期,避免未来函数),选股模型中推荐使用。

3. 杜邦分析选股模型 Python 源码

以下是一个完整的QMT策略示例。该模型在初始化时设定股票池,在 handlebar 中获取最新的财务数据,计算杜邦三因子并进行打分排序,最终筛选出综合得分最高的股票。

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

def init(ContextInfo):
    # 1. 设定股票池(以沪深300部分成分股为例)
    ContextInfo.stock_list = ['600000.SH', '600036.SH', '600276.SH', '601318.SH', '000001.SZ', '000333.SZ', '000858.SZ', '002594.SZ']
    ContextInfo.set_universe(ContextInfo.stock_list)
    
    # 2. 设定选股参数
    ContextInfo.start_date = '20230101'
    ContextInfo.end_date = '20231231'

def handlebar(ContextInfo):
    # 仅在最后一根Bar运行选股逻辑
    if not ContextInfo.is_last_bar():
        return
        
    # 定义需要获取的财务字段
    fields = [
        'ASHAREINCOME.net_profit_incl_min_int_inc', # 净利润
        'ASHAREBALANCESHEET.tot_assets',            # 总资产
        'ASHAREBALANCESHEET.total_equity',          # 净资产
        'ASHAREINCOME.revenue_inc'                  # 营业收入
    ]
    
    # 获取财务数据 (返回 Panel 或 Dict 结构)
    print("正在获取财务数据...")
    fin_data = ContextInfo.get_financial_data(
        fields, 
        ContextInfo.stock_list, 
        ContextInfo.start_date, 
        ContextInfo.end_date, 
        report_type='announce_time'
    )
    
    # 存储每只股票的杜邦指标
    dupont_results = []
    
    for stock in ContextInfo.stock_list:
        try:
            # 提取单只股票的财务DataFrame
            df = fin_data[stock] if isinstance(fin_data, dict) else fin_data.major_xs(stock)
            if df.empty:
                continue
            
            # 取最新一个报告期的数据
            latest_data = df.iloc[-1]
            
            net_profit = latest_data['ASHAREINCOME.net_profit_incl_min_int_inc']
            total_assets = latest_data['ASHAREBALANCESHEET.tot_assets']
            total_equity = latest_data['ASHAREBALANCESHEET.total_equity']
            revenue = latest_data['ASHAREINCOME.revenue_inc']
            
            # 杜邦公式拆解计算
            # 1. 净资产收益率 ROE = 净利润 / 净资产
            roe = net_profit / total_equity if total_equity > 0 else 0
            # 2. 销售净利率 = 净利润 / 营业收入
            net_profit_margin = net_profit / revenue if revenue > 0 else 0
            # 3. 资产周转率 = 营业收入 / 总资产
            asset_turnover = revenue / total_assets if total_assets > 0 else 0
            # 4. 权益乘数 = 总资产 / 净资产
            equity_multiplier = total_assets / total_equity if total_equity > 0 else 0
            
            dupont_results.append({
                'stock': stock,
                'ROE': roe,
                'Margin': net_profit_margin,
                'Turnover': asset_turnover,
                'Leverage': equity_multiplier
            })
        except Exception as e:
            print("获取股票 %s 财务数据失败: %s" % (stock, str(e)))
            
    # 构建分析表格
    result_df = pd.DataFrame(dupont_results)
    if result_df.empty:
        print("未获取到有效财务数据")
        return
        
    # 4. 杜邦打分模型:对各项指标进行百分比排名打分
    result_df['score_roe'] = result_df['ROE'].rank(pct=True)
    result_df['score_margin'] = result_df['Margin'].rank(pct=True)
    result_df['score_turnover'] = result_df['Turnover'].rank(pct=True)
    
    # 财务杠杆(权益乘数)并非越高越好,这里给予适度权重或不纳入高分项,此处主要以盈利和营运效率为主
    result_df['total_score'] = result_df['score_roe'] * 0.4 + result_df['score_margin'] * 0.3 + result_df['score_turnover'] * 0.3
    
    # 排序并输出前3名优质基本面股票
    selected_stocks = result_df.sort_values(by='total_score', ascending=False).head(3)
    
    print("\n====== 杜邦分析选股打分结果 ======")
    print(selected_stocks[['stock', 'ROE', 'Margin', 'Turnover', 'total_score']])

4. 策略避坑指南(量化细节)

  1. 未来函数预防: 在调用 get_financial_data 时,参数 report_type 务必设为 'announce_time'(公告日期)。如果设为 'report_time'(报告期),在回测时会提前使用尚未公布的财报数据,导致回测业绩虚高。
  2. 停牌与缺失值处理: 部分股票可能因未及时披露财报导致数据缺失,代码中加入了 try...except 异常捕获,确保单只股票数据异常不影响整个选股模型的运行。
  3. 行业中性化: 杜邦指标(如资产周转率、权益乘数)在不同行业间差异极大(例如重资产的钢铁行业与轻资产的软件行业)。在实际实盘中,建议配合 get_industry_name_of_stock 接口,在同行业内部进行打分排序。