问题描述
解决方案
在聚宽(JoinQuant)的 Position 对象中,avg_cost 和 acc_avg_cost 是两个用于描述持仓成本的属性,但它们的定义、计算逻辑和用途有显著区别。
简单来说:avg_cost 是当前的开仓均价(仅买入变动),而 acc_avg_cost 是考虑了历史盈亏的累计成本(买卖均变动)。
以下是详细对比:
1. avg_cost (当前持仓成本)
- 定义:当前持有股票的平均买入成本。
- 更新时机:仅在开仓或加仓(买入)时更新。
- 卖出时的表现:卖出股票时,
avg_cost保持不变。这符合大多数交易软件中“持仓成本”的定义。 - 计算公式(加仓时):
$$ \text{new_avg_cost} = \frac{\text{原持仓市值} + \text{本次买入金额} + \text{手续费}}{\text{原持仓数量} + \text{本次买入数量}} $$ - 用途:主要用于计算当前的浮动盈亏。
2. acc_avg_cost (累计持仓成本)
- 定义:该标的从第一次买入开始,累计投入的资金成本摊薄到当前持仓数量上。它反映了该标的在整个交易历史中的累计盈亏情况。
- 更新时机:在买入和卖出时都会更新。
- 卖出时的表现:
- 如果盈利卖出(卖出价 > 持仓成本),
acc_avg_cost会降低(因为赚回了部分现金,相当于降低了剩余持仓的成本)。 - 如果卖出金额巨大(赚了很多),
acc_avg_cost甚至可能变成负数(意味着已经收回了所有本金还有盈余,且手中还有持仓)。 - 如果亏损卖出,
acc_avg_cost会升高(因为亏损部分被摊薄到了剩余持仓的成本中)。
- 如果盈利卖出(卖出价 > 持仓成本),
- 计算公式(减仓/卖出时):
$$ \text{new_acc_avg_cost} = \frac{\text{原累计成本} \times \text{原持仓数} - \text{本次卖出金额} + \text{手续费}}{\text{原持仓数} - \text{本次卖出数量}} $$ - 用途:用于计算该标的的累计收益,适合网格交易或长期定投策略中观察该股的总投资回报。
举例说明
假设不计算手续费,操作一只股票:
-
操作一:买入 100 股,价格 10 元。
avg_cost: 10.0acc_avg_cost: 10.0
-
操作二:加仓 100 股,价格 20 元。
avg_cost: (100*10 + 100*20) / 200 = 15.0acc_avg_cost: 15.0
-
操作三:卖出 100 股,价格 30 元(盈利卖出)。
avg_cost: 15.0 (保持不变,卖出不影响剩余持仓的开仓均价)acc_avg_cost:- 总投入资金:3000元 (100*10 + 100*20)
- 收回资金:3000元 (100*30)
- 剩余持仓:100股
- 计算:(15.0 * 200 - 3000) / 100 = 0.0
- 解释:因为卖出赚的钱覆盖了所有成本,剩余的100股相当于“零成本”持仓。
总结
| 特性 | avg_cost | acc_avg_cost |
|---|---|---|
| 中文名 | 当前持仓成本 | 累计持仓成本 |
| 买入时 | 更新(加权平均) | 更新(加权平均) |
| 卖出时 | 不更新 | 更新(摊薄盈亏) |
| 数值特性 | 通常为正数 | 可能为负数(当盈利覆盖本金时) |
| 核心用途 | 看当前这笔持仓是赚是赔 | 看在这个票上历史上总共是赚是赔 |
Q&A
Q: 为什么我的 acc_avg_cost 是负数?
A: 当您在某只股票上通过波段操作或部分止盈,累计卖出收回的资金已经超过了累计买入投入的资金,且账户中仍持有该股票时,acc_avg_cost 就会变成负数。这代表您的剩余持仓已经是“纯利润”了。
Q: 回测中计算止损应该用哪个成本?
A: 通常建议使用 avg_cost。因为止损通常是针对当前持仓的浮动亏损进行风控,avg_cost 反映了当前手中筹码的平均买入价格,以此计算的盈亏比例更符合单次交易的风控逻辑。
Q: acc_avg_cost 会在清仓后重置吗?
A: 是的。当持仓数量(total_amount)变为 0 时,该标的的 Position 对象通常会被移除或重置。下次再买入该标的时,acc_avg_cost 和 avg_cost 都会从新的买入价重新开始计算(除非策略中有特殊逻辑保留了全局变量)。