问题描述
回测的时候,客户的委托数量和当时获取行情内volume获取值不一样,并且成交撮合和委托对不上!
14:36:00 WARNING Order Cancelled: market order 515120.XSHG volume 40000 is larger than 25.0 percent of current bar volume, fill 4800.0 actually
14:37:00 INFO 挂卖出 515120.SS 40000 0.697 bar量: 2504200.0 bar金额 1742924.0 2023-03-21 06:37:00+00:00
解决方案
问题原因解析
在 ptrade 回测引擎中,您遇到的现象是由于回测系统的成交比例限制机制引起的。
从您的日志报错信息 WARNING Order Cancelled: market order 515120.XSHG volume 40000 is larger than 25.0 percent of current bar volume, fill 4800.0 actually 可以看出:
- 默认成交比例限制:ptrade 回测环境默认设置了单笔委托的成交量不能超过当前周期(Bar)市场真实总成交量的 25%(即
volume_ratio=0.25)。 - 撮合逻辑:当您的委托数量(40000)大于当前分钟/日线 K 线的真实成交量的 25% 时,系统为了模拟真实的流动性冲击,只会撮合这 25% 的量(在您的例子中是 4800),而差额部分(未成交部分)会被系统自动撤单(Cancelled),不会继续挂单。
这就是为什么您发现委托数量和实际成交量对不上,且撮合结果与预期不一致的原因。
解决方案
要解决这个问题,您可以通过在策略的 initialize 函数中调用特定的 API 来调整或关闭这个限制。
方法一:调整成交比例(推荐)
如果您希望放宽限制,但仍保留一定的流动性模拟,可以使用 set_volume_ratio 函数调大成交比例。例如,将其设置为 1.0(即允许成交量达到当前 Bar 的 100%)。
def initialize(context):
g.security = '515120.SS'
set_universe(g.security)
# 将最大成交数量设置为本周期可成交总量的 100%
set_volume_ratio(volume_ratio=1.0)
方法二:完全关闭成交数量限制模式
对于低频策略(如月度调仓)或对流动性冲击不敏感的策略,您可以直接关闭成交量限制。使用 set_limit_mode 函数并传入 'UNLIMITED'。
注意:关闭限制后,实际撮合成交量可能会大于该时间段市场的实际成交总量。
def initialize(context):
g.security = '515120.SS'
set_universe(g.security)
# 回测中不限制成交数量
set_limit_mode('UNLIMITED')
总结
在进行 ptrade 回测时,为了让回测结果更贴近真实交易,系统默认引入了滑点(Slippage)和成交比例限制(Volume Ratio)。如果您在测试大资金或流动性较差的标的时遇到成交不足的问题,请务必检查并根据策略需求合理配置 set_volume_ratio 和 set_limit_mode。