🚀 AI 一键生成 joinquant 策略代码
立即体验

joinquant 概念轮动策略:基于 get_concept_stocks 的热点板块选股指南

joinquant | 发布时间: 2026/7/24
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: joinquant 概念轮动策略:基于 get_concept_stocks 的热点板块选股

Question: 如何利用 joinquant 获取概念板块成分股并编写板块轮动策略?

解决方案

如何利用 JoinQuant 获取概念板块成分股并编写板块轮动策略

在 A 股市场中,概念板块轮动具有显著的动量效应。通过 JoinQuant(聚宽)量化交易平台,投资者可以方便地使用 get_concept_stocksget_concepts API 获取概念板块数据,并实现自动化的板块轮动交易策略。


1. 核心 API 介绍

1.1 get_concepts()

获取平台支持的所有概念板块列表,包含概念代码、概念名称及上市/生效日期。

from jqdata import *
# 获取所有概念板块列表
concepts_df = get_concepts()
print(concepts_df.head())

1.2 get_concept_stocks(concept_code, date=None)

获取在给定日期指定概念板块的所有股票列表。

  • 参数
    • concept_code: 概念板块编码(如 'SC0084')。
    • date: 查询日期(默认为当前回测/逻辑日期)。
  • 返回值:股票代码的 list
# 获取风电概念板块的成分股
stocks = get_concept_stocks('SC0084', date='2023-01-01')

2. 概念轮动策略逻辑设计

概念轮动策略的核心思想是**“追强剔弱”**:

  1. 定义轮动池:挑选关注度高、流动性好的若干核心概念板块(如半导体、新能源、新能源汽车等)。
  2. 计算板块动量:按周期(如每周/每双周)计算各个概念板块内成分股在过去一段时间的平均收益率。
  3. 选中强板块:挑选过去收益率最高的前 $N$ 个概念板块。
  4. 调仓执行:买入所选强势概念板块中的前几只代表性股票或等权重分散持仓,卖出不再处于强势概念中的标的。

3. 策略完整 Python 源码

以下为在 JoinQuant 平台上运行的完整策略代码:

import jqdata
import pandas as pd

def initialize(context):
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 设置交易税费(股票类:买入佣金万3,卖出佣金万3+印花税千1,最低5元)
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 选定的目标概念板块列表(示例选取部分热门概念)
    # 概念代码可以通过 get_concepts() 查询
    g.concept_list = [
        'GN028',  # 智能电网
        'GN033',  # 锂电池
        'GN060',  # 光伏概念
        'GN187',  # 芯片概念
        'GN208'   # 人工智能
    ]
    
    g.hold_concept_count = 1  # 每次持有最强概念数
    g.stock_per_concept = 3   # 每个概念选取的股票数
    
    # 定时调仓:每周第一个交易日 09:30 运行
    run_weekly(rebalance, weekday=1, time='09:30')

def rebalance(context):
    # 1. 计算各大概念板块过去 20 个交易日的平均涨跌幅
    concept_performance = {}
    for concept in g.concept_list:
        stocks = get_concept_stocks(concept, date=context.current_dt)
        if not stocks:
            continue
        # 过滤停牌及退市股票
        current_data = get_current_data()
        valid_stocks = [s for s in stocks if not current_data[s].paused]
        if not valid_stocks:
            continue
            
        # 获取过去20日收盘价
        price_data = history(20, '1d', 'close', valid_stocks, df=True)
        # 计算单只股票20日涨跌幅并求板块均值
        returns = (price_data.iloc[-1] - price_data.iloc[0]) / price_data.iloc[0]
        concept_performance[concept] = returns.mean()
    
    if not concept_performance:
        return
        
    # 2. 排序选出最强的概念板块
    sorted_concepts = sorted(concept_performance.items(), key=lambda x: x[1], reverse=True)
    top_concept = sorted_concepts[0][0]
    log.info("当前最强概念板块: %s,过去20日收益率: %.2f%%" % (top_concept, concept_performance[top_concept] * 100))
    
    # 3. 获取目标概念板块的前 N 只股票(按过去20日涨幅排名)
    target_stocks = get_concept_stocks(top_concept, date=context.current_dt)
    current_data = get_current_data()
    target_stocks = [s for s in target_stocks if not current_data[s].paused and not current_data[s].is_st][:g.stock_per_concept]
    
    # 4. 执行卖出:不在目标持仓里的股票全部平仓
    for stock in list(context.portfolio.positions.keys()):
        if stock not in target_stocks:
            order_target(stock, 0)
            log.info("卖出股票: %s" % stock)
            
    # 5. 执行买入:调仓买入目标股票
    if target_stocks:
        value_per_stock = context.portfolio.available_cash / len(target_stocks)
        for stock in target_stocks:
            if stock not in context.portfolio.positions:
                order_value(stock, value_per_stock)
                log.info("买入股票: %s" % stock)

4. 关键点与开发注意事项

  1. 动态复权设置:强烈建议在 initialize 中开启 set_option('use_real_price', True),保证下单时使用真实价格计算,避免未来函数。
  2. 规避停牌与 ST:在获取概念成分股后,通过 get_current_data() 过滤掉停牌 (paused) 或 ST (is_st) 的股票,提高订单撮合成功率。
  3. 规避未来函数:使用 get_concept_stocks 时,传入 date=context.current_dt 以确保获取的是历史当时的概念成分股。