问题描述
目前滑点并不能设置加在买单还是卖单一侧,如果开仓一侧是限价单,平仓一侧是市价单,那么滑点加在哪一侧呢?
因为如果加在限价单开仓1侧,影响的是限价单是否能够撮合成功,但是不影响成交价。
如果加在市价单平仓1侧,直接影响成交价。
根据我比对交易记录的结果,发现1个滑点,有时加在开仓,有时加在平仓,是不一定的。
但是加在开仓和加在平仓对一边限价一边市价的影响截然不同。
所以,建议滑点函数加一个设置参数,滑点是加在开仓一侧还是平仓一侧。
解决方案
在 JoinQuant 平台中,滑点(Slippage)的机制是双边对称且针对每一笔独立交易(买入或卖出)生效的,而不是针对“开仓”或“平仓”这个完整的交易周期来分配的。
针对您的疑问,以下是 JoinQuant 滑点机制的详细解析:
1. 滑点是如何加在买单和卖单上的?
在 JoinQuant 中,无论您使用的是固定滑点(FixedSlippage)、百分比滑点(PriceRelatedSlippage)还是跳数滑点(StepRelatedSlippage),滑点都是双边计算的。具体来说:
- 买入动作(开多/平空):成交价 = 预期价格 + 滑点(即买得更贵)。
- 卖出动作(开空/平多):成交价 = 预期价格 - 滑点(即卖得更便宜)。
2. 限价单与市价单的滑点处理差异
当您“开仓使用限价单,平仓使用市价单”时,滑点的表现形式会有所不同,这也是导致您感觉“滑点有时加在开仓,有时加在平仓”的原因:
市价单(如您的平仓操作)
市价单在未启用盘口撮合时,会直接按 最新价 ± 滑点 进行撮合。因此,市价单的成交价一定会直接受到滑点的影响。
限价单(如您的开仓操作)
限价单的撮合分为两个阶段,滑点的影响也分为两种情况:
- 下单即时撮合:下单时,系统会尝试按
最新价 ± 滑点撮合。如果您的委托价满足条件(例如买入时,委托价 >= 最新价 + 滑点),订单会立即成交,此时的成交价为最新价 + 滑点。这种情况下,滑点直接影响了成交价。 - 挂单后撮合:如果下单时未满足上述条件,订单会变为挂单。在后续的分钟 Bar 或 Tick 撮合中,只要满足价格穿透条件(例如买入时,
委托价 > Bar的最低价),订单就会成交,且成交价为您设定的“委托价”。这种情况下,滑点确实只影响了下单时的即时撮合是否成功,而不影响最终的挂单成交价。
3. 为什么感觉滑点位置不固定?
正如上面限价单的逻辑所述:
- 如果您的限价单在下单瞬间就满足了加了滑点后的最新价,它会立刻成交,此时您会观察到开仓侧产生了滑点。
- 如果您的限价单是挂单后成交的,成交价就是您的委托价,看起来开仓侧没有滑点;而平仓的市价单必然带有滑点,此时您会观察到滑点只加在了平仓侧。
实际上,系统对每一笔交易都一视同仁地计算了滑点,只是限价单的挂单成交机制掩盖了滑点在价格上的体现。
4. 关于单边滑点设置的建议
您建议在 set_slippage 中增加参数来控制滑点仅加在开仓或平仓一侧,这是一个非常精细化的回测需求。目前 JoinQuant 的 API 原生不支持单边滑点设置(滑点模型默认都是双边对称的)。
目前的替代解决方案:
如果您希望在回测中严格控制滑点仅在某一侧生效,可以将全局滑点设置为 0(set_slippage(FixedSlippage(0))),然后在策略代码中手动调整委托价来模拟单边滑点:
- 模拟开仓滑点:在下限价单时,手动将委托价调差(买入调高,卖出调低)。
- 模拟平仓滑点:在下市价单时,改用限价单,并将价格设定为
当前价 ± 您期望的滑点,以确保成交价符合您的单边滑点预期。
希望这个解释能帮助您理清 JoinQuant 的滑点撮合逻辑!