第二章:订单类型与交易机制

做市商这行,说白了就是跟订单打交道。你每天看到的那些跳动的数字,背后都是一个个订单在撮合。今天我就带你看看这些订单到底长什么样,交易所又是怎么把它们配对的。

2.1 限价单与市价单:最基础的两种武器

先说说最常用的两种订单。我个人习惯把限价单叫做「耐心单」,把市价单叫做「急迫单」。

限价单(Limit Order):你指定一个价格,只有市场达到这个价格才会成交。比如你想在100元买某只股票,那就挂一个限价买单。价格不到100,单子就一直在那等着。

市价单(Market Order):你不指定价格,直接按当前最优价成交。说白了就是「我要买,不管多少钱,赶紧给我成交」。这种单子成交快,但价格可能不太理想。

核心区别:限价单提供流动性,市价单消耗流动性。做市商主要靠挂限价单赚钱。

我在项目中遇到过一件事。有一次做回测,我发现策略在模拟环境里跑得挺好,一上实盘就亏钱。查了半天,原来是模拟环境里市价单的滑点设得太理想了。真实市场里,大额市价单能把价格推出去好几个tick。嗯,从那以后我再也不敢低估滑点了。

2.2 冰山订单与隐藏订单:大资金的隐身衣

大资金进场最怕什么?怕被市场发现。你想想看,如果你要买100万股,直接挂个限价单,盘口上突然多出100万股的买单,其他交易者一看就知道有大资金在买,肯定会抢跑。

这时候就需要冰山订单(Iceberg Order)了。它只显示一部分数量,剩下的藏在下面。就像冰山一样,水面上的只是一小部分。

# 一个简单的冰山订单示例
class IcebergOrder:
    def __init__(self, total_qty, display_qty, price):
        self.total_qty = total_qty      # 总数量 100000
        self.display_qty = display_qty  # 显示数量 5000
        self.price = price
        self.remaining = total_qty
    
    def get_display_qty(self):
        # 每次只返回显示部分
        return min(self.display_qty, self.remaining)
    
    def fill(self, qty):
        self.remaining -= qty
        # 如果剩余数量小于显示数量,就全部显示
        return self.remaining > 0

隐藏订单(Hidden Order)更绝,完全不显示在盘口上。只有价格到了,它才会被触发。交易所通常允许部分隐藏,比如显示10%,隐藏90%。

实战技巧:做市商经常用冰山订单来管理库存。比如你手里有大量存货想慢慢出掉,用冰山订单可以避免把价格砸下去。

我曾经吃过一次亏。有次做统计套利,我发现两个合约的价差突然收窄,以为是机会,赶紧进场。结果发现是有人在用冰山订单慢慢吃货,把价格拉上去了。等我反应过来,价差已经恢复了,我反而被套住了。所以现在我看到盘口上有大单慢慢吃,都会多留个心眼。

2.3 集合竞价与连续竞价:两种不同的游戏规则

交易所的交易时段,其实分两种模式。

集合竞价(Call Auction):在一段时间内收集所有订单,然后统一撮合。开盘和收盘通常用这种方式。为什么?因为开盘时信息最多,需要让价格充分发现。

连续竞价(Continuous Trading):订单来了就立刻撮合。这是盘中主要的交易方式。

特征 集合竞价 连续竞价
撮合时机 定时统一撮合 实时撮合
价格发现 充分,能反映供需 可能滞后
流动性 集中释放 持续提供
典型场景 开盘、收盘、临时停牌 盘中交易

我个人觉得,集合竞价阶段是做市商最紧张的时候。因为价格波动大,信息不对称严重。我记得有次开盘前,我挂了一堆限价单准备做市,结果集合竞价一出来,价格直接跳空2%。我的单子全被吃了,库存一下子暴露了很大的风险。

2.4 交易所撮合引擎原理:到底是怎么配对的?

撮合引擎,说白了就是一个巨大的订单匹配器。它的核心逻辑其实很简单:价格优先,时间优先

什么意思呢?

  • 价格优先:买单出价高的先成交,卖单出价低的先成交
  • 时间优先:同样价格,先挂单的先成交

举个例子。假设当前盘口是这样的:

卖单队列(从低到高):
    100.01  1000股  (张三,09:30:01)
    100.02  2000股  (李四,09:30:05)
    100.03  1500股  (王五,09:30:10)

买单队列(从高到低):
    100.00  3000股  (赵六,09:30:02)
    99.99   2000股  (钱七,09:30:08)

这时候来了一个市价买单,要买5000股。撮合引擎会怎么做?

  1. 先吃最优卖单:100.01的1000股(张三的)
  2. 再吃下一个:100.02的2000股(李四的)
  3. 还不够,继续吃:100.03的1500股(王五的)
  4. 还差500股,继续吃下一个卖单...

你看,这就是典型的「扫盘」。市价单会一路吃过去,直到满足数量为止。

注意:不同交易所的撮合逻辑可能有细微差别。比如有些交易所支持「部分成交」,有些则要求「全部成交否则取消」。做策略的时候一定要搞清楚目标交易所的规则。

我曾经在开发高频策略时,遇到过一个坑。交易所的撮合引擎在处理冰山订单时,每次只显示一部分。但如果你用市价单去吃,它会自动把冰山下面的部分也吃掉。我当时没考虑到这一点,导致策略的订单量估算严重偏差。后来我专门写了个模块来模拟冰山订单的撮合逻辑,才把问题解决。

2.5 实战中的订单选择

说了这么多,到底该怎么选?我个人的经验是这样的:

  • 做市商:主要用限价单,偶尔用冰山订单管理大额库存
  • 套利策略:用市价单快速进场,用限价单慢慢出场
  • 趋势跟踪:用市价单追涨杀跌,但要注意滑点
  • 高频交易:限价单和市价单混合使用,看具体策略

最后说一句,订单类型的选择,本质上是在「成交确定性」和「价格确定性」之间做权衡。市价单成交快但价格不确定,限价单价格确定但可能成交不了。做市商的核心能力之一,就是在这两者之间找到平衡点。

下一章,我会讲讲做市商最核心的指标——买卖价差,以及怎么通过订单簿数据来估算它。到时候见。