3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在基本面量化投资中,扣除非经常性损益后的净利润(扣非净利润)能够比普通净利润更真实地反映公司主营业务的盈利能力与持续成长性。QMT 平台提供了丰富的财务数据接口,支持投资者便捷地提取和计算财务指标。
获取财务数据的主要函数为 ContextInfo.get_financial_data()。针对利润表(ASHAREINCOME)中的相关数据,其调用方法如下:
ContextInfo.get_financial_data(fieldList, stockList, startDate, endDate, report_type='report_time')
表名.字段名。例如:ASHAREINCOME.net_profit_excl_min_int_inc(归属母公司所有者的净利润)或使用相关财务指标表 PERSHAREINDEX.adjusted_net_profit(扣非净利润)。['600000.SH', '000001.SZ']。'YYYYMMDD' 的开始与结束日期。'announce_time'(按公告期),若需按实际报告期计算,可指定为 'report_time'。get_financial_data 提取连续几期报告期的扣非净利润数据。#coding:gbk
import pandas as pd
def init(ContextInfo):
# 设定基准与交易参数
ContextInfo.start = '2023-01-01'
ContextInfo.end = '2023-12-31'
# 获取沪深300成分股作为选股池
ContextInfo.stocks = ContextInfo.get_stock_list_in_sector('沪深300')
ContextInfo.set_universe(ContextInfo.stocks)
print("初始化完成,初始股票池数量:", len(ContextInfo.stocks))
def handlebar(ContextInfo):
# 仅在最后一个 bar 执行策略计算
if not ContextInfo.is_last_bar():
return
print("开始进行扣非净利润高增长股票筛选...")
# 定义需要提取的字段:PERSHAREINDEX 表中的扣非净利润 adjusted_net_profit
field_list = ['PERSHAREINDEX.adjusted_net_profit']
stock_list = ContextInfo.stocks
# 设置对比时间范围(获取近两年数据进行同比分析)
start_date = '20211231'
end_date = '20230930'
# 获取财务数据,按报告期取数
financial_df = ContextInfo.get_financial_data(
field_list,
stock_list,
start_date,
end_date,
report_type='report_time'
)
selected_stocks = []
# 遍历每只股票计算扣非净利润增长
if isinstance(financial_df, dict):
for stock in stock_list:
if stock in financial_df:
df = financial_df[stock]
# 确保获取到了足够的财务数据期数
if df is not None and len(df) >= 2:
# 获取最近两期的扣非净利润
latest_profit = df['PERSHAREINDEX.adjusted_net_profit'].iloc[-1]
prev_profit = df['PERSHAREINDEX.adjusted_net_profit'].iloc[-2]
# 筛选逻辑:前期利润大于0,且同比增幅超过 15%
if prev_profit > 0 and (latest_profit - prev_profit) / prev_profit > 0.15:
selected_stocks.append(stock)
print(f"筛选完成,符合连续扣非净利润高增长的股票共 {len(selected_stocks)} 只:")
print(selected_stocks)
# 重新设定选股后的股票池
ContextInfo.set_universe(selected_stocks)
report_type 设为 'announce_time'(公告日),以防使用未披露的财报数据造成未来函数偏差。get_financial_data 返回的数据结构(Series, DataFrame, Dict/Panel)会有所不同,编写代码时需做好类型校验。