问题描述
在聚宽用的命令为:
order(security, amount, style=None, side='long', pindex=0, close_today=False)
这里,API说明里:
“style: 参见OrderStyle, None代表MarketOrder”
在OrderStyle:
“科创板保护价逻辑:
市价买入时成交的最高价格不高于本价格,若最优一档的价格高于该价格,剩余未成交部分撤单;
市价卖出时成交的最低价格不低于本价格,若最优一档的价格低于该价格,剩余未成交部分撤单“
一般在回测时,不都是市价吗?为什么这里非要搞个限价命令呢?而且为了回测能跑起来,还必须设置这个LimitOrderStyle(),貌似还不能设在最大涨跌幅之外,所以只能动态的设为涨停(卖出则设为跌停)。这有什么意义呢,而且还增加了代码的复杂性(比如要买却没有买到)。
非常费解。请高手能解答为感。
解决方案
你好!这是一个非常好的问题,涉及到量化回测与真实市场交易规则的差异。针对你的疑惑,我们从API默认行为、限价单的意义以及科创板保护价的背景三个方面来详细解答。
1. 澄清误解:回测中并非“必须”使用限价单
首先,需要澄清一个常见的误解:在聚宽中,order 函数默认就是市价单,并非必须使用限价单。
根据 API 文档:
order(security, amount, style=None, side='long', pindex=0, close_today=False)
当 style=None 时,系统默认使用的是 市价单(MarketOrder)。也就是说,对于绝大多数主板股票,你只需要写 order('000001.XSHE', 100),系统就会以当前市场的最优价格(最新价+滑点)进行撮合成交,完全不需要去动态计算涨跌停价并设置 LimitOrderStyle。
如果你在回测时发现“必须设置 LimitOrderStyle 才能跑起来”,那很可能是因为你交易了**科创板(688开头)或创业板(300开头,注册制后)**的股票,并且没有正确理解“保护限价”的规则。
2. 为什么 API 要提供限价单(LimitOrderStyle)?
虽然很多初学者在回测时喜欢用市价单(因为一定能成交,代码简单),但在真实的量化交易中,限价单(Limit Order)是必不可少的,原因如下:
- 控制滑点与交易成本:市价单的特点是“保证成交速度,不保证成交价格”。如果你的策略交易的是流动性较差的小盘股,或者下单量非常大,市价单可能会直接“击穿盘口”,导致成交均价极差(滑点巨大)。使用限价单可以严格控制你的买入成本或卖出底线。
- 特定策略的刚性需求:很多策略(如网格交易、均值回归、套利策略、高频做市等)的核心逻辑就是“低买高卖”。这些策略必须在特定的价格挂单等待成交,而不是按市价去追高或杀跌。如果没有限价单,这些策略根本无法实现。
- 模拟真实挂单行为:在分钟级或 Tick 级回测中,限价单会挂在订单簿中,按照“价格优先、时间优先”的规则与市场真实的 Bar 或 Tick 数据进行撮合。这能比市价单更真实地反映策略在实盘中的表现。
3. 为什么科创板市价单非要搞个“保护价”?
你提到的“科创板保护价逻辑”,其实不是聚宽平台故意刁难用户,而是上海证券交易所的硬性交易规则。
- 价格笼子机制:科创板和创业板实施了20%的涨跌幅限制。为了防止极端行情下的“乌龙指”或恶意拉抬打压股价,交易所引入了“价格笼子”机制(即保护限价)。
- 交易所规定:在真实市场中,如果你对科创板股票下达市价申报,必须同时填报一个保护限价。如果市场最优价格超过了你的保护限价,超出部分将直接被交易所废单(撤单)。
- 聚宽的还原:聚宽作为一个专业的量化平台,其回测引擎必须尽可能 100% 还原真实交易所的规则。因此,当你在聚宽中对科创板股票下市价单时,API 要求你必须传入保护价,例如:
order('688001.XSHG', 100, MarketOrderStyle(10))。如果你不传保护价,实盘中这笔订单会被券商直接拒单,为了防止回测与实盘产生巨大差异,回测引擎也会要求你遵守这一规则。
4. 如何优雅地处理下单代码?
如果你只是想做一个简单的趋势策略,希望“不管什么价格,只要能买到就行”,你可以这样写代码来兼容主板和科创板:
def buy_stock(context, security, amount):
# 获取当前数据
current_data = get_current_data()
# 判断是否是科创板或创业板(简单以代码前缀区分)
if security.startswith('688') or security.startswith('300'):
# 获取当天的涨停价作为保护价,确保市价单能以最高容忍度成交
high_limit = current_data[security].high_limit
order(security, amount, MarketOrderStyle(high_limit))
else:
# 主板股票,直接下市价单
order(security, amount)
总结
- 市价单是默认的,主板股票不需要写
LimitOrderStyle。 - 限价单是高级策略和控制风险的刚需,量化平台必须提供。
- 科创板保护价是交易所的真实规则,聚宽为了保证回测与实盘的一致性,在 API 中严格落实了这一规则。
理解了交易所的底层规则,你就会发现这些 API 的设计不仅不是“增加复杂性”,反而是为了保护你的策略在实盘中不会因为规则差异而遭遇惨重损失。