问题描述
run_weekly(weekly_adjustment, weekday=1, time='9:30', reference_security='000300.XSHG')
可是查看归因分析里的持仓分析,发现最短持仓天数小于1.75?
这是什么情况,按周调仓,最少会持有5天吧?
难道是节假日的影响?
解决方案
您好!在使用 JoinQuant 平台的 run_weekly 函数进行按周调仓时,归因分析中显示的最短持仓天数小于 5 天(如 1.75 天),确实是非常常见的现象。您的猜测非常准确,节假日的影响是其中最主要的原因之一,但除此之外还有其他几种可能的情况。以下为您详细解析:
1. 节假日导致的“交易日偏移”
run_weekly(func, weekday=1) 的逻辑是:在每周的第一个交易日执行调仓。
- 正常情况:本周一是第一个交易日,下周一也是第一个交易日,中间相隔 5 个交易日。
- 节假日情况:假设某周一到周三是法定节假日(如国庆节、五一),那么该周的“第一个交易日”实际上是周四。您的策略会在周四买入股票。到了下一周,如果没有节假日,下周的“第一个交易日”恢复为周一。这样一来,您在周四买入的股票,在下周一就被调仓卖出了,中间只持有了周四、周五两个交易日(即 2 天)。
2. 回测期末的“截断效应”
归因分析统计的是整个回测期间的所有持仓记录。假设您的回测结束日期是某周的周二,而您的策略在这一周的周一(即前一天)刚刚执行了 run_weekly 调仓买入了股票。当回测在周二结束时,系统会强制结算所有持仓,这笔交易的实际持仓天数就只有 1 天。这会直接拉低统计中的“最短持仓天数”。
3. 策略中存在其他卖出逻辑
请检查您的策略代码中,除了 run_weekly 绑定的 weekly_adjustment 函数外,是否还存在其他可能触发卖出的逻辑:
- 止损/止盈逻辑:如果在
handle_data或run_daily中写了止损止盈代码,股票可能在买入后的第二天或第三天触发条件被卖出。 - 退市或停牌处理:如果持有的股票即将退市,或者策略中有针对停牌股的特殊处理,也可能导致提前卖出。
4. 订单未完全成交(分批成交)
在真实价格或考虑滑点、成交量限制的回测中,如果某只股票在周一调仓时因为涨停或成交量不足没有完全买入,而是在周二、周三才部分成交(限价单挂单成交),然后在下周一卖出。那么这部分在周三才成交的仓位,其实际持仓天数也会少于 5 天。
总结
归因分析中的“最短持仓天数”是一个极值统计,只要在整个回测历史中发生过一次上述情况(如遇到一次特殊的节假日安排,或回测刚好在调仓后一两天结束),这个数值就会小于 5。这是完全符合 A 股日历规则和回测引擎逻辑的,不需要担心策略代码本身存在基础性错误。