问题描述
解决方案
这是一个基于 QMT Python API 的选股脚本。该脚本会获取所有 A 股股票,并筛选出在当前回测或运行时间点,最新财报中净资产收益率 (ROE) 大于 20% 的股票。
策略逻辑说明
- 获取股票池:在
init中使用get_stock_list_in_sector('沪深A股')获取全市场 A 股代码。 - 获取财务数据:在
handlebar中(仅在最后一根 K 线执行),使用get_financial_data批量获取所有股票的PERSHAREINDEX.du_return_on_equity(净资产收益率)数据。 - 筛选与排序:利用 Pandas 对数据进行过滤,筛选出 ROE > 20 的股票,并按 ROE 从高到低排序。
- 输出结果:打印符合条件的股票代码、名称及具体的 ROE 数值。
Python 策略代码
# -*- coding: gbk -*-
import pandas as pd
def init(ContextInfo):
# 1. 获取所有沪深A股股票代码
# 这一步在初始化时执行一次即可
ContextInfo.stock_list = ContextInfo.get_stock_list_in_sector('沪深A股')
print(f"策略初始化完成,获取到 A 股数量: {len(ContextInfo.stock_list)}")
def handlebar(ContextInfo):
# 为了避免在历史回测的每一根 K 线上都打印,我们只在最后一根 K 线(最新时刻)执行筛选
if not ContextInfo.is_last_bar():
return
# 2. 定义需要获取的财务字段
# du_return_on_equity 对应主要指标中的“净资产收益率”
field_name = 'PERSHAREINDEX.du_return_on_equity'
field_list = [field_name]
# 获取当前运行到的日期(YYYYMMDD格式)
current_timetag = ContextInfo.get_bar_timetag(ContextInfo.barpos)
current_date = timetag_to_datetime(current_timetag, '%Y%m%d')
print(f"正在筛选 {current_date} 时刻 ROE > 20% 的股票,请稍候...")
# 3. 批量获取财务数据
# 参数说明:字段列表, 股票列表, 开始时间, 结束时间, 报表类型
# report_type='announce_time' 表示按照公告日期获取当时已发布的最新数据,避免未来函数
# 开始时间和结束时间都设为 current_date,表示获取该时间点的截面数据
df = ContextInfo.get_financial_data(
field_list,
ContextInfo.stock_list,
current_date,
current_date,
report_type='announce_time'
)
# 4. 数据处理与筛选
# get_financial_data 返回的数据格式:
# 当代码列表为 n,时间范围为 1 时,返回 DataFrame (Index=代码, Columns=字段)
if df is None or df.empty:
print("未获取到财务数据,请检查数据是否已下载补充。")
return
# 提取 ROE 列
roe_series = df[field_name]
# 筛选 ROE > 20 的股票
# 注意:财务数据中可能存在 NaN (空值),Pandas 比较时会自动处理
filtered_stocks = roe_series[roe_series > 20]
# 按 ROE 从高到低排序
filtered_stocks = filtered_stocks.sort_values(ascending=False)
# 5. 输出结果
print("=" * 60)
print(f"筛选结果:共发现 {len(filtered_stocks)} 只股票 ROE > 20%")
print(f"{'代码':<12} {'名称':<12} {'ROE(%)':<10}")
print("-" * 60)
for code, roe_value in filtered_stocks.items():
# 获取股票名称
name = ContextInfo.get_stock_name(code)
print(f"{code:<12} {name:<12} {roe_value:.2f}")
print("=" * 60)
使用说明
- 补充数据:运行此脚本前,请确保在 QMT 客户端的【数据管理】中补充了财务数据。如果没有本地数据,
get_financial_data将无法返回结果。 - 运行模式:
- 此脚本可以在“回测模式”或“模型研究/运行”模式下运行。
- 如果在回测模式下,它会筛选出回测结束日期那一天符合条件的股票。
- 如果在实时模式下,它会筛选出基于最新已公告财报符合条件的股票。
- 字段解释:代码中使用的
PERSHAREINDEX.du_return_on_equity是“净资产收益率”。如果你需要“摊薄净资产收益率”或“加权净资产收益率”,可以分别替换为PERSHAREINDEX.net_roe或PERSHAREINDEX.equity_roe。
Q&A
Q: 为什么运行后提示“未获取到财务数据”?
A: QMT 的财务数据依赖本地数据库。请在客户端顶部菜单栏点击“数据” -> “数据管理”,勾选“财务数据”并选择对应的市场和时间段进行下载补充。
Q: report_type='announce_time' 是什么意思?
A: 这代表“按公告日期”取数。例如,某公司在 4 月 20 日发布年报,如果在 4 月 19 日运行策略,系统会取三季报的数据;在 4 月 20 日运行则取年报数据。这能确保回测时不会用到当时还未公开的“未来数据”。
Q: 如何将筛选结果直接买入?
A: 可以在 handlebar 函数的循环中添加交易逻辑。例如:
for code, roe_value in filtered_stocks.items():
# 以最新价买入 100 股
passorder(23, 1101, ContextInfo.accid, code, 5, -1, 100, ContextInfo)
注意:实盘交易请务必添加风控逻辑和资金判断。