3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化投资中,基本面分析与多因子选股是构建长期稳健策略的核心。QMT(Quantitative Trading System)平台提供了强大的财务数据接口 ContextInfo.get_financial_data(),支持投资者获取 A 股上市公司的历史财务报表(资产负债表、利润表、现金流量表、主要财务指标等),从而实现深度的基本面多因子选股。
QMT 提供了两种调用财务数据的方法,分别适用于多股批量查询和单股逐 K 线回测查询。
ContextInfo.get_financial_data(fieldList, stockList, startDate, endDate, report_type='announce_time')
表名.字段名,例如 ['ASHAREBALANCESHEET.fix_assets', 'ASHAREINCOME.net_profit_incl_min_int_inc']。['600000.SH', '000001.SZ']。'YYYYMMDD'。'announce_time'(按公告期,默认)或 'report_time'(按报告期)。
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 核心因子 |
以下是一个完整的 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)
get_financial_data 将返回空值。report_type 建议使用默认的 'announce_time'(公告日期)。如果使用 'report_time'(报告期),回测时会使用尚未公开的财务数据,导致回测结果失真(即未来函数误差)。ContextInfo.is_suspended_stock() 剔除停牌股票,避免下单失败。