🚀 AI 一键生成 joinquant 策略代码

JoinQuant API 教程:如何使用 on_event 函数响应持仓事件?

joinquant | 发布时间: 2025/11/26
以下内容由 EasyQuant 生成。

问题描述

当我的持仓股票分红时,如何自动处理?

解决方案

在聚宽(JoinQuant)平台中,处理持仓股票分红(现金分红或送转股)的最佳方式是开启“真实价格(动态复权)模式”

开启该模式后,系统会自动处理分红派息,无需您手动编写复杂的计算逻辑。

以下是详细的处理机制和代码实现:

1. 核心设置:开启真实价格模式

initialize 函数中调用 set_option('use_real_price', True)

  • 未开启时(默认):使用的是前复权价格。历史价格会被调整以消除分红影响,分红发生时账户现金不会增加,持仓数量也不会变化(除非发生拆合),这不符合真实交易场景。
  • 开启后(推荐):使用的是真实价格
    • 现金分红:在除权除息日,分红现金(扣税后)会自动打入您的账户(available_cash 增加),股价会自然回落。
    • 送转股:持仓数量(total_amount)会自动增加,股价会相应降低。

2. 自动处理的细节

当您设置了 set_option('use_real_price', True) 后,系统行为如下:

  • 除权除息:系统会在除权除息日自动调整您的持仓数量和可用资金。
  • 税费扣除
    • 在回测和模拟交易中,由于难以精确追踪每一笔买入的持仓时长(先进先出原则),系统通常统一按照 20% 的税率扣除红利税。
    • 分红现金 = 每股分红金额 × 持仓股数 × (1 - 20%)。
  • 资金到账:现金会在除权除息日开盘前自动加到账户的 available_cash 中,您可以在当天的交易中直接使用这笔资金。

3. 代码示例

以下是一个完整的策略示例,展示如何开启该模式,以及如何(可选地)使用 on_event 回调函数来监控分红事件。

# -*- coding: utf-8 -*-
from jqdata import *

def initialize(context):
    # 1. 设定基准
    set_benchmark('000300.XSHG')
    
    # 2. 【关键步骤】开启动态复权模式(真实价格)
    # 开启后,分红、送股将自动到账,股价使用真实历史价格
    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')
    
    # 举例:买入一只历史上分红较多的股票(如格力电器)
    g.security = '000651.XSHE'
    run_daily(market_open, time='09:30')

def market_open(context):
    if g.security not in context.portfolio.positions:
        order_value(g.security, 100000)

# 【可选】高级功能:使用事件回调监听分红
# 如果您需要在分红发生时执行特定逻辑(如收到分红立即再投资),可以使用此函数
def on_event(context, event):
    # 检查是否是分红事件
    if isinstance(event, DividendsEvent):
        log.info("触发分红事件!")
        log.info("标的: %s" % event.security)
        # event.dividends 是一个列表,包含分红信息
        # 结构示例: [{'date': datetime.date(2023, 6, 1), 'bonus_pre_tax': 0.5, 'scale_factor': 0}]
        for div in event.dividends:
            log.info("分红详情: %s" % str(div))
        
        # 示例逻辑:如果收到现金分红,打印当前可用资金
        log.info("当前可用资金(含分红): %s" % context.portfolio.available_cash)

4. 常见问题说明

  • 为什么回测结果和不开启真实价格时不一样?
    不开启真实价格时,使用的是前复权数据,历史股价被“压低”了。开启真实价格后,买入同样金额的股票,获得的股数可能不同(因为价格不同),且分红会以现金形式回流,这更接近真实实盘的收益曲线。
  • 能否不扣税?
    在回测环境中,税率计算是系统固定的(通常为20%),无法通过简单的API参数修改为不扣税或按持仓时长阶梯扣税。
  • 数据更新时间
    分红数据通常在除权除息日当天生效。如果您在 handle_datarun_daily 中打印 context.portfolio.available_cash,会发现资金已经包含了当天的分红。

总结

要在聚宽中自动处理分红,您只需要做一件事:initialize 中添加 set_option('use_real_price', True)。系统会自动处理除权、除息、派现和红股入账。


Q&A

Q: 如果我不开启 use_real_price,分红会怎么处理?
A: 如果不开启(即使用默认的前复权模式),系统会假设分红已经“再投资”到了股价中(通过降低历史股价来实现复权)。您的账户不会收到现金分红,持仓数量也不会因为送转而增加。这种模式适合技术指标分析,但不适合模拟真实的账户资金流。

Q: on_event 函数是必须写的吗?
A: 不是。on_event 是可选的。即使不写这个函数,只要开启了真实价格模式,分红资金和股票依然会自动到账。on_event 仅用于您需要在分红发生的瞬间执行特定代码(例如记录日志或立即将分红资金买入股票)时使用。

Q: 模拟交易中分红什么时候到账?
A: 在模拟交易中,分红通常在除权除息日的开盘前到账。系统会根据交易所的公告自动处理。