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

JoinQuant中avg_cost计算浮动盈亏是否考虑拆分合并?

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

问题描述

用avg_cost来计算浮动盈亏,是否没考虑拆分合并的情况?

根据,api文档的说明

avg_cost 是当前持仓成本,只有在开仓/加仓时会更新: new_avg_cost = (posiont_value + trade_value + commission) / (position_amount + trade_amount)
每次买入后会调整avg_cost, 卖出时avg_cost不变. 这个值也会被用来计算浮动盈亏.

用context.Portfolio.Position中的avg_cost来计算浮动盈亏,是否没考虑拆分合并的情况?

比如买入价是2,当天发生了拆分,价格变为1,用来计算浮动盈亏的话,在回测中会直接变成浮亏50%。

策略里面计算持仓盈亏也有同样问题。请问应该如何处理呢?

--
比如,5.13买入512690.XSHG(酒ETF),5.17拆分,被记成浮亏

解决方案

在 JoinQuant 平台中,关于 avg_cost 计算浮动盈亏以及拆分合并的处理,主要与是否开启动态复权(真实价格)模式以及**交易标的的类型(如场内基金)**有关。

1. 平台的默认处理机制(动态复权模式)

根据 JoinQuant API 文档,如果您在 initialize 函数中开启了动态复权(真实价格)模式:

set_option('use_real_price', True)

每到新的一天,如果持仓中的股票发生了拆合或者分红等影响复权因子的情形,系统会根据复权因子自动调整股票的数量。为了保证 context.portfolio.total_value(总资产)不变,持仓数量会相应增加或减少,同时 avg_cost 也会被系统自动按比例调整,因此理论上不会出现因为拆分导致直接浮亏 50% 的情况

2. 为什么场内基金(如酒ETF 512690.XSHG)会出现异常?

您提到的 512690.XSHG 属于场内基金(ETF)。在 JoinQuant 的官方文档中有特别的注意事项:

注意: 对期货不生效,对场内基金会生效,但因场内基金在拆分/合并时除权日披露不标准,目前采用的是折算基准日,和实际除权日可能有差异,鉴于此原因不建议给含有场内基金的策略开启动态复权。

正是因为场内基金的除权日和折算基准日存在时间差,导致系统在某一天更新价格时,持仓数量和 avg_cost 可能没有在同一天同步调整,从而在回测或模拟中表现为巨大的“浮亏”或“浮盈”。

3. 应该如何处理?

针对这种情况,建议采用以下几种方式来处理策略中的持仓盈亏计算:

方案一:自行使用前复权价格计算盈亏(推荐)

不要依赖 context.portfolio.positions[security].avg_cost 来计算盈亏。您可以在买入时,记录当时的前复权价格,并在后续判断时,获取当前的前复权价格进行对比。

def initialize(context):
    set_option('use_real_price', True)
    g.buy_prices = {} # 记录买入时的前复权价格

def market_open(context):
    security = '512690.XSHG'
    # 获取当前的前复权价格
    current_price = get_price(security, count=1, end_date=context.current_dt, frequency='1m', fields=['close'], fq='pre')['close'][0]
    
    # 买入逻辑
    if condition_to_buy:
        order(security, 1000)
        g.buy_prices[security] = current_price
        
    # 计算浮动盈亏比例
    if security in context.portfolio.positions and security in g.buy_prices:
        cost_price = g.buy_prices[security]
        profit_ratio = (current_price - cost_price) / cost_price
        log.info(f"{security} 当前浮动盈亏比例: {profit_ratio*100:.2f}%")

注:get_priceattribute_history 默认返回的都是基于当天的前复权价格,这样计算出的盈亏比例是准确的,不受拆分合并的干扰。

方案二:避免在场内基金拆分合并期间交易

如果您主要交易的是场内基金,且依赖系统的 avg_cost,由于平台数据的局限性,您可以提前查阅该 ETF 的拆分/折算公告,在策略中硬编码避开这些日期进行交易和盈亏判断。

方案三:关闭动态复权模式(仅限回测)

如果您只做回测,可以关闭动态复权模式(即不调用 set_option('use_real_price', True))。此时回测全程使用基于回测当天的前复权价格,价格是连续的,avg_cost 也是连续的,不会出现突变。但强烈不建议在模拟交易中使用此方法,因为这会导致下单价格与真实市场价格不符。