🚀 AI 一键生成 joinquant 策略代码

JoinQuant回测遇到沪深300成分股调整,系统会自动平仓吗?

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

问题描述

回测沪深三百成分股,如果遇到成分股调整,系统如何处理?

请问,
比如我回测20220501~20230501时间段中持有'000XXX',但该股票在20230201被调整出沪深300成分股,那么该持仓:
是否按调整前最后一天收盘价强制平仓并在交易明细里结算?还是持续交易等待回测系统给出的信号平仓?

解决方案

在 JoinQuant(聚宽)量化平台上,系统不会自动强制平仓。该持仓会持续交易,直到你的策略代码给出平仓信号

原理解释

JoinQuant 的回测引擎是完全基于你编写的策略代码来执行交易指令的。系统本身不会对你的账户持仓进行任何主观干预(除了保证金不足导致的期货强平等极端情况)。

当你使用 get_index_stocks('000300.XSHG') 获取沪深300成分股时,系统返回的是该时间点最新的成分股列表。如果某只股票被调出指数,它只是不再出现在这个列表中,但这并不会触发任何卖出动作

如何在策略中处理成分股调整?

如果你希望在股票被调出沪深300时将其卖出,你需要在策略的调仓逻辑中显式地编写代码来实现。通常的做法是在每次调仓时,对比当前持仓和最新的成分股列表,将不在最新列表中的股票卖出。

以下是一个简单的代码示例,展示了如何处理这种情况:

import jqdata

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    
    # 每月第一个交易日运行调仓函数
    run_monthly(rebalance, monthday=1, time='09:30')

def rebalance(context):
    # 1. 获取当前最新的沪深300成分股
    current_hs300_stocks = get_index_stocks('000300.XSHG')
    
    # 2. 获取当前账户的所有持仓股票
    current_positions = list(context.portfolio.positions.keys())
    
    # 3. 卖出逻辑:如果持仓中的股票已经不在最新的沪深300成分股列表中,则卖出
    for stock in current_positions:
        if stock not in current_hs300_stocks:
            order_target(stock, 0)
            log.info(f"股票 {stock} 已被调出沪深300,执行平仓")
            
    # 4. 买入逻辑:(此处省略具体的选股和买入逻辑)
    # ...

总结

  • 系统默认行为:一直持有,直到你的代码调用 orderorder_target 等函数将其卖出。
  • 正确做法:在你的定时运行函数(如 run_daily, run_monthly)中,定期获取最新的 get_index_stocks,并与 context.portfolio.positions 进行比对,自行编写剔除逻辑。