4、价格形成机制:撮合引擎原理、连续竞价与集合竞价、开盘价与收盘价

聊到价格形成,很多人第一反应就是「买卖双方讨价还价」。但在交易所里,这个过程被拆解成了非常精密的机械步骤。我当年第一次看撮合引擎的日志时,说实话,有点懵——几千笔订单在几毫秒内完成匹配,这背后到底发生了什么?

今天我们就来拆开这个黑盒子。价格不是凭空产生的,它是订单簿里每一笔挂单、每一次撤单、每一轮博弈的最终结果。

4.1 撮合引擎:订单簿的「心脏」

撮合引擎,说白了就是交易所的中央处理器。它的任务只有一个:把买单和卖单配成一对

但这里有个关键点——价格优先、时间优先。这是所有撮合引擎的黄金法则。

  • 价格优先:买单出价高的排前面,卖单出价低的排前面。
  • 时间优先:价格相同的情况下,先来的订单先成交。

我曾在项目中遇到过一个问题:某个小交易所的撮合引擎在价格相同时,竟然按订单ID大小排序。结果导致大户总能插队,散户怨声载道。嗯,后来他们改成了时间戳排序,问题才解决。

来看一个最简单的撮合流程:

// 伪代码:撮合引擎核心逻辑
function matchOrder(newOrder, orderBook):
    while newOrder.volume > 0:
        // 找到最优对手单
        bestOpposite = orderBook.getBestOpposite(newOrder)
        if bestOpposite is None:
            break  // 没有对手单,挂单等待
        
        // 比较价格
        if newOrder.isBuy and newOrder.price >= bestOpposite.price:
            // 可以成交
            tradePrice = bestOpposite.price
            tradeVolume = min(newOrder.volume, bestOpposite.volume)
            executeTrade(newOrder, bestOpposite, tradePrice, tradeVolume)
        elif newOrder.isSell and newOrder.price <= bestOpposite.price:
            tradePrice = bestOpposite.price
            tradeVolume = min(newOrder.volume, bestOpposite.volume)
            executeTrade(newOrder, bestOpposite, tradePrice, tradeVolume)
        else:
            break  // 价格不匹配,挂单等待
    
    if newOrder.volume > 0:
        orderBook.addOrder(newOrder)  // 剩余部分挂单

你想想看,这个逻辑其实很直白。但实际生产环境里,要考虑的东西多得多——比如订单类型(市价单、限价单、冰山订单)、撤单处理、异常恢复等等。

核心要点:撮合引擎不创造价格,它只是忠实地执行市场参与者的意愿。价格是买卖双方博弈的结果,引擎只是那个「裁判」。

4.2 连续竞价:日常交易的「主旋律」

大部分交易时间,我们都在连续竞价模式下运行。什么叫连续竞价?就是订单随时来,撮合随时做

举个例子:

  • 当前卖一价是 100.50,挂单量 200 股
  • 你下了一个市价买单,买入 300 股
  • 撮合引擎会先吃掉卖一的 200 股,成交价 100.50
  • 然后继续往下吃卖二的 100 股,成交价可能是 100.55
  • 最终你的成交价是加权平均价,而不是一个固定价格

这里有个坑,我必须要提醒你:市价单在流动性不足时,可能会滑点很大。我曾经见过一个新手,在流动性很差的币对上用市价单买了 10 个 BTC,结果直接把价格拉高了 2%。他以为成交价是当前价,实际上他吃掉了好几个档位的卖单。

避坑指南:在流动性差的市场,尽量用限价单。市价单虽然成交快,但你可能要付出「流动性溢价」。

连续竞价的核心特征:

  • 实时性:订单到达后立即尝试撮合
  • 价格波动:价格随买卖力量变化而实时变动
  • 深度依赖:订单簿的厚度直接影响成交质量

4.3 集合竞价:开盘与收盘的「定海神针」

连续竞价虽然好,但有个问题——如果开盘时大家一窝蜂下单,价格会剧烈波动。这时候就需要集合竞价出场了。

集合竞价的逻辑,说白了就是收集一段时间内的所有订单,然后找一个能让成交量最大的价格,统一成交

我习惯把集合竞价比作「拍卖会」:

  1. 收集阶段:大家自由报价,但暂时不成交
  2. 定价阶段:系统计算出一个「均衡价格」
  3. 成交阶段:所有订单按这个价格统一成交

这个均衡价格怎么找?看个例子:

价格 累计买单量 累计卖单量 可成交量
10.00 1000 200 200
10.05 800 400 400
10.10 600 600 600
10.15 400 900 400
10.20 200 1200 200

你看,在 10.10 这个价格上,可成交量最大(600 股)。所以集合竞价就会以 10.10 作为开盘价或收盘价。

小技巧:集合竞价期间,你可以通过观察「未匹配量」的变化,大致判断市场情绪。如果买单远多于卖单,开盘大概率高开。

4.4 开盘价与收盘价:市场的「锚点」

开盘价和收盘价,是交易中最常被引用的两个价格。它们不是随便定的,背后有严格的规则。

开盘价:通常是集合竞价产生的。如果集合竞价没有成交,那就用第一笔连续竞价的价格作为开盘价。

收盘价:不同市场规则不同。

  • A股:最后 3 分钟的集合竞价
  • 港股:最后 10 分钟,每 15 秒取一次中位数
  • 美股:最后 10 分钟的加权平均价

我曾在做回测系统时,发现一个有意思的现象:很多策略在收盘前几分钟会「异动」。为什么?因为机构要调整仓位,而收盘价是很多基金净值的计算基准。你想想看,如果某只基金持有大量股票,它肯定希望在收盘价附近完成调仓,而不是被砸个坑。

实战经验:收盘前 5 分钟,流动性通常会突然增加。如果你做日内交易,这个时间段值得重点关注。但也要小心——大资金可能会利用这个时间段「做收盘价」。

4.5 知识体系总览

下面这张图,把价格形成的核心逻辑串起来了。你可以把它当作本章的「地图」:

价格形成机制:核心逻辑 撮合引擎 价格优先 时间优先 竞价模式 连续竞价 集合竞价 关键价格 开盘价 收盘价 核心流程 ① 订单进入撮合引擎 ② 按价格优先、时间优先排序 ③ 判断当前处于连续竞价还是集合竞价模式 ④ 连续竞价:实时撮合,价格随买卖力量波动 ⑤ 集合竞价:收集订单后统一成交,产生开盘/收盘价 ⑥ 最终价格反映市场供需平衡

这张图把撮合引擎、竞价模式和关键价格串在了一起。你可以看到,价格形成不是孤立的,而是一个从订单到成交的完整链条

嗯,说到这,我想起一个细节:很多人在做量化策略时,只关注价格本身,却忽略了价格是怎么来的。其实,理解撮合机制能帮你更好地预测价格行为。比如,在集合竞价阶段,你可以通过订单簿的「不平衡度」来预判开盘方向。

个人建议:如果你写交易系统,一定要把撮合逻辑的单元测试写全。我见过太多因为撮合 bug 导致的「乌龙指」事件了。测试用例至少覆盖:市价单、限价单、冰山订单、撤单、部分成交等场景。

最后,记住一句话:价格是市场参与者用真金白银投票的结果,而撮合引擎只是那个公正的计票员


公众号:蓝海资料掘金营,微信deep3321