问题描述
获取申万一级行业指数的实时收盘价(例如:白酒行业指数 '801120')
industry_code = '801120' # 申万白酒行业指数
current_data = get_price(
security=industry_code,
end_date=context.current_dt, # 当前回测/模拟日期
frequency='daily', # 日线数据
fields=['close'], # 只获取收盘价
skip_paused=False, # 不跳过停牌
fq=None, # 不复权
count=1 # 获取最近1条数据
)
close_price = current_data['close'][0] # 提取收盘价
log.info(f"行业指数 {industry_code} 收盘价: {close_price}")
编译运行:jqdata.exceptions.ParamsError: 找不到标的801120
这个情况怎么处理?或者有没有其他的办法取得?
解决方案
为什么会提示“找不到标的”?
在 JoinQuant(聚宽)平台中,get_price 函数的 security 参数需要传入标准的交易标的代码(如股票、基金、期货等,且需带有 .XSHG 或 .XSHE 等后缀)。
根据 JoinQuant 官方 API 文档的说明:“目前不支持行业的行情数据,及指数的PE/股息率”。因此,直接将申万行业代码(如 '801120')传入 get_price 会导致系统无法识别,从而抛出 jqdata.exceptions.ParamsError: 找不到标的801120 的错误。
替代解决方案
虽然无法直接获取行业指数的 K 线数据,但我们可以通过以下两种有效的方法来替代实现获取行业行情的需求:
方案一:使用对应的行业 ETF 基金作为替代标的(推荐)
如果您获取行业价格是为了生成交易信号或作为基准,最直接且可交易的方式是使用跟踪该行业的 ETF 基金。例如,白酒行业可以使用“酒ETF(512690.XSHG)”。
def handle_data(context, data):
# 使用白酒ETF作为替代标的
etf_code = '512690.XSHG'
current_data = get_price(
security=etf_code,
end_date=context.current_dt,
frequency='daily',
fields=['close'],
skip_paused=False,
fq='pre', # 建议使用前复权
count=1
)
if not current_data.empty:
close_price = current_data['close'][0]
log.info(f"白酒ETF {etf_code} 收盘价: {close_price}")
方案二:获取行业成分股并自行计算行业平均价
如果您纯粹是为了进行数据分析,可以通过 get_industry_stocks 获取该行业下的所有成分股,然后拉取这些成分股的价格,自行计算等权平均价或市值加权平均价来拟合行业走势。
def handle_data(context, data):
industry_code = '801120' # 申万白酒行业
# 1. 获取该行业下的所有成分股
stocks = get_industry_stocks(industry_code, date=context.current_dt)
if not stocks:
log.error(f"未找到行业 {industry_code} 的成分股")
return
# 2. 获取所有成分股的收盘价
# 注意:获取多只股票时,get_price 返回的是 DataFrame,列名为股票代码
price_df = get_price(
security=stocks,
end_date=context.current_dt,
frequency='daily',
fields=['close'],
skip_paused=True, # 跳过停牌股票,避免计算失真
fq='pre',
count=1,
panel=False # 建议设置为 False
)
if not price_df.empty:
# 3. 计算等权平均价作为行业参考价格
# price_df['close'] 包含了所有成分股的收盘价
industry_avg_price = price_df['close'].iloc[0].mean()
log.info(f"行业 {industry_code} 成分股等权平均收盘价: {industry_avg_price:.2f}")
总结建议
- 用于交易信号:强烈建议使用方案一。因为行业指数本身不可交易,使用 ETF 既能反映行业走势,又能直接用于
order()下单,且避免了成分股停牌、退市带来的计算偏差。 - 用于宏观/行业分析:可以使用方案二,结合
get_valuation获取市值数据,进一步计算市值加权的行业指数。