3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化选股体系中,基本面因子(如 ROE、市盈率 PE、净利润增长率等)是构建阿尔法策略的核心。评估因子有效性的标准指标是 信息系数(Information Coefficient, IC) 与 秩信息系数(Rank-IC)。同时,通过 QMT 的 get_financial_data 接口,我们可以高效获取历史财务数据并构建多因子组合。
QMT 提供了 get_financial_data 函数来拉取财务报表及指标数据:
# 示例:拉取净资产收益率与净利润
fieldList = ['PERSHAREINDEX.s_fa_roe', 'ASHAREINCOME.net_profit_incl_min_int_inc']
stockList = ['600000.SH', '000001.SZ']
startDate = '20230101'
endDate = '20231231'
df_finance = ContextInfo.get_financial_data(fieldList, stockList, startDate, endDate, report_type='announce_time')
以下示例展示如何在 QMT 策略中提取选股池股票的基本面因子,计算因子与收益的相关性并进行打分选股:
#encoding:gbk
import pandas as pd
import numpy as np
from scipy.stats import spearmanr, pearsonr
def init(ContextInfo):
# 1. 设置股票池(以沪深300成份股为例)
ContextInfo.stock_pool = ContextInfo.get_stock_list_in_sector('沪深300')
ContextInfo.set_universe(ContextInfo.stock_pool)
ContextInfo.set_account('6000000001')
# 2. 定期调仓标记
ContextInfo.trade_bar = 0
ContextInfo.hold_count = 10 # 持仓10只股票
def handlebar(ContextInfo):
# 每20个Bar(如日线20个交易日)进行一次因子评估与重新调仓
if ContextInfo.trade_bar % 20 != 0:
ContextInfo.trade_bar += 1
return
ContextInfo.trade_bar += 1
stocks = ContextInfo.get_universe()
if not stocks:
return
# 1. 获取行情数据计算未来收益率
close_data = ContextInfo.get_market_data(['close'], stock_code=stocks, period='1d', count=21)
if close_data.empty:
return
# 计算近20日收益率作为收益率响应标的
returns = (close_data['close'].iloc[-1] - close_data['close'].iloc[0]) / close_data['close'].iloc[0]
# 2. 获取基本面因子数据(例如:ROE 与 每股收益 EPS)
# 字段格式:表名.字段名
fields = ['PERSHAREINDEX.s_fa_roe', 'PERSHAREINDEX.s_fa_eps_basic']
end_date = ContextInfo.get_bar_timetag(ContextInfo.barpos)
# 转换时间格式为 YYYYMMDD
str_end_date = timetag_to_datetime(end_date, '%Y%m%d')
str_start_date = timetag_to_datetime(end_date - 30 * 86400 * 1000, '%Y%m%d')
try:
fin_df = ContextInfo.get_financial_data(fields, stocks, str_start_date, str_end_date)
except Exception as e:
print("获取财务数据失败:", e)
return
# 提取最新的基本面因子截面数据
factor_roe = {}
factor_eps = {}
for stk in stocks:
if stk in fin_df:
df_stk = fin_df[stk]
if 'PERSHAREINDEX.s_fa_roe' in df_stk.columns and not df_stk.empty:
factor_roe[stk] = df_stk['PERSHAREINDEX.s_fa_roe'].iloc[-1]
if 'PERSHAREINDEX.s_fa_eps_basic' in df_stk.columns and not df_stk.empty:
factor_eps[stk] = df_stk['PERSHAREINDEX.s_fa_eps_basic'].iloc[-1]
df_factors = pd.DataFrame({'ROE': factor_roe, 'EPS': factor_eps, 'Return': returns}).dropna()
if len(df_factors) < 10:
return
# 3. 计算 IC 与 Rank-IC
ic_roe, _ = pearsonr(df_factors['ROE'], df_factors['Return'])
rank_ic_roe, _ = spearmanr(df_factors['ROE'], df_factors['Return'])
ic_eps, _ = pearsonr(df_factors['EPS'], df_factors['Return'])
rank_ic_eps, _ = spearmanr(df_factors['EPS'], df_factors['Return'])
print(f"[因子评估] ROE IC: {ic_roe:.4f}, Rank-IC: {rank_ic_roe:.4f}")
print(f"[因子评估] EPS IC: {ic_eps:.4f}, Rank-IC: {rank_ic_eps:.4f}")
# 4. 基于因子的 Z-Score 标准化与组合打分(极简加权)
df_factors['ROE_score'] = (df_factors['ROE'] - df_factors['ROE'].mean()) / df_factors['ROE'].std()
df_factors['EPS_score'] = (df_factors['EPS'] - df_factors['EPS'].mean()) / df_factors['EPS'].std()
# 总得分 = 0.5 * ROE + 0.5 * EPS
df_factors['Total_Score'] = 0.5 * df_factors['ROE_score'] + 0.5 * df_factors['EPS_score']
# 排序选出得分最高前 N 只股票
target_stocks = df_factors.sort_values(by='Total_Score', ascending=False).head(ContextInfo.hold_count).index.tolist()
# 5. 调仓执行:目标比例下单
for stk in target_stocks:
order_target_percent(stk, 1.0 / ContextInfo.hold_count, 'LATEST', ContextInfo.stockcode, ContextInfo)
get_financial_data 时,建议设置 report_type='announce_time'(默认按财报实际公告日期对齐),以防用到未公开的前瞻数据引发未来函数。Rank-IC IR(Rank-IC 均值 / Rank-IC 标准差)动态调整因子权重。