问题描述
行业板块指数有相应的数据,但概念指数好像没有?
要把概念下面所有股票查出来,再自行计算吗?谢谢。
解决方案
直接回答
是的,您的猜测完全正确。
根据聚宽(JoinQuant)官方 API 文档的说明:
“概念板块目前只可以通过
get_concept_stocks获取某个概念板块包含哪些股票;目前没有概念板块的行情数据。”
因此,聚宽平台目前没有直接提供概念指数的行情数据(如开高低收、涨跌幅等)。如果您需要获取某个概念指数的涨幅,必须先通过 get_concept_stocks 查出该概念下的所有成分股,然后获取这些成分股的行情数据,最后自行编写代码进行计算。
如何自行计算概念指数的涨幅?
计算概念指数的涨幅通常有两种常见的方法:等权重计算法和市值加权计算法。下面为您提供在聚宽研究环境或回测中可以直接使用的 Python 代码示例。
方法一:等权重计算法(简单平均)
这种方法假设您在概念板块中的每一只股票上投入相同的资金,直接对所有成分股的涨跌幅求平均值。
import pandas as pd
from jqdata import *
def get_concept_return_equal_weight(concept_code, end_date):
"""
计算概念板块的等权重日涨幅
:param concept_code: 概念代码,例如 'GN028' (智能电网)
:param end_date: 计算日期,例如 '2023-10-10'
:return: float, 等权重涨幅
"""
# 1. 获取概念成分股
stocks = get_concept_stocks(concept_code, date=end_date)
if not stocks:
return None
# 2. 获取这些股票近两日的收盘价
df_close = get_price(stocks, end_date=end_date, count=2, fields=['close'], panel=False)
# 3. 数据透视,将长表转换为宽表 (index为日期,columns为股票代码)
df_pivot = df_close.pivot(index='time', columns='code', values='close')
# 4. 计算每只股票的日涨跌幅
returns = df_pivot.pct_change().iloc[-1]
# 5. 计算等权重平均涨幅 (自动忽略 NaN 值)
avg_return = returns.mean()
return avg_return
# 测试调用
# print("等权重涨幅:", get_concept_return_equal_weight('GN028', '2023-10-10'))
方法二:市值加权计算法(更贴近真实指数)
真实的指数(如沪深300)通常是按市值加权的,即市值越大的股票对指数涨幅的影响越大。我们可以利用 get_fundamentals 获取市值数据来进行加权计算。
import pandas as pd
from jqdata import *
def get_concept_return_market_cap_weight(concept_code, end_date):
"""
计算概念板块的市值加权日涨幅
:param concept_code: 概念代码,例如 'GN028'
:param end_date: 计算日期,例如 '2023-10-10'
:return: float, 市值加权涨幅
"""
# 1. 获取概念成分股
stocks = get_concept_stocks(concept_code, date=end_date)
if not stocks:
return None
# 2. 获取成分股的总市值
q = query(valuation.code, valuation.market_cap).filter(valuation.code.in_(stocks))
df_cap = get_fundamentals(q, date=end_date)
df_cap.set_index('code', inplace=True)
# 3. 获取近两日收盘价并计算涨跌幅
df_close = get_price(stocks, end_date=end_date, count=2, fields=['close'], panel=False)
df_pivot = df_close.pivot(index='time', columns='code', values='close')
returns = df_pivot.pct_change().iloc[-1]
# 4. 合并涨跌幅与市值数据
data = pd.concat([returns, df_cap['market_cap']], axis=1)
data.columns = ['return', 'market_cap']
# 剔除停牌或缺失数据的股票
data.dropna(inplace=True)
if data.empty:
return None
# 5. 计算市值加权涨幅
total_cap = data['market_cap'].sum()
weighted_return = (data['return'] * data['market_cap']).sum() / total_cap
return weighted_return
# 测试调用
# print("市值加权涨幅:", get_concept_return_market_cap_weight('GN028', '2023-10-10'))
💡 注意事项与优化建议
- 停牌股票处理:上述代码中使用了
dropna()来剔除没有计算出涨跌幅的股票(例如停牌导致获取不到有效价格)。在实际策略中,停牌股票的涨跌幅通常视为0,您可以根据策略的严谨程度决定是剔除还是填充为0。 - 概念代码获取:如果您不知道具体的概念代码,可以通过
get_concepts()函数获取聚宽支持的所有概念板块列表及其对应的代码(如GN028)。 - 性能优化:如果您需要在回测中每天计算多个概念的涨幅,建议将
get_price和get_fundamentals的调用批量化,避免在循环中频繁调用 API,以提升回测速度。