🚀 AI 一键生成 qmt 策略代码

QMT 平台财务数据不准确及未来时间异常的解决方法

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

问题描述

download_financial_data2

download_financial_data2 下载的有些数据不准确如下:

000657.SZ Income 转换后的数据:
[{'m_anntime': '20250827', 'm_timetag': '20250630', 'oper_profit': 669710518.64}, {'m_anntime': '20240823', 'm_timetag': '20240630', 'oper_profit': 200754552.18}, {'m_anntime': '20250827', 'm_timetag': '20240630', 'oper_profit': 572782264.69}]

解决方案

问题分析

在使用 QMT 获取财务数据时,遇到如 000657.SZ 利润表数据中出现未来时间(如 20250827)以及同一报告期(20240630)存在多条数据的情况,通常是由以下两个原因造成的:

  1. 未来时间异常:底层数据源可能提前录入了上市公司的预约披露时间业绩预告,或者是数据供应商端产生的脏数据
  2. 同一报告期多条数据:上市公司在发布财报后,经常会因为会计准则变更或审计发现问题而发布财务重述(修正)公告。因此,同一个报告期(m_timetag)会对应多个不同的公告日(m_anntime),这在量化财务数据中属于正常现象。

解决方案

为了在策略中准确使用财务数据,建议在获取数据后进行数据清洗,主要包括剔除未来数据保留最新公告数据

1. 重新补充本地数据

首先,建议在 QMT 客户端的【数据管理】->【补充数据】中,重新勾选并下载最新的财务数据。这可以修复部分由于本地数据未同步导致的脏数据问题。

2. 代码层面的数据清洗逻辑

在策略代码中,对获取到的财务数据列表进行以下处理:

  • 过滤未来数据:剔除 m_anntime 大于当前真实日期的记录。
  • 去重并保留最新:按照报告期 m_timetag 进行分组,如果同一报告期有多条记录,保留公告日 m_anntime 最大(最新)的一条。

3. Python 处理代码示例

以下是一个通用的 Python 数据清洗函数示例,适用于处理此类财务数据列表:

import datetime
import pandas as pd

def clean_financial_data(raw_data):
    if not raw_data:
        return []
    
    # 获取当前日期字符串,例如 '20231025'
    current_date = datetime.datetime.now().strftime('%Y%m%d')
    
    # 1. 过滤掉公告日大于当前日期的未来数据
    valid_data = [d for d in raw_data if d.get('m_anntime', '99999999') <= current_date]
    
    if not valid_data:
        return []
        
    # 2. 转换为 DataFrame 方便处理
    df = pd.DataFrame(valid_data)
    
    # 3. 按报告期(m_timetag)排序,并按公告日(m_anntime)升序排列
    df = df.sort_values(by=['m_timetag', 'm_anntime'])
    
    # 4. 去重:同一报告期只保留最后一次公告的数据(即修正后的最终数据)
    df_cleaned = df.drop_duplicates(subset=['m_timetag'], keep='last')
    
    # 转换回字典列表
    return df_cleaned.to_dict('records')

# 测试用户提供的数据
raw_data = [
    {'m_anntime': '20250827', 'm_timetag': '20250630', 'oper_profit': 669710518.64}, 
    {'m_anntime': '20240823', 'm_timetag': '20240630', 'oper_profit': 200754552.18}, 
    {'m_anntime': '20250827', 'm_timetag': '20240630', 'oper_profit': 572782264.69}
]

cleaned_data = clean_financial_data(raw_data)
print("清洗后的数据:", cleaned_data)

4. 使用 QMT 官方 API 的建议

在 QMT 策略中,建议直接使用官方提供的 ContextInfo.get_financial_data 接口,并合理利用 report_type 参数:

  • report_type='announce_time':按公告期取数,严格避免未来函数,适合回测。
  • report_type='report_time':按报告期取数,适合截面分析。
def handlebar(ContextInfo):
    # 示例:获取净利润,按报告期取数
    fieldList = ['ASHAREINCOME.net_profit_incl_min_int_inc']
    stockList = ['000657.SZ']
    # 确保传入的时间范围是合理的历史时间
    df = ContextInfo.get_financial_data(fieldList, stockList, '20230101', '20231231', report_type='report_time')