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

如何在 JoinQuant 编写多因子策略的定时换仓函数?(附完整源码)

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

问题描述

多因子换仓函数如何写?

需要一个能按固定比例调仓,每周期卖出不在股票名单内的股票,买入在股票名单内而未持有的股票。
谢谢!

解决方案

在 JoinQuant(聚宽)平台上编写多因子策略的换仓函数,核心逻辑通常分为两步:第一步是卖出(平仓当前持有但不在新目标名单中的股票),第二步是买入/调仓(将目标名单中的股票调整至目标权重)。

以下是一个完整且通用的换仓函数实现,采用**等权重(固定比例)**的方式进行调仓:

完整策略代码示例

# 导入聚宽函数库
import jqdata

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 设置手续费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 每月第一个交易日 09:30 运行调仓函数
    run_monthly(rebalance, monthday=1, time='09:30')

def get_target_stocks(context):
    # 这里是你的多因子选股逻辑,返回一个股票代码列表
    # 示例:简单选取几只股票作为目标名单
    return ['000001.XSHE', '000002.XSHE', '600000.XSHG', '600036.XSHG']

def rebalance(context):
    # 1. 获取本周期的目标股票名单
    target_list = get_target_stocks(context)
    
    # 2. 获取当前账户持仓的股票
    current_positions = list(context.portfolio.positions.keys())
    
    # 3. 卖出逻辑:如果持仓中的股票不在目标名单内,则全部卖出
    for stock in current_positions:
        if stock not in target_list:
            order_target_value(stock, 0)
            log.info("卖出不在目标名单内的股票: %s" % stock)
            
    # 4. 买入/调仓逻辑:按固定比例(等权重)买入目标股票
    if len(target_list) > 0:
        # 计算每只股票应分配的目标价值(总资产 / 目标股票数量)
        # 注意:这里使用 context.portfolio.total_value 获取账户总权益
        target_value = context.portfolio.total_value / len(target_list)
        
        for stock in target_list:
            # order_target_value 会自动计算差额进行买入或卖出,使其达到目标价值
            order_target_value(stock, target_value)
            log.info("调仓股票: %s, 目标价值: %.2f" % (stock, target_value))

核心函数解析

  1. context.portfolio.positions:这是一个字典,包含了当前账户所有持仓的股票信息。通过 .keys() 可以获取当前持有的所有股票代码。
  2. order_target_value(security, value):这是聚宽非常强大的一个下单 API。它的作用是将指定标的(security)的仓位调整到目标价值(value)。
    • 如果 value = 0,相当于全部清仓卖出。
    • 如果当前未持有该股票,它会用相应的现金买入该股票直到达到 value 的市值。
    • 如果当前已持有该股票但市值不足 value,它会补仓;如果市值超过 value,它会减仓。
  3. context.portfolio.total_value:获取账户的总资产(包含可用现金和当前持仓市值)。用它除以目标股票数量,即可实现“等权重/固定比例”调仓。

进阶优化建议

在实际的实盘或高精度回测中,你可能还需要考虑停牌股票涨跌停股票的处理。例如,在卖出时如果股票停牌是无法卖出的,这会占用资金,导致后续买入其他股票时资金不足。可以通过 get_current_data()[stock].paused 来判断股票是否停牌,从而优化资金分配逻辑。