问题描述
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"
"1、客户反馈14:36进行委托,14:37进行撮合成交,但是成交数量与bar盘口对不上;
2、检查客户交易日志,14:36委托40000股,查看委托价格,与14:36时price价格一致,当时盘口volume为19300
解决方案
问题原因解析
您在回测中遇到的现象是由于触发了 Ptrade 回测引擎的默认成交比例限制机制。
根据 Ptrade API 文档,为了使回测中的盘口流动性尽量逼近真实交易场景,系统默认设置了单笔委托的成交比例限制。具体规则如下:
- 默认成交比例为 25%:系统默认调用了
set_volume_ratio(volume_ratio=0.25),即本周期最大成交数量为本周期市场可成交总量的四分之一。 - 超出部分自动撤单:假如委托下单数量大于按成交比例计算后的数量,系统会按计算后的最大数量进行撮合,差额部分的委托数量不会继续挂单,而是会被直接取消(Cancelled)。
结合您的日志数据进行计算:
- 日志提示:
volume 40000 is larger than 25.0 percent of current bar volume, fill 4800.0 actually - 实际撮合逻辑:系统判定当前 bar 的实际可用于撮合的 volume 约为
19200(4800 / 0.25 = 19200,这与您观察到的盘口 volume19300基本一致,微小差异可能源于复权或数据精度)。 - 结果:您委托了
40000股,但当前 bar 的 25% 只有4800股。因此,系统只为您成交了4800股,剩余的35200股被系统自动撤单。
解决方法
如果您希望在回测中成交更多的数量,或者完全不受真实市场流动性的限制(例如在验证策略逻辑时),可以通过在 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')
总结:回测引擎的这一设计是为了防止策略在回测中产生“虚假的流动性错觉”(即在实盘中根本无法成交那么大的量)。如果您明确知道策略的资金容量,或者仅为了验证信号,使用 set_limit_mode('UNLIMITED') 即可解决该问题。