问题描述
我用
C.get_financial_data(fieldList=['CAPITALSTRUCTURE.total_capital'],
stockList=stock_list,
startDate='20250710',
endDate='20250710')
来获取股本数据,想计算总市值。但是部分股票的股本数据为 nan 是为什么?我看到论坛上有人说若股本数据未变化就会为 nan,需要自己向前填充,我甚至将 startDate 从 2015 年开始结果仍然有大量股票的股本数据为 0.想问下是为什么,是 api 的 bug 吗?
解决方案
在使用 QMT 的 get_financial_data 接口获取股本数据时遇到返回 nan 或 0 的情况,通常不是 API 的 bug,而是由数据机制或调用方式引起的。以下是常见原因及最佳解决方案:
1. 本地财务数据未补充(最常见原因)
QMT 的财务数据接口(get_financial_data)是直接读取本地数据的。如果你的客户端没有下载对应的财务数据,接口就会返回 nan 或 0。
解决方法:在 QMT 客户端中,点击菜单栏的 数据管理 -> 补充数据,勾选“财务数据”并设定好时间范围,点击补充。确保数据下载完成后再运行策略。
2. 查询日期设置问题
在你提供的代码示例中,startDate 和 endDate 都设置为了 '20250710'。这是一个未来的日期,自然无法获取到任何已公告的财务数据。即使你将日期改为了 2015 年,如果只查询某一天,且该股票在这一天并没有发布财报或股本变动公告,依然会返回 nan。
3. 财务数据的低频特性与填充
财务数据属于低频数据。默认情况下,get_financial_data 的 report_type 参数为 'announce_time'(按公告日取数)。这意味着只有在公告日当天才有数据点,其他日期都是 nan。如果你获取的是一个时间序列(DataFrame),确实需要使用 pandas 的 .ffill()(向前填充)方法来用最近一次的公告数据填充空白日期。
💡 最佳替代方案:如何高效获取总股本计算市值?
如果你获取股本数据的唯一目的是为了计算总市值,强烈建议不要使用 get_financial_data 接口。财务数据接口较重,且处理对齐比较麻烦。QMT 提供了专门且更轻量的接口来获取股本信息:
方法一:使用 get_total_share 接口(推荐)
该接口直接返回指定股票的最新总股数,无需下载庞大的财务数据包。
def handlebar(ContextInfo):
stock_code = '000001.SZ'
# 获取总股数
total_share = ContextInfo.get_total_share(stock_code)
# 获取最新收盘价
close_price = ContextInfo.get_market_data(['close'], [stock_code], period='1d', count=1)['close'][0]
# 计算总市值
market_value = total_share * close_price
print(f"{stock_code} 总市值: {market_value}")
方法二:使用 get_instrumentdetail 接口
该接口可以获取合约的详细静态信息,其中包含了总股本(TotalVolumn)和流通股本(FloatVolumn)。
def handlebar(ContextInfo):
stock_code = '000001.SZ'
detail = ContextInfo.get_instrumentdetail(stock_code)
if detail:
total_capital = detail.get('TotalVolumn', 0) # 总股本
float_capital = detail.get('FloatVolumn', 0) # 流通股本
print(f"{stock_code} 总股本: {total_capital}")
总结:
- 检查并补充 QMT 客户端的本地财务数据。
- 检查传入的日期参数是否合理。
- 计算市值时,优先使用
ContextInfo.get_total_share()或ContextInfo.get_instrumentdetail(),既准确又高效。